diff --git a/README.md b/README.md index c1e6723a8b..d63298d308 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Build Status](https://travis-ci.org/runelite-extended/runelite.svg?branch=master)](https://travis-ci.org/runelite-extended/runelite) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![HitCount](http://hits.dwyl.io/runelite-extended/runelite.svg)](http://hits.dwyl.io/runelite-extended/runelite) [![saythanks](https://img.shields.io/badge/say-thanks-32cd32.svg)](https://www.patreon.com/RuneLitePlus) -[RuneLitePlus](https://runelitepl.us) is a extended version of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying more open-source. +[RuneLitePlus](https://runelitepl.us) is an extended version of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying more open-source. diff --git a/cache/src/main/java/net/runelite/cache/io/OutputStream.java b/cache/src/main/java/net/runelite/cache/io/OutputStream.java index 751905f4fb..24275b5c73 100644 --- a/cache/src/main/java/net/runelite/cache/io/OutputStream.java +++ b/cache/src/main/java/net/runelite/cache/io/OutputStream.java @@ -27,6 +27,7 @@ package net.runelite.cache.io; import com.google.common.base.Preconditions; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.nio.Buffer; import java.nio.ByteBuffer; public final class OutputStream extends java.io.OutputStream @@ -56,7 +57,7 @@ public final class OutputStream extends java.io.OutputStream int newCapacity = buffer.capacity() * 2; ByteBuffer old = buffer; - old.flip(); + ((Buffer) old).flip(); buffer = ByteBuffer.allocate(newCapacity); @@ -196,7 +197,7 @@ public final class OutputStream extends java.io.OutputStream public byte[] flip() { - buffer.flip(); + ((Buffer) buffer).flip(); byte[] b = new byte[buffer.limit()]; buffer.get(b); return b; diff --git a/http-api/src/main/java/net/runelite/http/api/discord/DiscordClient.java b/http-api/src/main/java/net/runelite/http/api/discord/DiscordClient.java new file mode 100644 index 0000000000..4f536b68ff --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/DiscordClient.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord; + +import com.google.gson.Gson; +import java.io.IOException; +import lombok.extern.slf4j.Slf4j; +import net.runelite.http.api.RuneLiteAPI; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +@Slf4j +public class DiscordClient +{ + public static final Gson gson = new Gson(); + private static final MediaType JSON = MediaType.parse("application/json"); + + public void message(HttpUrl url, DiscordMessage discordMessage) + { + log.info("Message being sent"); + message(url, discordMessage, 0, 5); + } + + private void message(HttpUrl url, DiscordMessage discordMessage, int retryAttempt, int maxAttempts) + { + Request request = new Request.Builder() + .post(RequestBody.create(JSON, gson.toJson(discordMessage))) + .url(url) + .build(); + + log.info("Attempting to message with {}", discordMessage); + + RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback() + { + + @Override + public void onFailure(Call call, IOException e) + { + log.warn("Unable to submit discord post.", e); + if (retryAttempt < maxAttempts) + { + message(url, discordMessage, retryAttempt + 1, maxAttempts); + } + } + + @Override + public void onResponse(Call call, Response response) throws IOException + { + try + { + if (response.body() == null) + { + log.error("API Call - Reponse was null."); + return; + } + if (response.body().string().contains("You are being rate limited") && retryAttempt < maxAttempts) + { + log.error("You are being rate limited, retrying..."); + message(url, discordMessage, retryAttempt + 1, maxAttempts); + } + } + finally + { + response.close(); + log.debug("Submitted discord log record"); + } + } + }); + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/discord/DiscordEmbed.java b/http-api/src/main/java/net/runelite/http/api/discord/DiscordEmbed.java new file mode 100644 index 0000000000..4c04ecc69d --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/DiscordEmbed.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord; + +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import net.runelite.http.api.discord.embed.AuthorEmbed; +import net.runelite.http.api.discord.embed.FieldEmbed; +import net.runelite.http.api.discord.embed.FooterEmbed; +import net.runelite.http.api.discord.embed.ImageEmbed; +import net.runelite.http.api.discord.embed.ProviderEmbed; +import net.runelite.http.api.discord.embed.ThumbnailEmbed; +import net.runelite.http.api.discord.embed.VideoEmbed; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@ToString +public class DiscordEmbed +{ + String title; + String type; + String description; + String url; + String timestamp; + String iconurl; + String color; + FooterEmbed footer; + ImageEmbed image; + ThumbnailEmbed thumbnail; + VideoEmbed video; + ProviderEmbed provider; + AuthorEmbed author; + List fields = new ArrayList<>(); + + public DiscordEmbed() + { + + } + + public DiscordEmbed(String title, String description) + { + this(title, description, null); + } + + public DiscordEmbed(String title, String description, String url) + { + setTitle(title); + setDescription(description); + setUrl(url); + } + + public static DiscordMessage toDiscordMessage(DiscordEmbed embed, String username, String avatarURL) + { + return DiscordMessage.builder() + .username(username) + .avatarUrl(avatarURL) + .content("") + .embed(embed) + .build(); + } + + public DiscordMessage toDiscordMessage(String username, String avatarUrl) + { + return DiscordEmbed.toDiscordMessage(this, username, avatarUrl); + } + + public static class DiscordEmbedBuilder + { + List fields = new ArrayList<>(); + + public DiscordEmbedBuilder field(FieldEmbed field) + { + fields.add(field); + return this; + } + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/discord/DiscordMessage.java b/http-api/src/main/java/net/runelite/http/api/discord/DiscordMessage.java new file mode 100644 index 0000000000..061568da9d --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/DiscordMessage.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord; + +import com.google.gson.annotations.SerializedName; +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@ToString +public class DiscordMessage +{ + String username; + String content; + @SerializedName("avatar_url") + String avatarUrl; + @SerializedName("tts") + boolean textToSpeech; + List embeds = new ArrayList<>(); + + public DiscordMessage() + { + + } + + public DiscordMessage(String username, String content, String avatar_url) + { + this(username, content, avatar_url, false); + } + + public DiscordMessage(String username, String content, String avatar_url, boolean tts) + { + setUsername(username); + setContent(content); + setAvatarUrl(avatar_url); + setTextToSpeech(tts); + } + + public void setUsername(String username) + { + if (username != null) + { + this.username = username.substring(0, Math.min(31, username.length())); + } + else + { + this.username = null; + } + } + + public static class DiscordMessageBuilder + { + List embeds = new ArrayList<>(); + + public DiscordMessageBuilder embed(DiscordEmbed embed) + { + embeds.add(embed); + return this; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/ZombifiedSpawnOverlay.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/AuthorEmbed.java similarity index 58% rename from runelite-client/src/main/java/net/runelite/client/plugins/vorkath/ZombifiedSpawnOverlay.java rename to http-api/src/main/java/net/runelite/http/api/discord/embed/AuthorEmbed.java index a0cbc0451a..46d1f34213 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/ZombifiedSpawnOverlay.java +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/AuthorEmbed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, https://runelitepl.us + * Copyright (c) 2018, Forsco * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -7,6 +7,7 @@ * * 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. @@ -22,39 +23,26 @@ * (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.vorkath; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import javax.inject.Inject; -import javax.inject.Singleton; -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; +package net.runelite.http.api.discord.embed; -@Singleton -public class ZombifiedSpawnOverlay extends Overlay +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class AuthorEmbed { - private final VorkathPlugin plugin; - - @Inject - public ZombifiedSpawnOverlay(final VorkathPlugin plugin) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.plugin = plugin; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (plugin.getZombifiedSpawn() != null) - { - OverlayUtil.renderActorOverlayImage(graphics, plugin.getZombifiedSpawn(), VorkathPlugin.SPAWN, Color.green, 10); - } - - return null; - } + String name; + String url; + String icon_url; + String proxy_icon_url; } \ No newline at end of file diff --git a/http-api/src/main/java/net/runelite/http/api/discord/embed/FieldEmbed.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/FieldEmbed.java new file mode 100644 index 0000000000..7abf9c3832 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/FieldEmbed.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord.embed; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class FieldEmbed +{ + @NonNull + String name; + @NonNull + String value; + boolean inline; +} diff --git a/runelite-client/src/main/java/net/runelite/client/eventbus/Subscribe.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/FooterEmbed.java similarity index 76% rename from runelite-client/src/main/java/net/runelite/client/eventbus/Subscribe.java rename to http-api/src/main/java/net/runelite/http/api/discord/embed/FooterEmbed.java index e34e350be0..73185c0d7f 100644 --- a/runelite-client/src/main/java/net/runelite/client/eventbus/Subscribe.java +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/FooterEmbed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Abex + * Copyright (c) 2018, Forsco * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -7,6 +7,7 @@ * * 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. @@ -22,20 +23,25 @@ * (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.eventbus; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +package net.runelite.http.api.discord.embed; -/** - * Marks a method as an event subscriber. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface Subscribe +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class FooterEmbed { + String text; + String icon_url; + String proxy_icon_url; } diff --git a/http-api/src/main/java/net/runelite/http/api/discord/embed/ImageEmbed.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/ImageEmbed.java new file mode 100644 index 0000000000..df8c511384 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/ImageEmbed.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord.embed; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class ImageEmbed +{ + String url; + String proxy_url; + int height; + int width; +} diff --git a/http-api/src/main/java/net/runelite/http/api/discord/embed/ProviderEmbed.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/ProviderEmbed.java new file mode 100644 index 0000000000..0ac555189e --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/ProviderEmbed.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord.embed; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class ProviderEmbed +{ + String name; + String url; +} diff --git a/http-api/src/main/java/net/runelite/http/api/discord/embed/ThumbnailEmbed.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/ThumbnailEmbed.java new file mode 100644 index 0000000000..8c17e4dfc8 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/ThumbnailEmbed.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord.embed; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class ThumbnailEmbed +{ + String url; + String proxy_url; + int height; + int width; +} diff --git a/http-api/src/main/java/net/runelite/http/api/discord/embed/VideoEmbed.java b/http-api/src/main/java/net/runelite/http/api/discord/embed/VideoEmbed.java new file mode 100644 index 0000000000..af396f0ebf --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/discord/embed/VideoEmbed.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Forsco + * 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.discord.embed; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class VideoEmbed +{ + String url; + int height; + int width; +} diff --git a/http-api/src/main/java/net/runelite/http/api/item/ItemStats.java b/http-api/src/main/java/net/runelite/http/api/item/ItemStats.java index 3ebc17970f..088d0536ca 100644 --- a/http-api/src/main/java/net/runelite/http/api/item/ItemStats.java +++ b/http-api/src/main/java/net/runelite/http/api/item/ItemStats.java @@ -29,6 +29,7 @@ import lombok.Value; @Value public class ItemStats { + private String name; private boolean quest; private boolean equipable; private double weight; @@ -76,7 +77,7 @@ public class ItemStats newEquipment = equipment; } - return new ItemStats(quest, equipable, newWeight, newEquipment); + return new ItemStats(name, quest, equipable, newWeight, newEquipment); } } diff --git a/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java b/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java index 7e01dc4b56..151fbfd81f 100644 --- a/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java +++ b/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java @@ -62,18 +62,6 @@ public class XteaClient .url(url) .build(); - try - { - try (Response response = RuneLiteAPI.RLP_CLIENT.newCall(request).execute()) - { - logger.debug("xtea response " + response.code()); - } - } - catch (IOException e) - { - e.printStackTrace(); - } - RuneLiteAPI.RLP_CLIENT.newCall(request).enqueue(new Callback() { @Override @@ -114,9 +102,7 @@ public class XteaClient { InputStream in = response.body().byteStream(); // CHECKSTYLE:OFF - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), new TypeToken>() - { - }.getType()); + return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), new TypeToken>() {}.getType()); // CHECKSTYLE:ON } catch (JsonParseException ex) 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 3eaadba176..2c416451aa 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -363,6 +363,7 @@ public interface Client extends GameShell * @param scale the scale of the sprite * @return the created sprite */ + @Nullable Sprite createItemSprite(int itemId, int quantity, int border, int shadowColor, int stackable, boolean noted, int scale); /** @@ -373,6 +374,7 @@ public interface Client extends GameShell * @param fileId the sprites file ID * @return the sprite image of the file */ + @Nullable Sprite[] getSprites(IndexDataBase source, int archiveId, int fileId); /** @@ -1679,15 +1681,25 @@ public interface Client extends GameShell boolean isSpellSelected(); /** - * Set whether or not player attack options will be hidden for clanmembers/friends + * Set whether or not player attack options will be hidden for friends */ void setHideFriendAttackOptions(boolean yes); /** - * Set whether or not player cast options will be hidden for clanmembers/friends + * Set whether or not player cast options will be hidden for friends */ void setHideFriendCastOptions(boolean yes); + /** + * Set whether or not player attack options will be hidden for clanmates + */ + void setHideClanmateAttackOptions(boolean yes); + + /** + * Set whether or not player cast options will be hidden for clanmates + */ + void setHideClanmateCastOptions(boolean yes); + /** * Set spells excluded from above hiding */ diff --git a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java index aa714128ea..a9bb550df1 100644 --- a/runelite-api/src/main/java/net/runelite/api/ProjectileID.java +++ b/runelite-api/src/main/java/net/runelite/api/ProjectileID.java @@ -82,9 +82,9 @@ public class ProjectileID public static final int CERB_FIRE = 1247; /** - * missing: marble gargoyle, superior dark beast + * missing: superior dark beast */ - + public static final int MARBLE_GARGOYLE_AOE = 1453; /** * non AOE, regular projectiles */ diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java index 70076e3a6d..8d6796b40a 100644 --- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java +++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java @@ -160,9 +160,11 @@ public final class ScriptID /** * Handles zoom input + * + * Updates the VarClientInts (73, 74) to this same value *
    - *
  • int zoom value
  • - *
  • int zoom value
  • + *
  • int Reset zoom position
  • + *
  • int Reset zoom position
  • *
*/ public static final int CAMERA_DO_ZOOM = 42; diff --git a/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java b/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java index bbbaa34dfd..861ecf1196 100644 --- a/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java +++ b/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java @@ -41,14 +41,14 @@ public interface Callbacks * * @param event the event */ - void post(Object event); + void post(Class eventClass, Object event); /** * Post a deferred event, which gets delayed until the next cycle. * * @param event the event */ - void postDeferred(Object event); + void postDeferred(Class eventClass, Object event); /** * Called each client cycle. diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index e30b7deb73..b5bf50d355 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -300,6 +300,16 @@ httpmime 4.5.9 + + io.reactivex.rxjava2 + rxjava + 2.2.10 + + + com.jakewharton.rxrelay2 + rxrelay + 2.1.0 + 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 1fa6aeb5b3..2993fdf108 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -48,16 +48,9 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.client.account.SessionManager; import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.chat.CommandManager; import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; -import net.runelite.client.eventbus.EventBus; -import net.runelite.client.game.ClanManager; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.LootManager; -import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.graphics.ModelOutlineRenderer; -import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; @@ -65,18 +58,14 @@ import net.runelite.client.rs.ClientLoader; import net.runelite.client.rs.ClientUpdateCheckMode; import net.runelite.client.task.Scheduler; import net.runelite.client.ui.ClientUI; -import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.RuneLiteSplashScreen; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.WidgetOverlay; import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay; import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay; -import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay; import net.runelite.client.ui.overlay.tooltip.TooltipOverlay; import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay; -import net.runelite.client.ws.PartyService; import org.slf4j.LoggerFactory; @Singleton @@ -97,15 +86,9 @@ public class RuneLite @Inject private PluginManager pluginManager; - @Inject - private EventBus eventBus; - @Inject private ConfigManager configManager; - @Inject - private DrawManager drawManager; - @Inject private SessionManager sessionManager; @@ -118,33 +101,12 @@ public class RuneLite @Inject private ClientUI clientUI; - @Inject - private InfoBoxManager infoBoxManager; - @Inject private OverlayManager overlayManager; - @Inject - private PartyService partyService; - - @Inject - private Provider itemManager; - - @Inject - private Provider overlayRenderer; - - @Inject - private Provider clanManager; - @Inject private Provider chatMessageManager; - @Inject - private Provider menuManager; - - @Inject - private Provider commandManager; - @Inject private Provider infoBoxOverlay; @@ -160,12 +122,6 @@ public class RuneLite @Inject private Provider arrowMinimapOverlay; - @Inject - private Provider lootManager; - - @Inject - private Provider chatboxPanelManager; - @Inject @Nullable private Client client; @@ -351,28 +307,11 @@ public class RuneLite // Close the splash screen splashScreen.close(); - // Register event listeners - eventBus.register(clientUI); - eventBus.register(pluginManager); - eventBus.register(overlayManager); - eventBus.register(drawManager); - eventBus.register(infoBoxManager); - eventBus.register(partyService); - if (!isOutdated) { // Initialize chat colors chatMessageManager.get().loadColors(); - eventBus.register(overlayRenderer.get()); - eventBus.register(clanManager.get()); - eventBus.register(itemManager.get()); - eventBus.register(menuManager.get()); - eventBus.register(chatMessageManager.get()); - eventBus.register(commandManager.get()); - eventBus.register(lootManager.get()); - eventBus.register(chatboxPanelManager.get()); - // Add core overlays WidgetOverlay.createOverlays(client).forEach(overlayManager::add); overlayManager.add(infoBoxOverlay.get()); 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 ee8486811b..f394c17f40 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java @@ -32,7 +32,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Nullable; import javax.inject.Singleton; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.hooks.Callbacks; import net.runelite.client.account.SessionManager; @@ -56,7 +55,6 @@ import okhttp3.OkHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Slf4j public class RuneLiteModule extends AbstractModule { private final ClientUpdateCheckMode updateCheckMode; 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 4caef359c3..62e003bc44 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 @@ -39,7 +39,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.client.RuneLite; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.util.LinkBrowser; @@ -67,7 +66,8 @@ public class SessionManager this.configManager = configManager; this.eventBus = eventBus; this.wsClient = wsClient; - eventBus.register(this); + + this.eventBus.subscribe(LoginResponse.class, this, this::onLoginResponse); } public void loadSession() @@ -150,7 +150,7 @@ public class SessionManager configManager.switchSession(); } - eventBus.post(new SessionOpen()); + eventBus.post(SessionOpen.class, new SessionOpen()); } private void closeSession() @@ -179,7 +179,7 @@ public class SessionManager // Restore config configManager.switchSession(); - eventBus.post(new SessionClose()); + eventBus.post(SessionClose.class, new SessionClose()); } public void login() @@ -207,8 +207,7 @@ public class SessionManager LinkBrowser.browse(login.getOauthUrl()); } - @Subscribe - public void onLoginResponse(LoginResponse loginResponse) + private void onLoginResponse(LoginResponse loginResponse) { log.debug("Now logged in as {}", loginResponse.getUsername()); diff --git a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java index bbe3ae3f0d..805b7a5620 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java @@ -58,7 +58,7 @@ public class ClientThread { if (client.isClientThread()) { - if (r.getAsBoolean()) + if (!r.getAsBoolean()) { invokes.add(r); } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 5c53677308..93c3927554 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -128,15 +128,15 @@ public class Hooks implements Callbacks private boolean shouldProcessGameTick; @Override - public void post(Object event) + public void post(Class eventClass, Object event) { - eventBus.post(event); + eventBus.post(eventClass, event); } @Override - public void postDeferred(Object event) + public void postDeferred(Class eventClass, Object event) { - deferredEventBus.post(event); + deferredEventBus.post(eventClass, event); } @Override @@ -148,13 +148,13 @@ public class Hooks implements Callbacks deferredEventBus.replay(); - eventBus.post(GameTick.INSTANCE); + eventBus.post(GameTick.class, GameTick.INSTANCE); int tick = client.getTickCount(); client.setTickCount(tick + 1); } - eventBus.post(BeforeRender.INSTANCE); + eventBus.post(BeforeRender.class, BeforeRender.INSTANCE); clientThread.invoke(); @@ -509,7 +509,7 @@ public class Hooks implements Callbacks public static boolean drawMenu() { BeforeMenuRender event = new BeforeMenuRender(); - client.getCallbacks().post(event); + client.getCallbacks().post(BeforeMenuRender.class, event); return event.isConsumed(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java index b1aa9b3ac2..a336008d95 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatCommandManager.java @@ -31,18 +31,15 @@ import java.util.function.BiConsumer; import java.util.function.BiPredicate; import javax.inject.Inject; import javax.inject.Singleton; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.ChatMessage; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatInput; import net.runelite.client.events.ChatboxInput; import net.runelite.client.events.PrivateMessageInput; @Singleton -@Slf4j public class ChatCommandManager implements ChatboxInputListener { private final Map commands = new HashMap<>(); @@ -55,8 +52,10 @@ public class ChatCommandManager implements ChatboxInputListener { this.client = client; this.scheduledExecutorService = scheduledExecutorService; - eventBus.register(this); + // eventBus.register(this); commandManager.register(this); + + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); } public void registerCommand(String command, BiConsumer execute) @@ -84,8 +83,7 @@ public class ChatCommandManager implements ChatboxInputListener commands.remove(command.toLowerCase()); } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { if (client.getGameState() != GameState.LOGGED_IN) { diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java index c571282a00..c47b52126b 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java @@ -52,7 +52,7 @@ import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.events.VarbitChanged; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ChatColorConfig; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; @@ -70,17 +70,23 @@ public class ChatMessageManager @Inject private ChatMessageManager( - Client client, - ChatColorConfig chatColorConfig, - ClientThread clientThread) + final Client client, + final ChatColorConfig chatColorConfig, + final ClientThread clientThread, + final EventBus eventbus) { this.client = client; this.chatColorConfig = chatColorConfig; this.clientThread = clientThread; + + eventbus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventbus.subscribe(ResizeableChanged.class, this, this::onResizeableChanged); + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventbus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { int setting = client.getVar(Varbits.TRANSPARENT_CHATBOX); @@ -91,14 +97,12 @@ public class ChatMessageManager } } - @Subscribe - public void onResizeableChanged(ResizeableChanged event) + private void onResizeableChanged(ResizeableChanged event) { refreshAll(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("textrecolor")) { @@ -107,8 +111,7 @@ public class ChatMessageManager } } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { MessageNode messageNode = chatMessage.getMessageNode(); ChatMessageType chatMessageType = chatMessage.getType(); @@ -173,8 +176,7 @@ public class ChatMessageManager } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) + private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) { final String eventName = scriptCallbackEvent.getEventName(); diff --git a/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java b/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java index 7529fc6d56..f2871651bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/CommandManager.java @@ -38,7 +38,6 @@ import net.runelite.api.events.CommandExecuted; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.callback.ClientThread; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ChatboxInput; import net.runelite.client.events.PrivateMessageInput; @@ -58,11 +57,17 @@ public class CommandManager private final List chatboxInputListenerList = new ArrayList<>(); @Inject - private CommandManager(Client client, EventBus eventBus, ClientThread clientThread) + private CommandManager( + final Client client, + final EventBus eventBus, + final ClientThread clientThread + ) { this.client = client; this.eventBus = eventBus; this.clientThread = clientThread; + + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); } public void register(ChatboxInputListener chatboxInputListener) @@ -75,7 +80,6 @@ public class CommandManager chatboxInputListenerList.remove(chatboxInputListener); } - @Subscribe private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (sending) @@ -115,7 +119,7 @@ public class CommandManager String[] args = Arrays.copyOfRange(split, 1, split.length); CommandExecuted commandExecuted = new CommandExecuted(command, args); - eventBus.post(commandExecuted); + eventBus.post(CommandExecuted.class, commandExecuted); } private void handleInput(ScriptCallbackEvent event) 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 b22c8e67a7..505f5dca30 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 @@ -66,8 +66,8 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.client.RuneLite; import static net.runelite.client.RuneLite.PROFILES_DIR; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.util.ColorUtil; import net.runelite.client.ui.FontManager; +import net.runelite.client.util.ColorUtil; @Singleton @Slf4j @@ -89,7 +89,6 @@ public class ConfigManager @Inject public ConfigManager(ScheduledExecutorService scheduledExecutorService) { - scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS); } @@ -194,7 +193,7 @@ public class ConfigManager configChanged.setKey(key); configChanged.setOldValue(null); configChanged.setNewValue(value); - eventBus.post(configChanged); + eventBus.post(ConfigChanged.class, configChanged); }); } catch (Exception ex) @@ -233,7 +232,7 @@ public class ConfigManager private void postConfigChanged(ConfigChanged configChanged) { configObjectCache.remove(configChanged.getGroup() + "." + configChanged.getKey()); - eventBus.post(configChanged); + eventBus.post(ConfigChanged.class, configChanged); } public T getConfig(Class clazz) @@ -332,7 +331,7 @@ public class ConfigManager configChanged.setKey(key); configChanged.setOldValue(oldValue); - eventBus.post(configChanged); + eventBus.post(ConfigChanged.class, configChanged); } public ConfigDescriptor getConfigDescriptor(Object configurationProxy) diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index 069483865a..ea30bfe5dd 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -28,6 +28,7 @@ import java.awt.Dimension; import java.awt.Font; import net.runelite.api.Constants; import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.ContainableFrame; @ConfigGroup("runelite") public interface RuneLiteConfig extends Config @@ -66,14 +67,14 @@ public interface RuneLiteConfig extends Config } @ConfigItem( - keyName = "containInScreen", + keyName = "containInScreen2", name = "Contain in screen", - description = "Makes the client stay contained in the screen when attempted to move out of it.
Note: Only works if custom chrome is enabled.", + description = "Makes the client stay contained in the screen when attempted to move out of it.
Note: 'Always' only works if custom chrome is enabled.", position = 13 ) - default boolean containInScreen() + default ContainableFrame.Mode containInScreen() { - return false; + return ContainableFrame.Mode.RESIZING; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java b/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java index 091c479ac6..b8abbc518b 100644 --- a/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java +++ b/runelite-client/src/main/java/net/runelite/client/discord/DiscordService.java @@ -198,7 +198,7 @@ public class DiscordService implements AutoCloseable { log.info("Discord RPC service is ready with user {}.", user.username); currentUser = user; - eventBus.post(new DiscordReady( + eventBus.post(DiscordReady.class, new DiscordReady( user.userId, user.username, user.discriminator, @@ -207,28 +207,28 @@ public class DiscordService implements AutoCloseable private void disconnected(int errorCode, String message) { - eventBus.post(new DiscordDisconnected(errorCode, message)); + eventBus.post(DiscordDisconnected.class, new DiscordDisconnected(errorCode, message)); } private void errored(int errorCode, String message) { log.warn("Discord error: {} - {}", errorCode, message); - eventBus.post(new DiscordErrored(errorCode, message)); + eventBus.post(DiscordErrored.class, new DiscordErrored(errorCode, message)); } private void joinGame(String joinSecret) { - eventBus.post(new DiscordJoinGame(joinSecret)); + eventBus.post(DiscordJoinGame.class, new DiscordJoinGame(joinSecret)); } private void spectateGame(String spectateSecret) { - eventBus.post(new DiscordSpectateGame(spectateSecret)); + eventBus.post(DiscordSpectateGame.class, new DiscordSpectateGame(spectateSecret)); } private void joinRequest(DiscordUser user) { - eventBus.post(new DiscordJoinRequest( + eventBus.post(DiscordJoinRequest.class, new DiscordJoinRequest( user.userId, user.username, user.discriminator, diff --git a/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java b/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java index a28f2f4371..a6b404bc14 100644 --- a/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java +++ b/runelite-client/src/main/java/net/runelite/client/eventbus/EventBus.java @@ -1,249 +1,72 @@ -/* - * Copyright (c) 2018, Tomas Slusny - * Copyright (c) 2018, Abex - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ package net.runelite.client.eventbus; -import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; -import java.lang.invoke.CallSite; -import java.lang.invoke.LambdaMetafactory; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.function.Consumer; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.ThreadSafe; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.Value; +import com.jakewharton.rxrelay2.PublishRelay; +import com.jakewharton.rxrelay2.Relay; +import io.reactivex.annotations.NonNull; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @Slf4j -@RequiredArgsConstructor -@ThreadSafe -public class EventBus +@Singleton +public class EventBus implements EventBusInterface { - @FunctionalInterface - public interface SubscriberMethod + private Map, Relay> subjectList = new HashMap<>(); + private Map subscriptionsMap = new HashMap<>(); + + @NonNull + private Relay getSubject(Class eventClass) { - void invoke(Object event); + return subjectList.computeIfAbsent(eventClass, k -> PublishRelay.create().toSerialized()); } - @Value - private static class Subscriber + @NonNull + private CompositeDisposable getCompositeDisposable(@NonNull Object object) { - private final Object object; - private final Method method; - @EqualsAndHashCode.Exclude - private final SubscriberMethod lamda; - - void invoke(final Object arg) throws Exception + CompositeDisposable compositeDisposable = subscriptionsMap.get(object); + if (compositeDisposable == null) { - if (lamda != null) + compositeDisposable = new CompositeDisposable(); + subscriptionsMap.put(object, compositeDisposable); + } + + return compositeDisposable; + } + + @Override + // Subscribe on lifecycle (for example from plugin startUp -> shutdown) + public void subscribe(Class eventClass, @NonNull Object lifecycle, @NonNull Consumer action) + { + Disposable disposable = getSubject(eventClass) + .filter(Objects::nonNull) // Filter out null objects, better safe than sorry + .cast(eventClass) // Cast it for easier usage + .subscribe(action, error -> { - lamda.invoke(arg); - } - else - { - method.invoke(object, arg); - } + log.error("Error in eventbus: {}", error.getMessage()); + }); + + getCompositeDisposable(lifecycle).add(disposable); + } + + @Override + public void unregister(@NonNull Object lifecycle) + { + //We have to remove the composition from the map, because once you dispose it can't be used anymore + CompositeDisposable compositeDisposable = subscriptionsMap.remove(lifecycle); + if (compositeDisposable != null) + { + compositeDisposable.dispose(); } } - private final Consumer exceptionHandler; - private ImmutableMultimap subscribers = ImmutableMultimap.of(); - - /** - * Instantiates EventBus with default exception handler - */ - public EventBus() + @Override + public void post(Class eventClass, @NonNull Object event) { - this((e) -> log.warn("Uncaught exception in event subscriber", e)); - } - - /** - * Registers subscriber to EventBus. All methods in subscriber and it's parent classes are checked for - * {@link Subscribe} annotation and then added to map of subscriptions. - * - * @param object subscriber to register - * @throws IllegalArgumentException in case subscriber method name is wrong (correct format is 'on' + EventName - */ - public synchronized void register(@Nonnull final Object object) - { - final ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); - - if (subscribers != null) - { - builder.putAll(subscribers); - } - - for (Class clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass()) - { - for (final Method method : clazz.getDeclaredMethods()) - { - final Subscribe sub = method.getAnnotation(Subscribe.class); - - if (sub == null) - { - continue; - } - - Preconditions.checkArgument(method.getReturnType() == Void.TYPE, "@Subscribed method \"" + method + "\" cannot return a value"); - Preconditions.checkArgument(method.getParameterCount() == 1, "@Subscribed method \"" + method + "\" must take exactly 1 argument"); - Preconditions.checkArgument(!Modifier.isStatic(method.getModifiers()), "@Subscribed method \"" + method + "\" cannot be static"); - - final Class parameterClazz = method.getParameterTypes()[0]; - - Preconditions.checkArgument(!parameterClazz.isPrimitive(), "@Subscribed method \"" + method + "\" cannot subscribe to primitives"); - Preconditions.checkArgument((parameterClazz.getModifiers() & (Modifier.ABSTRACT | Modifier.INTERFACE)) == 0, "@Subscribed method \"" + method + "\" cannot subscribe to polymorphic classes"); - - for (Class psc = parameterClazz.getSuperclass(); psc != null; psc = psc.getSuperclass()) - { - if (subscribers.containsKey(psc)) - { - throw new IllegalArgumentException("@Subscribed method \"" + method + "\" cannot subscribe to class which inherits from subscribed class \"" + psc + "\""); - } - } - - final String preferredName = "on" + parameterClazz.getSimpleName(); - Preconditions.checkArgument(method.getName().equals(preferredName), "Subscribed method " + method + " should be named " + preferredName); - - method.setAccessible(true); - SubscriberMethod lambda = null; - - try - { - final MethodHandles.Lookup caller = privateLookupIn(clazz); - final MethodType subscription = MethodType.methodType(void.class, parameterClazz); - final MethodHandle target = caller.findVirtual(clazz, method.getName(), subscription); - final CallSite site = LambdaMetafactory.metafactory( - caller, - "invoke", - MethodType.methodType(SubscriberMethod.class, clazz), - subscription.changeParameterType(0, Object.class), - target, - subscription); - - final MethodHandle factory = site.getTarget(); - lambda = (SubscriberMethod) factory.bindTo(object).invokeExact(); - } - catch (Throwable e) - { - log.warn("Unable to create lambda for method {}", method, e); - } - - final Subscriber subscriber = new Subscriber(object, method, lambda); - builder.put(parameterClazz, subscriber); - log.debug("Registering {} - {}", parameterClazz, subscriber); - } - } - - subscribers = builder.build(); - } - - /** - * Unregisters all subscribed methods from provided subscriber object. - * - * @param object object to unsubscribe from - */ - public synchronized void unregister(@Nonnull final Object object) - { - if (subscribers == null) - { - return; - } - - final Multimap map = HashMultimap.create(); - map.putAll(subscribers); - - for (Class clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass()) - { - for (final Method method : clazz.getDeclaredMethods()) - { - final Subscribe sub = method.getAnnotation(Subscribe.class); - - if (sub == null) - { - continue; - } - - final Class parameterClazz = method.getParameterTypes()[0]; - map.remove(parameterClazz, new Subscriber(object, method, null)); - } - } - - subscribers = ImmutableMultimap.copyOf(map); - } - - /** - * Posts provided event to all registered subscribers. Subscriber calls are invoked immediately and in order - * in which subscribers were registered. - * - * @param event event to post - */ - public void post(@Nonnull final Object event) - { - for (final Subscriber subscriber : subscribers.get(event.getClass())) - { - try - { - subscriber.invoke(event); - } - catch (Exception e) - { - exceptionHandler.accept(e); - } - } - } - - private static MethodHandles.Lookup privateLookupIn(Class clazz) throws IllegalAccessException, NoSuchFieldException, InvocationTargetException - { - try - { - // Java 9+ has privateLookupIn method on MethodHandles, but since we are shipping and using Java 8 - // 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()); - } - catch (NoSuchMethodException e) - { - // In Java 8 we first do standard lookupIn class - final MethodHandles.Lookup lookupIn = MethodHandles.lookup().in(clazz); - - // and then we mark it as trusted for private lookup via reflection on private field - final Field modes = MethodHandles.Lookup.class.getDeclaredField("allowedModes"); - modes.setAccessible(true); - modes.setInt(lookupIn, -1); // -1 == TRUSTED - return lookupIn; - } + getSubject(eventClass).accept(event); } } diff --git a/runelite-client/src/main/java/net/runelite/client/eventbus/EventBusInterface.java b/runelite-client/src/main/java/net/runelite/client/eventbus/EventBusInterface.java new file mode 100644 index 0000000000..d0858562ef --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/eventbus/EventBusInterface.java @@ -0,0 +1,13 @@ +package net.runelite.client.eventbus; + +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Consumer; + +public interface EventBusInterface +{ + void subscribe(Class eventClass, @NonNull Object lifecycle, @NonNull Consumer action); + + void unregister(@NonNull Object lifecycle); + + void post(Class eventClass, @NonNull Object event); +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java b/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java index 0b80bbc7e9..2d5bbe832c 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java @@ -44,7 +44,7 @@ import net.runelite.api.IndexedSprite; import net.runelite.api.SpriteID; import net.runelite.api.events.ClanChanged; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; @@ -97,10 +97,17 @@ public class ClanManager private int modIconsLength; @Inject - private ClanManager(Client client, SpriteManager spriteManager) + private ClanManager( + final Client client, + final SpriteManager spriteManager, + final EventBus eventbus + ) { this.client = client; this.spriteManager = spriteManager; + + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventbus.subscribe(ClanChanged.class, this, this::onClanChanged); } public ClanMemberRank getRank(String playerName) @@ -123,8 +130,7 @@ public class ClanManager return modIconsLength - CLANCHAT_IMAGES.length + clanMemberRank.ordinal() - 1; } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGGED_IN && modIconsLength == 0) @@ -133,8 +139,7 @@ public class ClanManager } } - @Subscribe - public void onClanChanged(ClanChanged clanChanged) + private void onClanChanged(ClanChanged clanChanged) { clanRanksCache.invalidateAll(); } diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index f06de90882..71bc00f829 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -28,9 +28,14 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -50,121 +55,12 @@ import static net.runelite.api.Constants.HIGH_ALCHEMY_MULTIPLIER; import net.runelite.api.GameState; import net.runelite.api.ItemDefinition; import net.runelite.api.ItemID; -import static net.runelite.api.ItemID.AGILITY_CAPE; -import static net.runelite.api.ItemID.AGILITY_CAPET; -import static net.runelite.api.ItemID.AGILITY_CAPET_13341; -import static net.runelite.api.ItemID.AGILITY_CAPE_13340; -import static net.runelite.api.ItemID.BOOTS_OF_LIGHTNESS; -import static net.runelite.api.ItemID.BOOTS_OF_LIGHTNESS_89; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_11861; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13589; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13590; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13601; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13602; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13613; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13614; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13625; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13626; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13637; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13638; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13677; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13678; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_21076; -import static net.runelite.api.ItemID.GRACEFUL_BOOTS_21078; -import static net.runelite.api.ItemID.GRACEFUL_CAPE; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_11853; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13581; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13582; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13593; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13594; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13605; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13606; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13617; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13618; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13629; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13630; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13669; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_13670; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_21064; -import static net.runelite.api.ItemID.GRACEFUL_CAPE_21066; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_11859; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13587; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13588; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13599; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13600; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13611; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13612; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13623; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13624; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13635; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13636; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13675; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13676; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_21073; -import static net.runelite.api.ItemID.GRACEFUL_GLOVES_21075; -import static net.runelite.api.ItemID.GRACEFUL_HOOD; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_11851; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13579; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13580; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13591; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13592; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13603; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13604; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13615; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13616; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13627; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13628; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13667; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_13668; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_21061; -import static net.runelite.api.ItemID.GRACEFUL_HOOD_21063; -import static net.runelite.api.ItemID.GRACEFUL_LEGS; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_11857; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13585; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13586; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13597; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13598; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13609; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13610; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13621; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13622; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13633; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13634; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13673; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_13674; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_21070; -import static net.runelite.api.ItemID.GRACEFUL_LEGS_21072; -import static net.runelite.api.ItemID.GRACEFUL_TOP; -import static net.runelite.api.ItemID.GRACEFUL_TOP_11855; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13583; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13584; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13595; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13596; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13607; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13608; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13619; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13620; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13631; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13632; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13671; -import static net.runelite.api.ItemID.GRACEFUL_TOP_13672; -import static net.runelite.api.ItemID.GRACEFUL_TOP_21067; -import static net.runelite.api.ItemID.GRACEFUL_TOP_21069; -import static net.runelite.api.ItemID.MAX_CAPE; -import static net.runelite.api.ItemID.MAX_CAPE_13342; -import static net.runelite.api.ItemID.PENANCE_GLOVES; -import static net.runelite.api.ItemID.PENANCE_GLOVES_10554; -import static net.runelite.api.ItemID.SPOTTED_CAPE; -import static net.runelite.api.ItemID.SPOTTED_CAPE_10073; -import static net.runelite.api.ItemID.SPOTTIER_CAPE; -import static net.runelite.api.ItemID.SPOTTIER_CAPE_10074; +import static net.runelite.api.ItemID.*; import net.runelite.api.Sprite; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.PostItemDefinition; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemStats; @@ -174,33 +70,6 @@ import org.jetbrains.annotations.NotNull; @Slf4j public class ItemManager { - @Value - private static class ImageKey - { - private final int itemId; - private final int itemQuantity; - private final boolean stackable; - } - - @Value - private static class OutlineKey - { - private final int itemId; - private final int itemQuantity; - private final Color outlineColor; - } - - private final Client client; - private final ScheduledExecutorService scheduledExecutorService; - private final ClientThread clientThread; - - private final ItemClient itemClient = new ItemClient(); - private Map itemPrices = Collections.emptyMap(); - private Map itemStats = Collections.emptyMap(); - private final LoadingCache itemImages; - private final LoadingCache itemDefinitions; - private final LoadingCache itemOutlines; - // Worn items with weight reducing property have a different worn and inventory ItemID private static final ImmutableMap WORN_ITEMS = ImmutableMap.builder(). put(BOOTS_OF_LIGHTNESS_89, BOOTS_OF_LIGHTNESS). @@ -263,9 +132,23 @@ public class ItemManager put(AGILITY_CAPET_13341, AGILITY_CAPET). put(AGILITY_CAPE_13340, AGILITY_CAPE). build(); - + private final Client client; + private final ScheduledExecutorService scheduledExecutorService; + private final ClientThread clientThread; + private final ItemClient itemClient = new ItemClient(); + private final ImmutableMap itemStatMap; + private final LoadingCache itemImages; + private final LoadingCache itemDefinitions; + private final LoadingCache itemOutlines; + private Map itemPrices = Collections.emptyMap(); + private Map itemStats = Collections.emptyMap(); @Inject - public ItemManager(Client client, ScheduledExecutorService executor, ClientThread clientThread) + public ItemManager( + Client client, + ScheduledExecutorService executor, + ClientThread clientThread, + EventBus eventbus + ) { this.client = client; this.scheduledExecutorService = executor; @@ -309,6 +192,19 @@ public class ItemManager return loadItemOutline(key.itemId, key.itemQuantity, key.outlineColor); } }); + + final Gson gson = new Gson(); + + final Type typeToken = new TypeToken>() + { + }.getType(); + + final InputStream statsFile = getClass().getResourceAsStream("/item_stats.json"); + final Map stats = gson.fromJson(new InputStreamReader(statsFile), typeToken); + itemStatMap = ImmutableMap.copyOf(stats); + + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventbus.subscribe(PostItemDefinition.class, this, this::onPostItemDefinition); } private void loadPrices() @@ -352,9 +248,7 @@ public class ItemManager } } - - @Subscribe - public void onGameStateChanged(final GameStateChanged event) + private void onGameStateChanged(final GameStateChanged event) { if (event.getGameState() == GameState.HOPPING || event.getGameState() == GameState.LOGIN_SCREEN) { @@ -362,8 +256,7 @@ public class ItemManager } } - @Subscribe - public void onPostItemDefinition(PostItemDefinition event) + private void onPostItemDefinition(PostItemDefinition event) { itemDefinitions.put(event.getItemDefinition().getId(), event.getItemDefinition()); } @@ -392,7 +285,7 @@ public class ItemManager /** * Look up an item's price * - * @param itemID item id + * @param itemID item id * @param ignoreUntradeableMap should the price returned ignore the {@link UntradeableItemMapping} * @return item price */ @@ -473,7 +366,7 @@ public class ItemManager return null; } - return itemStats.get(canonicalize(itemId)); + return itemStatMap.get(canonicalize(itemId)); } /** @@ -629,4 +522,20 @@ public class ItemManager return null; } } + + @Value + private static class ImageKey + { + private final int itemId; + private final int itemQuantity; + private final boolean stackable; + } + + @Value + private static class OutlineKey + { + private final int itemId; + private final int itemQuantity; + private final Color outlineColor; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemStat.java b/runelite-client/src/main/java/net/runelite/client/game/ItemStat.java new file mode 100644 index 0000000000..92746d052c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemStat.java @@ -0,0 +1,27 @@ +package net.runelite.client.game; + +import lombok.Value; + +@Value +public class ItemStat +{ + private int slot; + + private int astab; + private int aslash; + private int acrush; + private int amagic; + private int arange; + + private int dstab; + private int dslash; + private int dcrush; + private int dmagic; + private int drange; + + private int str; + private int rstr; + private int mdmg; + private int prayer; + private int aspeed; +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/LootManager.java b/runelite-client/src/main/java/net/runelite/client/game/LootManager.java index e297e103c7..2a6ad376de 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/LootManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/LootManager.java @@ -54,7 +54,6 @@ import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.PlayerDespawned; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.NpcLootReceived; import net.runelite.client.events.PlayerLootReceived; @@ -74,14 +73,24 @@ public class LootManager private WorldPoint krakenPlayerLocation; @Inject - private LootManager(EventBus eventBus, Client client) + private LootManager( + final EventBus eventBus, + final Client client + ) { this.eventBus = eventBus; this.client = client; + + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + eventBus.subscribe(ItemSpawned.class, this, this::onItemSpawned); + eventBus.subscribe(ItemDespawned.class, this, this::onItemDespawned); + eventBus.subscribe(ItemQuantityChanged.class, this, this::onItemQuantityChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { final NPC npc = npcDespawned.getNpc(); if (!npc.isDead()) @@ -123,8 +132,7 @@ public class LootManager processNpcLoot(npc); } - @Subscribe - public void onPlayerDespawned(PlayerDespawned playerDespawned) + private void onPlayerDespawned(PlayerDespawned playerDespawned) { final Player player = playerDespawned.getPlayer(); // Only care about dead Players @@ -150,11 +158,10 @@ public class LootManager } killPoints.add(location); - eventBus.post(new PlayerLootReceived(player, items)); + eventBus.post(PlayerLootReceived.class, new PlayerLootReceived(player, items)); } - @Subscribe - public void onItemSpawned(ItemSpawned itemSpawned) + private void onItemSpawned(ItemSpawned itemSpawned) { final Item item = itemSpawned.getItem(); final Tile tile = itemSpawned.getTile(); @@ -164,16 +171,14 @@ public class LootManager log.debug("Item spawn {} ({}) location {},{}", item.getId(), item.getQuantity(), location); } - @Subscribe - public void onItemDespawned(ItemDespawned itemDespawned) + private void onItemDespawned(ItemDespawned itemDespawned) { final Item item = itemDespawned.getItem(); final LocalPoint location = itemDespawned.getTile().getLocalLocation(); log.debug("Item despawn {} ({}) location {},{}", item.getId(), item.getQuantity(), location); } - @Subscribe - public void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) + private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) { final Item item = itemQuantityChanged.getItem(); final Tile tile = itemQuantityChanged.getTile(); @@ -189,8 +194,7 @@ public class LootManager itemSpawns.put(packed, new ItemStack(item.getId(), diff, location)); } - @Subscribe - public void onAnimationChanged(AnimationChanged e) + private void onAnimationChanged(AnimationChanged e) { if (!(e.getActor() instanceof NPC)) { @@ -219,8 +223,7 @@ public class LootManager } } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { playerLocationLastTick = client.getLocalPlayer().getWorldLocation(); itemSpawns.clear(); @@ -257,7 +260,7 @@ public class LootManager } killPoints.add(location); - eventBus.post(new NpcLootReceived(npc, allItems)); + eventBus.post(NpcLootReceived.class, new NpcLootReceived(npc, allItems)); } private WorldPoint getDropLocation(NPC npc, WorldPoint worldLocation) diff --git a/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java b/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java index df81112d27..63469c4e49 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/SpriteManager.java @@ -37,14 +37,14 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.SwingUtilities; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.Sprite; import net.runelite.client.callback.ClientThread; +import net.runelite.client.ui.overlay.infobox.InfoBox; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.ImageUtil; -@Slf4j @Singleton public class SpriteManager { @@ -54,7 +54,10 @@ public class SpriteManager @Inject private ClientThread clientThread; - private final Cache cache = CacheBuilder.newBuilder() + @Inject + private InfoBoxManager infoBoxManager; + + public Cache cache = CacheBuilder.newBuilder() .maximumSize(128L) .expireAfterAccess(1, TimeUnit.HOURS) .build(); @@ -76,6 +79,11 @@ public class SpriteManager } Sprite[] sp = client.getSprites(client.getIndexSprites(), archive, 0); + if (sp == null) + { + return null; + } + BufferedImage img = sp[file].toBufferedImage(); cache.put(key, img); @@ -104,6 +112,15 @@ public class SpriteManager }); } + public void getSpriteAsync(int archive, int file, InfoBox infoBox) + { + getSpriteAsync(archive, file, img -> + { + infoBox.setImage(img); + infoBoxManager.updateInfoBoxImage(infoBox); + }); + } + /** * Calls setIcon on c, ensuring it is repainted when this changes */ diff --git a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java index 3e70483d2f..59c6d72a00 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxPanelManager.java @@ -41,7 +41,6 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseListener; @@ -79,6 +78,10 @@ public class ChatboxPanelManager this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider; this.chatboxTextInputProvider = chatboxTextInputProvider; + + + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); } public void close() @@ -103,7 +106,7 @@ public class ChatboxPanelManager { client.runScript(ScriptID.CLEAR_CHATBOX_PANEL); - eventBus.register(input); + // eventBus.register(input); if (input instanceof KeyListener) { keyManager.registerKeyListener((KeyListener) input); @@ -150,8 +153,7 @@ public class ChatboxPanelManager .prompt(prompt); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent ev) + private void onScriptCallbackEvent(ScriptCallbackEvent ev) { if (currentInput != null && "resetChatboxInput".equals(ev.getEventName())) { @@ -159,7 +161,6 @@ public class ChatboxPanelManager } } - @Subscribe private void onGameStateChanged(GameStateChanged ev) { if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN) diff --git a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextMenuInput.java b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextMenuInput.java index d1c7d8fd44..cb4cc632e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextMenuInput.java +++ b/runelite-client/src/main/java/net/runelite/client/game/chatbox/ChatboxTextMenuInput.java @@ -31,7 +31,6 @@ import java.util.List; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.FontID; import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.Widget; @@ -41,7 +40,6 @@ import net.runelite.api.widgets.WidgetTextAlignment; import net.runelite.api.widgets.WidgetType; import net.runelite.client.input.KeyListener; -@Slf4j public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener { @Data 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 70ab8ebadf..242e3df28f 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 @@ -66,7 +66,6 @@ import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.events.WidgetPressed; 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 @@ -106,6 +105,15 @@ public class MenuManager { this.client = client; this.eventBus = eventBus; + + + eventBus.subscribe(MenuOpened.class, this, this::onMenuOpened); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(BeforeRender.class, this, this::onBeforeRender); + eventBus.subscribe(PlayerMenuOptionsChanged.class, this, this::onPlayerMenuOptionsChanged); + eventBus.subscribe(NpcActionChanged.class, this, this::onNpcActionChanged); + eventBus.subscribe(WidgetPressed.class, this, this::onWidgetPressed); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); } /** @@ -145,8 +153,7 @@ public class MenuManager return false; } - @Subscribe - public void onMenuOpened(MenuOpened event) + private void onMenuOpened(MenuOpened event) { currentPriorityEntries.clear(); @@ -256,8 +263,7 @@ public class MenuManager client.setMenuEntries(arrayEntries); } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { int widgetId = event.getActionParam1(); Collection options = managedMenuOptions.get(widgetId); @@ -280,8 +286,7 @@ public class MenuManager } } - @Subscribe - public void onBeforeRender(BeforeRender event) + private void onBeforeRender(BeforeRender event) { rebuildLeftClickMenu(); } @@ -364,8 +369,7 @@ public class MenuManager } } - @Subscribe - public void onPlayerMenuOptionsChanged(PlayerMenuOptionsChanged event) + private void onPlayerMenuOptionsChanged(PlayerMenuOptionsChanged event) { int idx = event.getIndex(); @@ -389,8 +393,7 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onNpcActionChanged(NpcActionChanged event) + private void onNpcActionChanged(NpcActionChanged event) { NPCDefinition composition = event.getNpcDefinition(); for (String npcOption : npcMenuOptions) @@ -439,14 +442,12 @@ public class MenuManager } } - @Subscribe - public void onWidgetPressed(WidgetPressed event) + private void onWidgetPressed(WidgetPressed event) { leftClickEntry = rebuildLeftClickMenu(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (!client.isMenuOpen() && event.isAuthentic()) { @@ -481,7 +482,7 @@ public class MenuManager customMenu.setMenuOption(event.getOption()); customMenu.setMenuTarget(event.getTarget()); customMenu.setWidget(curMenuOption.getWidget()); - eventBus.post(customMenu); + eventBus.post(WidgetMenuOptionClicked.class, customMenu); return; // don't continue because it's not a player option } } @@ -496,7 +497,7 @@ public class MenuManager playerMenuOptionClicked.setMenuOption(event.getOption()); playerMenuOptionClicked.setMenuTarget(username); - eventBus.post(playerMenuOptionClicked); + eventBus.post(PlayerMenuOptionClicked.class, playerMenuOptionClicked); } private void addPlayerMenuItem(int playerOptionIndex, String menuText) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index 52488fb4e3..d3627aabe4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -68,7 +68,6 @@ import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PluginChanged; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; @@ -126,14 +125,12 @@ public class PluginManager pluginWatcher.start(); } - @Subscribe - public void onSessionOpen(SessionOpen event) + private void onSessionOpen(SessionOpen event) { refreshPlugins(); } - @Subscribe - public void onSessionClose(SessionClose event) + private void onSessionClose(SessionClose event) { refreshPlugins(); } @@ -368,9 +365,9 @@ public class PluginManager } } - eventBus.register(plugin); + // eventBus.register(plugin); schedule(plugin); - eventBus.post(new PluginChanged(plugin, true)); + eventBus.post(PluginChanged.class, new PluginChanged(plugin, true)); } catch (InterruptedException | InvocationTargetException | IllegalArgumentException ex) { @@ -392,7 +389,6 @@ public class PluginManager try { unschedule(plugin); - eventBus.unregister(plugin); // plugins always stop in the event thread SwingUtilities.invokeAndWait(() -> @@ -408,7 +404,7 @@ public class PluginManager }); log.debug("Plugin {} is now stopped", plugin.getClass().getSimpleName()); - eventBus.post(new PluginChanged(plugin, false)); + eventBus.post(PluginChanged.class, new PluginChanged(plugin, false)); } catch (InterruptedException | InvocationTargetException ex) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java index 07bd977a81..a6fb299f50 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java @@ -32,7 +32,7 @@ import javax.swing.JOptionPane; import lombok.extern.slf4j.Slf4j; import net.runelite.client.account.AccountSession; import net.runelite.client.account.SessionManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.plugins.Plugin; @@ -60,6 +60,9 @@ public class AccountPlugin extends Plugin @Inject private ScheduledExecutorService executor; + @Inject + private EventBus eventBus; + private NavigationButton loginButton; private NavigationButton logoutButton; @@ -74,6 +77,8 @@ public class AccountPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + loginButton = NavigationButton.builder() .tab(false) .icon(LOGIN_IMAGE) @@ -103,10 +108,18 @@ public class AccountPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + clientToolbar.removeNavigation(loginButton); clientToolbar.removeNavigation(logoutButton); } + private void addSubscriptions() + { + eventBus.subscribe(SessionClose.class, this, this::onSessionClose); + eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); + } + private void loginClick() { executor.execute(sessionManager::login); @@ -122,14 +135,12 @@ public class AccountPlugin extends Plugin } } - @Subscribe - public void onSessionClose(SessionClose e) + private void onSessionClose(SessionClose e) { addAndRemoveButtons(); } - @Subscribe - public void onSessionOpen(SessionOpen sessionOpen) + private void onSessionOpen(SessionOpen sessionOpen) { AccountSession session = sessionManager.getAccountSession(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/DiaryRequirementsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/DiaryRequirementsPlugin.java index 341e17a7aa..27369d8153 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/DiaryRequirementsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/DiaryRequirementsPlugin.java @@ -44,7 +44,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.achievementdiary.diaries.ArdougneDiaryRequirement; @@ -79,8 +79,22 @@ public class DiaryRequirementsPlugin extends Plugin @Inject private ClientThread clientThread; - @Subscribe - public void onWidgetLoaded(final WidgetLoaded event) + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void onWidgetLoaded(final WidgetLoaded event) { if (event.getGroupId() == WidgetID.DIARY_QUEST_GROUP_ID) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java index 3f7ac5b498..42a1dad7bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java @@ -70,7 +70,7 @@ import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.AgilityShortcut; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; @@ -120,6 +120,9 @@ public class AgilityPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private AgilitySession session; @@ -166,6 +169,7 @@ public class AgilityPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(agilityOverlay); overlayManager.add(lapCounterOverlay); @@ -175,6 +179,8 @@ public class AgilityPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(agilityOverlay); overlayManager.remove(lapCounterOverlay); marksOfGrace.clear(); @@ -183,8 +189,31 @@ public class AgilityPlugin extends Plugin agilityLevel = 0; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(BoostedLevelChanged.class, this, this::onBoostedLevelChanged); + eventBus.subscribe(ItemSpawned.class, this, this::onItemSpawned); + eventBus.subscribe(ItemDespawned.class, this, this::onItemDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(GroundObjectChanged.class, this, this::onGroundObjectChanged); + eventBus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(WallObjectChanged.class, this, this::onWallObjectChanged); + eventBus.subscribe(WallObjectDespawned.class, this, this::onWallObjectDespawned); + eventBus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned); + eventBus.subscribe(DecorativeObjectChanged.class, this, this::onDecorativeObjectChanged); + eventBus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -208,8 +237,7 @@ public class AgilityPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("agility")) { @@ -242,8 +270,7 @@ public class AgilityPlugin extends Plugin this.showShortcutLevel = config.showShortcutLevel(); } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void onExperienceChanged(ExperienceChanged event) { if (event.getSkill() != AGILITY || !this.showLapCount) { @@ -278,9 +305,7 @@ public class AgilityPlugin extends Plugin } } - - @Subscribe - public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged) + private void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged) { Skill skill = boostedLevelChanged.getSkill(); if (skill == AGILITY) @@ -289,8 +314,7 @@ public class AgilityPlugin extends Plugin } } - @Subscribe - public void onItemSpawned(ItemSpawned itemSpawned) + private void onItemSpawned(ItemSpawned itemSpawned) { if (obstacles.isEmpty()) { @@ -306,15 +330,13 @@ public class AgilityPlugin extends Plugin } } - @Subscribe - public void onItemDespawned(ItemDespawned itemDespawned) + private void onItemDespawned(ItemDespawned itemDespawned) { final Tile tile = itemDespawned.getTile(); marksOfGrace.remove(tile); } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { if (isInAgilityArena()) { @@ -365,74 +387,62 @@ public class AgilityPlugin extends Plugin infoBoxManager.addInfoBox(new AgilityArenaTimer(this, itemManager.getImage(AGILITY_ARENA_TICKET))); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { onTileObject(event.getTile(), null, event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { onTileObject(event.getTile(), event.getGameObject(), null); } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { onTileObject(event.getTile(), null, event.getGroundObject()); } - @Subscribe - public void onGroundObjectChanged(GroundObjectChanged event) + private void onGroundObjectChanged(GroundObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject()); } - @Subscribe - public void onGroundObjectDespawned(GroundObjectDespawned event) + private void onGroundObjectDespawned(GroundObjectDespawned event) { onTileObject(event.getTile(), event.getGroundObject(), null); } - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) + private void onWallObjectSpawned(WallObjectSpawned event) { onTileObject(event.getTile(), null, event.getWallObject()); } - @Subscribe - public void onWallObjectChanged(WallObjectChanged event) + private void onWallObjectChanged(WallObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getWallObject()); } - @Subscribe - public void onWallObjectDespawned(WallObjectDespawned event) + private void onWallObjectDespawned(WallObjectDespawned event) { onTileObject(event.getTile(), event.getWallObject(), null); } - @Subscribe - public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + private void onDecorativeObjectSpawned(DecorativeObjectSpawned event) { onTileObject(event.getTile(), null, event.getDecorativeObject()); } - @Subscribe - public void onDecorativeObjectChanged(DecorativeObjectChanged event) + private void onDecorativeObjectChanged(DecorativeObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject()); } - @Subscribe - public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + private void onDecorativeObjectDespawned(DecorativeObjectDespawned event) { onTileObject(event.getTile(), event.getDecorativeObject(), null); } @@ -484,8 +494,7 @@ public class AgilityPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!this.showShortcutLevel) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/alchemicalhydra/HydraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/alchemicalhydra/HydraPlugin.java index fe94944427..7bdc96738a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/alchemicalhydra/HydraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/alchemicalhydra/HydraPlugin.java @@ -46,7 +46,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.ProjectileMoved; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -89,9 +89,14 @@ public class HydraPlugin extends Plugin @Inject private HydraSceneOverlay poisonOverlay; + @Inject + private EventBus eventBus; + @Override protected void startUp() { + addSubscriptions(); + inHydraInstance = checkArea(); lastAttackTick = -1; poisonProjectiles.clear(); @@ -100,6 +105,8 @@ public class HydraPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + inHydraInstance = false; hydra = null; poisonProjectiles.clear(); @@ -107,7 +114,15 @@ public class HydraPlugin extends Plugin lastAttackTick = -1; } - @Subscribe + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + private void onGameStateChanged(GameStateChanged state) { if (state.getGameState() != GameState.LOGGED_IN) @@ -140,7 +155,6 @@ public class HydraPlugin extends Plugin addOverlays(); } - @Subscribe private void onNpcSpawned(NpcSpawned event) { if (!inHydraInstance || event.getNpc().getId() != NpcID.ALCHEMICAL_HYDRA) @@ -152,8 +166,7 @@ public class HydraPlugin extends Plugin addOverlays(); } - @Subscribe - public void onAnimationChanged(AnimationChanged animationChanged) + private void onAnimationChanged(AnimationChanged animationChanged) { Actor actor = animationChanged.getActor(); @@ -215,8 +228,7 @@ public class HydraPlugin extends Plugin } } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void onProjectileMoved(ProjectileMoved event) { if (!inHydraInstance || hydra == null || client.getGameCycle() >= event.getProjectile().getStartMovementCycle()) @@ -245,8 +257,7 @@ public class HydraPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (!event.getMessage().equals("The chemicals neutralise the Alchemical Hydra's defences!")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java index ee2b31666b..9796ef08ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ammo/AmmoPlugin.java @@ -35,7 +35,7 @@ import net.runelite.api.ItemDefinition; import net.runelite.api.ItemContainer; import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -61,11 +61,16 @@ public class AmmoPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + private AmmoCounter counterBox; @Override protected void startUp() throws Exception { + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + clientThread.invokeLater(() -> { final ItemContainer container = client.getItemContainer(InventoryID.EQUIPMENT); @@ -80,12 +85,13 @@ public class AmmoPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + infoBoxManager.removeInfoBox(counterBox); counterBox = null; } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/animsmoothing/AnimationSmoothingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/animsmoothing/AnimationSmoothingPlugin.java index 7c77990a26..c21a4504ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/animsmoothing/AnimationSmoothingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/animsmoothing/AnimationSmoothingPlugin.java @@ -30,7 +30,7 @@ import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -51,6 +51,9 @@ public class AnimationSmoothingPlugin extends Plugin @Inject private AnimationSmoothingConfig config; + @Inject + private EventBus eventBus; + @Provides AnimationSmoothingConfig getConfig(ConfigManager configManager) { @@ -60,20 +63,23 @@ public class AnimationSmoothingPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + update(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + client.setInterpolatePlayerAnimations(false); client.setInterpolateNpcAnimations(false); client.setInterpolateObjectAnimations(false); client.setInterpolateWidgetAnimations(false); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals(CONFIG_GROUP)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java index bd3de31419..833a07e2a3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java @@ -80,9 +80,7 @@ public interface AntiDragConfig extends Config keyName = "dragDelay", name = "Drag Delay", description = "Configures the inventory drag delay in client ticks (20ms)", - position = 3, - hidden = true, - unhide = "keybind" + position = 3 ) default int dragDelay() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java index ed6d07b6af..40cd4dc623 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragPlugin.java @@ -36,7 +36,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.Keybind; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -81,6 +81,9 @@ public class AntiDragPlugin extends Plugin @Inject private KeyManager keyManager; + @Inject + private EventBus eventBus; + @Provides AntiDragConfig getConfig(ConfigManager configManager) { @@ -102,7 +105,9 @@ public class AntiDragPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); updateConfig(); + if (this.keybind) { keyManager.registerKeyListener(hotkeyListener); @@ -113,14 +118,21 @@ public class AntiDragPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + client.setInventoryDragDelay(DEFAULT_DELAY); keyManager.unregisterKeyListener(hotkeyListener); toggleDrag = false; overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("antiDrag")) { @@ -141,6 +153,10 @@ public class AntiDragPlugin extends Plugin { client.setInventoryDragDelay(this.alwaysOn ? this.dragDelay : DEFAULT_DELAY); } + if (event.getKey().equals("dragDelay") && this.alwaysOn) + { + client.setInventoryDragDelay(this.dragDelay); + } } } @@ -157,8 +173,7 @@ public class AntiDragPlugin extends Plugin this.selectedCursor = config.selectedCursor(); } - @Subscribe - public void onFocusChanged(FocusChanged focusChanged) + private void onFocusChanged(FocusChanged focusChanged) { if (!this.alwaysOn && !focusChanged.isFocused() && this.reqfocus) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java index 7fcf46c32d..bf288c62ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeProjectileInfo.java @@ -123,7 +123,12 @@ public enum AoeProjectileInfo /** * Demonic gorilla */ - DEMONIC_GORILLA_BOULDER(ProjectileID.DEMONIC_GORILLA_BOULDER, 1); + DEMONIC_GORILLA_BOULDER(ProjectileID.DEMONIC_GORILLA_BOULDER, 1), + + /** + * Marble gargoyle (Superior Gargoyle) + */ + MARBLE_GARGOYLE_AOE(ProjectileID.MARBLE_GARGOYLE_AOE, 1); private static final Map map = new HashMap<>(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java index 95ea50287e..8c7a98d914 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/aoewarnings/AoeWarningPlugin.java @@ -59,7 +59,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.ProjectileMoved; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -92,6 +92,8 @@ public class AoeWarningPlugin extends Plugin private BombOverlay bombOverlay; @Inject private Client client; + @Inject + private EventBus eventbus; @Getter(AccessLevel.PACKAGE) private List LightningTrail = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) @@ -170,6 +172,7 @@ public class AoeWarningPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(coreOverlay); overlayManager.add(bombOverlay); @@ -179,13 +182,24 @@ public class AoeWarningPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventbus.unregister(this); + overlayManager.remove(coreOverlay); overlayManager.remove(bombOverlay); reset(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventbus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventbus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventbus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("aoe")) { @@ -195,8 +209,7 @@ public class AoeWarningPlugin extends Plugin updateConfig(); } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void onProjectileMoved(ProjectileMoved event) { Projectile projectile = event.getProjectile(); @@ -223,8 +236,7 @@ public class AoeWarningPlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { final GameObject gameObject = event.getGameObject(); final WorldPoint wp = gameObject.getWorldLocation(); @@ -260,8 +272,7 @@ public class AoeWarningPlugin extends Plugin } } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { GameObject gameObject = event.getGameObject(); WorldPoint wp = gameObject.getWorldLocation(); @@ -286,8 +297,7 @@ public class AoeWarningPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged delta) + private void onGameStateChanged(GameStateChanged delta) { if (client.getGameState() == GameState.LOGGED_IN) { @@ -295,8 +305,7 @@ public class AoeWarningPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (this.configLightningTrail) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java index 1a99f715af..66a6b3abd5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/AttackStylesPlugin.java @@ -50,7 +50,7 @@ import net.runelite.api.widgets.WidgetInfo; import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING; @@ -89,6 +89,9 @@ public class AttackStylesPlugin extends Plugin @Inject private AttackStylesOverlay overlay; + @Inject + private EventBus eventBus; + @Provides AttackStylesConfig provideConfig(ConfigManager configManager) { @@ -110,6 +113,7 @@ public class AttackStylesPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); @@ -140,12 +144,23 @@ public class AttackStylesPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); hideWarnedStyles(false); processWidgets(); hideWidget(client.getWidget(WidgetInfo.COMBAT_AUTO_RETALIATE), false); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + public AttackStyle getAttackStyle() { return attackStyle; @@ -156,8 +171,7 @@ public class AttackStylesPlugin extends Plugin return warnedSkillSelected; } - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged event) + private void onWidgetHiddenChanged(WidgetHiddenChanged event) { if (event.getWidget().isSelfHidden() || TO_GROUP(event.getWidget().getId()) != COMBAT_GROUP_ID) { @@ -167,8 +181,7 @@ public class AttackStylesPlugin extends Plugin processWidgets(); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() != COMBAT_GROUP_ID) { @@ -195,8 +208,7 @@ public class AttackStylesPlugin extends Plugin hideWidget(client.getWidget(WidgetInfo.COMBAT_AUTO_RETALIATE), this.hideAutoRetaliate); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -208,8 +220,7 @@ public class AttackStylesPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + void onVarbitChanged(VarbitChanged event) { if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE)) { @@ -236,8 +247,7 @@ public class AttackStylesPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("attackIndicator")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bank/BankPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/bank/BankPlugin.java index d5cebbd51d..3e5693165a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bank/BankPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bank/BankPlugin.java @@ -39,7 +39,7 @@ import net.runelite.api.events.MenuShouldLeftClick; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.banktags.tabs.BankSearch; @@ -72,6 +72,9 @@ public class BankPlugin extends Plugin @Inject private BankSearch bankSearch; + @Inject + private EventBus eventBus; + private boolean forceRightClickFlag; @Provides @@ -93,17 +96,26 @@ public class BankPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); } @Override protected void shutDown() { + eventBus.unregister(this); clientThread.invokeLater(() -> bankSearch.reset(false)); forceRightClickFlag = false; } - @Subscribe - public void onMenuShouldLeftClick(MenuShouldLeftClick event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(MenuShouldLeftClick.class, this, this::onMenuShouldLeftClick); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onMenuShouldLeftClick(MenuShouldLeftClick event) { if (!forceRightClickFlag) { @@ -124,8 +136,7 @@ public class BankPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if ((event.getOption().equals(DEPOSIT_WORN) && this.rightClickBankEquip) || (event.getOption().equals(DEPOSIT_INVENTORY) && this.rightClickBankInventory) @@ -135,8 +146,7 @@ public class BankPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!event.getEventName().equals("setBankTitle")) { @@ -192,8 +202,7 @@ public class BankPlugin extends Plugin stringStack[stringStackSize - 1] += strCurrentTab; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("bank")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 11c64fd0e3..b7bbb97a3c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -60,7 +60,7 @@ import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; @@ -132,6 +132,9 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis @Inject private SpriteManager spriteManager; + @Inject + private EventBus eventBus; + private boolean shiftPressed = false; private int nextRowIndex = 0; @@ -144,6 +147,8 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis @Override public void startUp() { + addSubscriptions(); + keyManager.registerKeyListener(this); mouseManager.registerMouseWheelListener(this); clientThread.invokeLater(tabInterface::init); @@ -153,6 +158,8 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis @Override public void shutDown() { + eventBus.unregister(this); + keyManager.unregisterKeyListener(this); mouseManager.unregisterMouseWheelListener(this); clientThread.invokeLater(tabInterface::destroy); @@ -161,6 +168,18 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis shiftPressed = false; } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(DraggingWidgetChanged.class, this, this::onDraggingWidgetChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + private boolean isSearching() { return client.getVar(VarClientInt.INPUT_TYPE) == InputType.SEARCH.getType() @@ -168,8 +187,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis && client.getVar(VarClientStr.INPUT_TEXT) != null && client.getVar(VarClientStr.INPUT_TEXT).length() > 0); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { String eventName = event.getEventName(); @@ -284,8 +302,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { MenuEntry[] entries = client.getMenuEntries(); @@ -318,8 +335,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis tabInterface.handleAdd(event); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getMenuAction() == MenuAction.RUNELITE @@ -393,8 +409,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis } } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getGroup().equals("banktags") && configChanged.getKey().equals("useTabs")) { @@ -409,20 +424,17 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { tabInterface.update(); } - @Subscribe - public void onDraggingWidgetChanged(DraggingWidgetChanged event) + private void onDraggingWidgetChanged(DraggingWidgetChanged event) { tabInterface.handleDrag(event.isDraggingWidget(), shiftPressed); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() == WidgetID.BANK_GROUP_ID) { @@ -430,8 +442,7 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis } } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void onFocusChanged(FocusChanged event) { if (!event.isFocused()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 1e26d51f87..66f25035c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -565,7 +565,15 @@ public class TabInterface return; } - if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() + if (chatboxPanelManager.getCurrentInput() != null + && event.getMenuAction() != MenuAction.CANCEL + && !event.getMenuEntry().equals(SCROLL_UP) + && !event.getMenuEntry().equals(SCROLL_DOWN)) + { + chatboxPanelManager.close(); + } + + if (event.getIdentifier() == WidgetInfo.BANK_ITEM_CONTAINER.getId() && event.getMenuAction() == MenuAction.EXAMINE_ITEM_BANK_EQ && event.getOption().equalsIgnoreCase("withdraw-x")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banlist/BanListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banlist/BanListPlugin.java index a34b7e756c..ea7875f1de 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banlist/BanListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banlist/BanListPlugin.java @@ -56,7 +56,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -91,6 +91,8 @@ public class BanListPlugin extends Plugin private BanListConfig config; @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; private String tobNames = ""; private boolean enableWDRScam; private boolean enableWDRToxic; @@ -108,6 +110,7 @@ public class BanListPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); List bannedPlayers = Splitter .on(",") .trimResults() @@ -120,14 +123,24 @@ public class BanListPlugin extends Plugin @Override protected void shutDown() throws Exception { + + eventBus.unregister(this); wdrScamSet.clear(); wdrToxicSet.clear(); runeWatchSet.clear(); manualBans.clear(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + eventBus.subscribe(ClanMemberJoined.class, this, this::onClanMemberJoined); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("banlist") && event.getKey().equals("bannedPlayers")) { @@ -159,8 +172,7 @@ public class BanListPlugin extends Plugin /** * Event to keep making sure player names are highlighted red in clan chat, since the red name goes away frequently */ - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged) + private void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged) { if (client.getGameState() != GameState.LOGGED_IN || client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN) != null @@ -180,9 +192,7 @@ public class BanListPlugin extends Plugin }); } - - @Subscribe - public void onClanMemberJoined(ClanMemberJoined event) + private void onClanMemberJoined(ClanMemberJoined event) { ClanMember member = event.getMember(); String memberUsername = Text.standardize(member.getUsername().toLowerCase()); @@ -212,8 +222,7 @@ public class BanListPlugin extends Plugin /** * If a trade window is opened and the person trading us is on the list, modify "trading with" */ - @Subscribe - public void onWidgetLoaded(WidgetLoaded widgetLoaded) + private void onWidgetLoaded(WidgetLoaded widgetLoaded) { if (this.highlightInTrade && widgetLoaded.getGroupId() == TRADING_SCREEN) { //if trading window was loaded @@ -233,9 +242,7 @@ public class BanListPlugin extends Plugin } } - - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (client.getWidget(WidgetInfo.THEATRE_OF_BLOOD_RAIDING_PARTY) == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java index 0c39075df7..88b3e69e25 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/BarbarianAssaultPlugin.java @@ -82,7 +82,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; @@ -155,6 +155,9 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener @Inject private KeyManager keyManager; + @Inject + private EventBus eventBus; + @Getter private boolean inGame = false; @@ -306,6 +309,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); font = FontManager.getRunescapeFont().deriveFont(Font.BOLD, 24); torsoImage = itemManager.getImage(ItemID.FIGHTER_TORSO); @@ -323,6 +327,8 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(widgetsOverlay); overlayManager.remove(sceneOverlay); keyManager.unregisterKeyListener(this); @@ -343,6 +349,24 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener menu.clearHiddenMenus(); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ItemSpawned.class, this, this::onItemSpawned); + eventBus.subscribe(ItemDespawned.class, this, this::onItemDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(BeforeRender.class, this, this::onBeforeRender); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + @Override public void keyTyped(KeyEvent e) { @@ -376,8 +400,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { //not client thread be careful if (!configChanged.getGroup().equals("barbarianAssault")) @@ -487,8 +510,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener this.showEggCountOverlay = config.showEggCountOverlay(); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { switch (event.getGroupId()) { @@ -558,8 +580,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { if (!chatMessage.getType().equals(ChatMessageType.GAMEMESSAGE)) { @@ -578,6 +599,11 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } else if (isInGame()) { + if (scorecard != null) + { + scorecard.onChatMessage(chatMessage); + } + if (message.contains("exploded") && wave != null) { wave.setWrongEggs(wave.getWrongEggs() + 1); @@ -637,8 +663,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onItemSpawned(ItemSpawned itemSpawned) + private void onItemSpawned(ItemSpawned itemSpawned) { if (!isInGame()) { @@ -657,8 +682,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onItemDespawned(ItemDespawned itemDespawned) + private void onItemDespawned(ItemDespawned itemDespawned) { if (!isInGame()) { @@ -708,8 +732,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { // Keep in mind isInGame is delayed by a tick when a wave ends if (!isInGame() || getRole() == null) @@ -740,8 +763,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { if (!isInGame()) { @@ -763,8 +785,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (!isInGame()) { @@ -779,8 +800,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener // This was almost certainly a waste of time to get working, because almost nobody // actually uses the horn of glory. At least now there shouldn't be anyone complaining // about the horn of glory breaking anything and everything that should never break. - @Subscribe - public void onBeforeRender(BeforeRender event) + private void onBeforeRender(BeforeRender event) { if (!isInGame()) { @@ -953,8 +973,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener // onMenuEntryAdded is being used for conditional entry changes that are not // easily achievable using MenuManager, all other changes use MenuManager in // the BarbarianAssaultMenu/Menus classes - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!isInGame()) { @@ -1144,8 +1163,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener client.setMenuEntries(menu.toArray(new MenuEntry[0])); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (!isInGame() && getRole() != null) { @@ -1177,8 +1195,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } // Interacting changed has a slight delay until after the hitsplat is applied - @Subscribe - public void onInteractingChanged(InteractingChanged event) + private void onInteractingChanged(InteractingChanged event) { if (!isInGame() || getRole() != Role.HEALER) { @@ -1213,8 +1230,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } - @Subscribe - public void onProjectileSpawned(ProjectileSpawned event) + private void onProjectileSpawned(ProjectileSpawned event) { if (!isInGame()) { @@ -1234,8 +1250,7 @@ public class BarbarianAssaultPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { int newInGameBit = client.getVar(Varbits.IN_GAME_BA); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Scorecard.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Scorecard.java index df5b7423b4..2cc3e6a3b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Scorecard.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Scorecard.java @@ -33,7 +33,6 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ChatMessage; import net.runelite.client.chat.ChatMessageBuilder; -import net.runelite.client.eventbus.Subscribe; @Getter(AccessLevel.PACKAGE) @@ -65,7 +64,6 @@ public class Scorecard this.game = game; } - @Subscribe public void onChatMessage(ChatMessage chatMessage) { if (chatMessage.getMessage().startsWith("---- Points:") && game.getStage() == 1) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java index beeb0ba8cf..e630d08389 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java @@ -63,7 +63,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; @@ -141,6 +141,9 @@ public class BarrowsPlugin extends Plugin @Inject private BarrowsConfig config; + @Inject + private EventBus eventBus; + @Provides BarrowsConfig provideConfig(ConfigManager configManager) { @@ -164,6 +167,8 @@ public class BarrowsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + overlayManager.add(barrowsOverlay); overlayManager.add(brotherOverlay); } @@ -171,6 +176,8 @@ public class BarrowsPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(barrowsOverlay); overlayManager.remove(brotherOverlay); walls.clear(); @@ -193,8 +200,20 @@ public class BarrowsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(WallObjectChanged.class, this, this::onWallObjectChanged); + eventBus.subscribe(WallObjectDespawned.class, this, this::onWallObjectDespawned); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("barrows")) { @@ -218,8 +237,7 @@ public class BarrowsPlugin extends Plugin this.showPrayerDrainTimer = config.showPrayerDrainTimer(); } - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) + private void onWallObjectSpawned(WallObjectSpawned event) { WallObject wallObject = event.getWallObject(); if (BARROWS_WALLS.contains(wallObject.getId())) @@ -228,8 +246,7 @@ public class BarrowsPlugin extends Plugin } } - @Subscribe - public void onWallObjectChanged(WallObjectChanged event) + private void onWallObjectChanged(WallObjectChanged event) { WallObject previous = event.getPrevious(); WallObject wallObject = event.getWallObject(); @@ -241,15 +258,13 @@ public class BarrowsPlugin extends Plugin } } - @Subscribe - public void onWallObjectDespawned(WallObjectDespawned event) + private void onWallObjectDespawned(WallObjectDespawned event) { WallObject wallObject = event.getWallObject(); walls.remove(wallObject); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { GameObject gameObject = event.getGameObject(); if (BARROWS_LADDERS.contains(gameObject.getId())) @@ -258,8 +273,7 @@ public class BarrowsPlugin extends Plugin } } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { GameObject previous = event.getPrevious(); GameObject gameObject = event.getGameObject(); @@ -271,15 +285,13 @@ public class BarrowsPlugin extends Plugin } } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { GameObject gameObject = event.getGameObject(); ladders.remove(gameObject); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { @@ -303,8 +315,7 @@ public class BarrowsPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() == WidgetID.BARROWS_REWARD_GROUP_ID && this.showChestValue) { @@ -359,10 +370,12 @@ public class BarrowsPlugin extends Plugin final LoopTimer loopTimer = new LoopTimer( PRAYER_DRAIN_INTERVAL_MS, ChronoUnit.MILLIS, - spriteManager.getSprite(SpriteID.TAB_PRAYER, 0), + null, this, true); + spriteManager.getSpriteAsync(SpriteID.TAB_PRAYER, 0, loopTimer); + loopTimer.setPriority(InfoBoxPriority.MED); loopTimer.setTooltip("Prayer Drain"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java index f31100e59e..315ac06eec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blackjack/BlackjackPlugin.java @@ -38,7 +38,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -68,6 +68,8 @@ public class BlackjackPlugin extends Plugin private Client client; @Inject private BlackjackConfig config; + @Inject + private EventBus eventBus; private boolean pickpocketOnAggro; @@ -80,11 +82,25 @@ public class BlackjackPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.pickpocketOnAggro = config.pickpocketOnAggro(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("blackjack")) { @@ -92,8 +108,7 @@ public class BlackjackPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (client.getGameState() != GameState.LOGGED_IN || client.getVar(Varbits.QUEST_THE_FEUD) < 13 || @@ -114,8 +129,7 @@ public class BlackjackPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() == ChatMessageType.SPAM && event.getMessage().equals(SUCCESS_BLACKJACK) ^ (event.getMessage().equals(FAILED_BLACKJACK) && this.pickpocketOnAggro)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnacePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnacePlugin.java index c1afdb3bee..8978a013c9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnacePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnacePlugin.java @@ -46,7 +46,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -97,6 +97,9 @@ public class BlastFurnacePlugin extends Plugin @Inject private BlastFurnaceConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean showConveyorBelt; @Getter(AccessLevel.PACKAGE) @@ -106,6 +109,7 @@ public class BlastFurnacePlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(cofferOverlay); @@ -115,6 +119,8 @@ public class BlastFurnacePlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + infoBoxManager.removeIf(ForemanTimer.class::isInstance); overlayManager.remove(overlay); overlayManager.remove(cofferOverlay); @@ -124,14 +130,22 @@ public class BlastFurnacePlugin extends Plugin foremanTimer = null; } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + @Provides BlastFurnaceConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(BlastFurnaceConfig.class); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("blastfurnace")) { @@ -139,8 +153,7 @@ public class BlastFurnacePlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { GameObject gameObject = event.getGameObject(); @@ -156,8 +169,7 @@ public class BlastFurnacePlugin extends Plugin } } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { GameObject gameObject = event.getGameObject(); @@ -173,8 +185,7 @@ public class BlastFurnacePlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { @@ -183,8 +194,7 @@ public class BlastFurnacePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { Widget npcDialog = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); if (npcDialog == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java index 88d98cebbf..c4ec42e2dc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMinePlugin.java @@ -42,7 +42,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -73,6 +73,9 @@ public class BlastMinePlugin extends Plugin @Inject private BlastMinePluginConfig config; + @Inject + private EventBus eventBus; + @Provides BlastMinePluginConfig getConfig(ConfigManager configManager) { @@ -96,6 +99,7 @@ public class BlastMinePlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(blastMineRockOverlay); overlayManager.add(blastMineOreCountOverlay); @@ -104,6 +108,8 @@ public class BlastMinePlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(blastMineRockOverlay); overlayManager.remove(blastMineOreCountOverlay); final Widget blastMineWidget = client.getWidget(WidgetInfo.BLAST_MINE); @@ -114,8 +120,14 @@ public class BlastMinePlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void addSubscriptions() + { + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameObjectSpawned(GameObjectSpawned event) { final GameObject gameObject = event.getGameObject(); BlastMineRockType blastMineRockType = BlastMineRockType.getRockType(gameObject.getId()); @@ -133,8 +145,7 @@ public class BlastMinePlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { @@ -142,8 +153,7 @@ public class BlastMinePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { if (rocks.isEmpty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java index 4140df8426..04f6c5d71c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.SkillIconManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -98,6 +98,8 @@ public class BoostsPlugin extends Plugin private SkillIconManager skillIconManager; @Inject private CombatIconsOverlay combatIconsOverlay; + @Inject + private EventBus eventBus; private boolean isChangedDown = false; private boolean isChangedUp = false; @@ -133,6 +135,7 @@ public class BoostsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(boostsOverlay); overlayManager.add(combatIconsOverlay); @@ -156,6 +159,7 @@ public class BoostsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.remove(boostsOverlay); overlayManager.remove(combatIconsOverlay); infoBoxManager.removeIf(t -> t instanceof BoostIndicator || t instanceof StatChangeIndicator); @@ -166,8 +170,15 @@ public class BoostsPlugin extends Plugin isChangedDown = false; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(BoostedLevelChanged.class, this, this::onBoostedLevelChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -179,8 +190,7 @@ public class BoostsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("boosts")) { @@ -201,8 +211,7 @@ public class BoostsPlugin extends Plugin } } - @Subscribe - public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged) + private void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged) { Skill skill = boostedLevelChanged.getSkill(); @@ -251,8 +260,7 @@ public class BoostsPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { lastTickMillis = System.currentTimeMillis(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/BossTimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/BossTimersPlugin.java index d5faf547dc..1fd643cb84 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/BossTimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/BossTimersPlugin.java @@ -30,7 +30,7 @@ import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.NPC; import net.runelite.api.events.NpcDespawned; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -51,14 +51,23 @@ public class BossTimersPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + } + @Override protected void shutDown() throws Exception { + eventBus.unregister(this); infoBoxManager.removeIf(t -> t instanceof RespawnTimer); } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { NPC npc = npcDespawned.getNpc(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java index 2c6c68ecb3..1a017ba004 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java @@ -56,7 +56,7 @@ import net.runelite.api.events.ProjectileMoved; import net.runelite.client.Notifier; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -123,6 +123,9 @@ public class CannonPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventbus; + private boolean lock; private boolean showEmptyCannonNotification; @@ -146,6 +149,7 @@ public class CannonPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(cannonOverlay); overlayManager.add(cannonSpotOverlay); @@ -155,6 +159,8 @@ public class CannonPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventbus.unregister(this); + cannonSpotOverlay.setHidden(true); overlayManager.remove(cannonOverlay); overlayManager.remove(cannonSpotOverlay); @@ -167,8 +173,17 @@ public class CannonPlugin extends Plugin spotPoints.clear(); } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void addSubscriptions() + { + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventbus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventbus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventbus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventbus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY)) { @@ -178,8 +193,7 @@ public class CannonPlugin extends Plugin cannonSpotOverlay.setHidden(!ItemUtil.containsAllItemIds(event.getItemContainer().getItems(), CANNON_PARTS)); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("cannon")) { @@ -223,8 +237,7 @@ public class CannonPlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { GameObject gameObject = event.getGameObject(); @@ -238,8 +251,7 @@ public class CannonPlugin extends Plugin } } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void onProjectileMoved(ProjectileMoved event) { Projectile projectile = event.getProjectile(); @@ -261,8 +273,7 @@ public class CannonPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.SPAM && event.getType() != ChatMessageType.GAMEMESSAGE) { @@ -345,8 +356,7 @@ public class CannonPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { skipProjectileCheckThisTick = false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java index 47f1adbec4..073616f72f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusPlugin.java @@ -37,7 +37,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -59,21 +59,34 @@ public class CerberusPlugin extends Plugin @Inject private CerberusOverlay overlay; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { overlayManager.add(overlay); + addSubscriptions(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); ghosts.clear(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged event) { GameState gameState = event.getGameState(); if (gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING || gameState == GameState.CONNECTION_LOST) @@ -82,21 +95,18 @@ public class CerberusPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(final NpcSpawned event) + private void onNpcSpawned(final NpcSpawned event) { final NPC npc = event.getNpc(); CerberusGhost.fromNPC(npc).ifPresent(ghost -> ghosts.add(npc)); } - @Subscribe - public void onNpcDespawned(final NpcDespawned event) + private void onNpcDespawned(final NpcDespawned event) { ghosts.remove(event.getNpc()); } - @Subscribe - public void onGameTick(GameTick gameTick) + void onGameTick(GameTick gameTick) { if (ghosts.isEmpty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatboxperformance/ChatboxPerformancePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatboxperformance/ChatboxPerformancePlugin.java index 3f51018632..2f274c5c6f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatboxperformance/ChatboxPerformancePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatboxperformance/ChatboxPerformancePlugin.java @@ -33,7 +33,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetSizeMode; import net.runelite.api.widgets.WidgetType; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -47,8 +47,22 @@ public class ChatboxPerformancePlugin extends Plugin @Inject private Client client; - @Subscribe - public void onWidgetPositioned(WidgetPositioned event) + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(WidgetPositioned.class, this, this::onWidgetPositioned); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void onWidgetPositioned(WidgetPositioned event) { if (!areWidgetsFixed()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 951547e777..a17596f99c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -56,7 +56,7 @@ import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.ChatInput; import net.runelite.client.game.ItemManager; import net.runelite.client.input.KeyManager; @@ -140,9 +140,14 @@ public class ChatCommandsPlugin extends Plugin @Inject private ChatKeyboardListener chatKeyboardListener; + @Inject + private EventBus eventBus; + @Override public void startUp() { + addSubscriptions(); + keyManager.registerKeyListener(chatKeyboardListener); chatCommandManager.registerCommandAsync(TOTAL_LEVEL_COMMAND_STRING, this::playerSkillLookup); @@ -160,6 +165,8 @@ public class ChatCommandsPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + lastBossKill = null; keyManager.unregisterKeyListener(chatKeyboardListener); @@ -176,6 +183,14 @@ public class ChatCommandsPlugin extends Plugin chatCommandManager.unregisterCommand(DUEL_ARENA_COMMAND); } + private void addSubscriptions() + { + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + @Provides ChatCommandsConfig provideConfig(ConfigManager configManager) { @@ -208,8 +223,7 @@ public class ChatCommandsPlugin extends Plugin return personalBest == null ? 0 : personalBest; } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + void onChatMessage(ChatMessage chatMessage) { if (chatMessage.getType() != ChatMessageType.TRADE && chatMessage.getType() != ChatMessageType.GAMEMESSAGE @@ -324,8 +338,7 @@ public class ChatCommandsPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (!logKills) { @@ -361,8 +374,7 @@ public class ChatCommandsPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded widget) + private void onWidgetLoaded(WidgetLoaded widget) { // don't load kc if in an instance, if the player is in another players poh // and reading their boss log @@ -374,8 +386,7 @@ public class ChatCommandsPlugin extends Plugin logKills = true; } - @Subscribe - public void onVarbitChanged(VarbitChanged varbitChanged) + private void onVarbitChanged(VarbitChanged varbitChanged) { hiscoreEndpoint = getLocalHiscoreEndpointType(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java index 8a24ade869..9dfd7d428c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.OverheadTextChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.Text; @@ -75,6 +75,9 @@ public class ChatFilterPlugin extends Plugin @Inject private ChatFilterConfig config; + @Inject + private EventBus eventBus; + @Setter(AccessLevel.PACKAGE) private ChatFilterType filterType; @Setter(AccessLevel.PACKAGE) @@ -96,6 +99,8 @@ public class ChatFilterPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + updateFilteredPatterns(); client.refreshChat(); } @@ -103,12 +108,20 @@ public class ChatFilterPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + filteredPatterns.clear(); client.refreshChat(); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(OverheadTextChanged.class, this, this::onOverheadTextChanged); + } + + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!"chatFilterCheck".equals(event.getEventName())) { @@ -171,10 +184,9 @@ public class ChatFilterPlugin extends Plugin } } - @Subscribe - public void onOverheadTextChanged(OverheadTextChanged event) + private void onOverheadTextChanged(OverheadTextChanged event) { - if (!(event.getActor() instanceof Player) || !shouldFilterPlayerMessage(event.getActor().getName())) + if (!(event.getActor() instanceof Player) || event.getActor().getName() == null || !shouldFilterPlayerMessage(event.getActor().getName())) { return; } @@ -254,8 +266,7 @@ public class ChatFilterPlugin extends Plugin .forEach(filteredPatterns::add); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"chatfilter".equals(event.getGroup())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java index 6b63e2c1d2..01f0ea8e1f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chathistory/ChatHistoryPlugin.java @@ -46,7 +46,7 @@ import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; @@ -85,6 +85,9 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + private boolean retainChatHistory; private boolean pmTargetCycling; @@ -98,6 +101,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener protected void startUp() { updateConfig(); + addSubscriptions(); messageQueue = EvictingQueue.create(100); friends = new ArrayDeque<>(FRIENDS_MAX_SIZE + 1); @@ -107,6 +111,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener @Override protected void shutDown() { + eventBus.unregister(this); + messageQueue.clear(); messageQueue = null; friends.clear(); @@ -114,8 +120,14 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener keyManager.unregisterKeyListener(this); } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + } + + private void onChatMessage(ChatMessage chatMessage) { // Start sending old messages right after the welcome message, as that is most reliable source // of information that chat history was reset @@ -159,8 +171,8 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener .type(chatMessage.getType()) .name(chatMessage.getName()) .sender(chatMessage.getSender()) - .value(nbsp(chatMessage.getMessage())) - .runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage())) + .value(tweakSpaces(chatMessage.getMessage())) + .runeLiteFormattedMessage(tweakSpaces(chatMessage.getMessageNode().getRuneLiteFormatMessage())) .timestamp(chatMessage.getTimestamp()) .build(); @@ -171,8 +183,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { String menuOption = event.getOption(); @@ -192,16 +203,18 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener } /** - * Small hack to prevent plugins checking for specific messages to match + * Small hack to prevent plugins checking for specific messages to match. This works because the "—" character + * cannot be seen in-game. This replacement preserves wrapping on chat history messages. * * @param message message - * @return message with nbsp + * @return message with invisible character before every space */ - private static String nbsp(final String message) + private static String tweakSpaces(final String message) { if (message != null) { - return message.replace(' ', '\u00A0'); + // First replacement cleans up prior applications of this so as not to keep extending the message + return message.replace("— ", " ").replace(" ", "— "); } return null; @@ -267,8 +280,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener return friends.getLast(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"chathistory".equals(event.getGroup())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java index 00b7cc80d4..178c441245 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPlugin.java @@ -47,7 +47,7 @@ import net.runelite.client.RuneLiteProperties; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.Text; @@ -76,6 +76,9 @@ public class ChatNotificationsPlugin extends Plugin @Inject private RuneLiteProperties runeLiteProperties; + @Inject + private EventBus eventBus; + //Custom Highlights private Pattern usernameMatcher = null; private String usernameReplacer = ""; @@ -102,17 +105,27 @@ public class ChatNotificationsPlugin extends Plugin public void startUp() { updateConfig(); + addSubscriptions(); + updateHighlights(); } @Override public void shutDown() { + eventBus.unregister(this); + this.privateMessageHashes.clear(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -123,8 +136,7 @@ public class ChatNotificationsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("chatnotification")) { @@ -150,8 +162,7 @@ public class ChatNotificationsPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + void onChatMessage(ChatMessage chatMessage) { MessageNode messageNode = chatMessage.getMessageNode(); boolean update = false; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java index 7cc488dbd7..8159aae561 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java @@ -26,7 +26,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.menus.MenuManager; @@ -74,6 +74,9 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener @Inject private ChatTranslationConfig config; + @Inject + private EventBus eventBus; + private boolean translateOptionVisable; private boolean publicChat; private String getPlayerNames; @@ -91,6 +94,7 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); if (client != null && this.translateOptionVisable) { @@ -104,6 +108,7 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener @Override protected void shutDown() throws Exception { + eventBus.unregister(this); if (client != null && this.translateOptionVisable) { menuManager.get().removePlayerMenuItem(TRANSLATE); @@ -113,8 +118,15 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener playerNames.clear(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(PlayerMenuOptionClicked.class, this, this::onPlayerMenuOptionClicked); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("chattranslation")) { @@ -132,8 +144,7 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!this.translateOptionVisable) { @@ -165,8 +176,7 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + private void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { if (event.getMenuOption().equals(TRANSLATE)) { @@ -181,8 +191,7 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java index ecbb2e1d63..c1da955f6a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java @@ -70,7 +70,7 @@ import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ClanManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; @@ -114,6 +114,9 @@ public class ClanChatPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + private List chats = new ArrayList<>(); public static CopyOnWriteArrayList getClanMembers() @@ -151,19 +154,37 @@ public class ClanChatPlugin extends Plugin public void startUp() { updateConfig(); + addSubscriptions(); + chats = new ArrayList<>(Text.fromCSV(this.chatsData)); } @Override public void shutDown() { + eventBus.unregister(this); + clanMembers.clear(); removeClanCounter(); resetClanChats(); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ClanMemberJoined.class, this, this::onClanMemberJoined); + eventBus.subscribe(ClanMemberLeft.class, this, this::onClanMemberLeft); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(VarClientStrChanged.class, this, this::onVarClientStrChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + eventBus.subscribe(ClanChanged.class, this, this::onClanChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getGroup().equals("clanchat")) { @@ -185,8 +206,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onClanMemberJoined(ClanMemberJoined event) + private void onClanMemberJoined(ClanMemberJoined event) { final ClanMember member = event.getMember(); @@ -231,8 +251,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onClanMemberLeft(ClanMemberLeft event) + private void onClanMemberLeft(ClanMemberLeft event) { final ClanMember member = event.getMember(); @@ -275,8 +294,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -414,8 +432,7 @@ public class ClanChatPlugin extends Plugin clanJoinMessages.addLast(clanJoinMessage); } - @Subscribe - public void onVarClientStrChanged(VarClientStrChanged strChanged) + private void onVarClientStrChanged(VarClientStrChanged strChanged) { if (strChanged.getIndex() == VarClientStr.RECENT_CLAN_CHAT.getIndex() && this.recentChats) { @@ -423,8 +440,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN) { @@ -465,8 +481,7 @@ public class ClanChatPlugin extends Plugin insertClanRankIcon(chatMessage); } - @Subscribe - public void onGameStateChanged(GameStateChanged state) + private void onGameStateChanged(GameStateChanged state) { GameState gameState = state.getGameState(); @@ -479,8 +494,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onPlayerSpawned(PlayerSpawned event) + private void onPlayerSpawned(PlayerSpawned event) { final Player local = client.getLocalPlayer(); final Player player = event.getPlayer(); @@ -492,8 +506,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onPlayerDespawned(PlayerDespawned event) + private void onPlayerDespawned(PlayerDespawned event) { if (clanMembers.remove(event.getPlayer()) && clanMembers.isEmpty()) { @@ -501,8 +514,7 @@ public class ClanChatPlugin extends Plugin } } - @Subscribe - public void onClanChanged(ClanChanged event) + private void onClanChanged(ClanChanged event) { if (event.isJoined()) { @@ -517,8 +529,7 @@ public class ClanChatPlugin extends Plugin activityBuffer.clear(); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) + private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) { if (!scriptCallbackEvent.getEventName().equalsIgnoreCase("clanchatInput")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java index 5313fec5f8..3b26cf862a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanmanmode/ClanManModePlugin.java @@ -18,7 +18,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -52,6 +52,9 @@ public class ClanManModePlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean highlightAttackable; @Getter(AccessLevel.PACKAGE) @@ -100,6 +103,7 @@ public class ClanManModePlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(ClanManModeOverlay); overlayManager.add(ClanManModeTileOverlay); @@ -109,6 +113,8 @@ public class ClanManModePlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(ClanManModeOverlay); overlayManager.remove(ClanManModeTileOverlay); overlayManager.remove(ClanManModeMinimapOverlay); @@ -120,7 +126,13 @@ public class ClanManModePlugin extends Plugin inwildy = 0; } - @Subscribe + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + private void onConfigChanged(ConfigChanged event) { if (!"clanmanmode".equals(event.getGroup())) @@ -131,8 +143,7 @@ public class ClanManModePlugin extends Plugin updateConfig(); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) { @@ -140,8 +151,7 @@ public class ClanManModePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { ticks++; final Player localPlayer = client.getLocalPlayer(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java index bc0c3d6526..fb28516576 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java @@ -72,7 +72,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -158,6 +158,9 @@ public class ClueScrollPlugin extends Plugin @Inject private WorldMapPointManager worldMapPointManager; + @Inject + private EventBus eventBus; + private BufferedImage emoteImage; private BufferedImage mapArrow; private Integer clueItemId; @@ -182,6 +185,8 @@ public class ClueScrollPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.displayHintArrows = config.displayHintArrows(); overlayManager.add(clueScrollOverlay); overlayManager.add(clueScrollEmoteOverlay); @@ -192,6 +197,8 @@ public class ClueScrollPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(clueScrollOverlay); overlayManager.remove(clueScrollEmoteOverlay); overlayManager.remove(clueScrollWorldOverlay); @@ -202,8 +209,20 @@ public class ClueScrollPlugin extends Plugin resetClue(true); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM) { @@ -224,8 +243,7 @@ public class ClueScrollPlugin extends Plugin resetClue(true); } - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) + private void onMenuOptionClicked(final MenuOptionClicked event) { if ("read".equalsIgnoreCase(event.getOption())) { @@ -239,8 +257,7 @@ public class ClueScrollPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(final ItemContainerChanged event) + private void onItemContainerChanged(final ItemContainerChanged event) { if (event.getItemContainer() == client.getItemContainer(InventoryID.EQUIPMENT)) { @@ -280,15 +297,13 @@ public class ClueScrollPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(final NpcSpawned event) + private void onNpcSpawned(final NpcSpawned event) { final NPC npc = event.getNpc(); checkClueNPCs(clue, npc); } - @Subscribe - public void onNpcDespawned(final NpcDespawned event) + private void onNpcDespawned(final NpcDespawned event) { final boolean removed = npcsToMark.remove(event.getNpc()); @@ -306,8 +321,7 @@ public class ClueScrollPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("cluescroll")) { @@ -319,8 +333,7 @@ public class ClueScrollPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(final GameStateChanged event) + private void onGameStateChanged(final GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN) { @@ -328,8 +341,7 @@ public class ClueScrollPlugin extends Plugin } } - @Subscribe - public void onGameTick(final GameTick event) + private void onGameTick(final GameTick event) { objectsToMark.clear(); @@ -392,8 +404,7 @@ public class ClueScrollPlugin extends Plugin updateClue(findClueScroll()); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() < WidgetID.BEGINNER_CLUE_MAP_CHAMPIONS_GUILD || event.getGroupId() > WidgetID.BEGINNER_CLUE_MAP_WIZARDS_TOWER) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java index ec7334ca2b..2fb7891866 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java @@ -96,7 +96,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati .put(new WorldPoint(2542, 3031, 0), "Gu'Tanoth.") .put(new WorldPoint(2581, 3030, 0), "Gu'Tanoth island, enter cave north-west of Feldip Hills (AKS).") .put(new WorldPoint(2961, 3024, 0), "Ship yard (DKP).") - .put(new WorldPoint(2339, 3311, 0), "East of Tirannwn on Arandar mountain pass.") + .put(new WorldPoint(2339, 3311, 0), "East of Prifddinas on Arandar mountain pass.") .put(new WorldPoint(3440, 3341, 0), "Nature Spirit's grotto.") .put(new WorldPoint(2763, 2974, 0), "Cairn Isle, west of Shilo Village.") .put(new WorldPoint(3138, 2969, 0), "West of Bandit Camp.") diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index dbd1bc413a..d94275dcdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -204,7 +204,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Search the drawers upstairs in Falador's shield shop.", DRAWERS, new WorldPoint(2971, 3386, 1), "Cassie's Shield Shop at the northern Falador entrance."), new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350 , new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."), new CrypticClue("Dig near some giant mushrooms, behind the Grand Tree.", new WorldPoint(2458, 3504, 0), "Dig near the red mushrooms northwest of the Grand Tree."), - new CrypticClue("Pentagrams and demons, burnt bones and remains, I wonder what the blood contains.", new WorldPoint(3297, 3890, 0), "Dig under the blood rune spawn next the the Demonic Ruins."), + new CrypticClue("Pentagrams and demons, burnt bones and remains, I wonder what the blood contains.", new WorldPoint(3297, 3890, 0), "Dig under the blood rune spawn next to the Demonic Ruins."), new CrypticClue("Search the drawers above Varrock's shops.", DRAWERS_7194, new WorldPoint(3206, 3419, 1), "Located upstairs in Thessalia's Fine Clothes shop in Varrock."), new CrypticClue("Search the drawers in one of Gertrude's bedrooms.", DRAWERS_7194, new WorldPoint(3156, 3406, 0), "Kanel's bedroom (southeastern room), outside of west Varrock."), new CrypticClue("Under a giant robotic bird that cannot fly.", new WorldPoint(1756, 4940, 0), "Dig next to the terrorbird display in the south exhibit of Varrock Museum's basement."), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index ae18259fb4..1cfb81246a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -62,14 +62,17 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat private static final int HOT_COLD_PANEL_WIDTH = 200; private static final HotColdClue BEGINNER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Reldo may have a clue.", "Reldo", - "Speak to Reldo to receive a strange device."); + "Speak to Reldo to receive a strange device.", + new WorldPoint(3211, 3494, 0)); private static final HotColdClue MASTER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", "Jorral", - "Speak to Jorral to receive a strange device."); + "Speak to Jorral to receive a strange device.", + new WorldPoint(2436, 3347, 0)); private final String text; private final String npc; private final String solution; + private final WorldPoint npcLocation; @Nullable private HotColdSolver hotColdSolver; private WorldPoint location; @@ -90,11 +93,12 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return null; } - private HotColdClue(String text, String npc, String solution) + private HotColdClue(String text, String npc, String solution, WorldPoint npcLocation) { this.text = text; this.npc = npc; this.solution = solution; + this.npcLocation = npcLocation; setRequiresSpade(true); initializeSolver(); } @@ -107,7 +111,14 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return new WorldPoint[0]; } - return hotColdSolver.getPossibleLocations().stream().map(HotColdLocation::getWorldPoint).toArray(WorldPoint[]::new); + if (hotColdSolver.getLastWorldPoint() == null) + { + return new WorldPoint[] {npcLocation}; + } + else + { + return hotColdSolver.getPossibleLocations().stream().map(HotColdLocation::getWorldPoint).toArray(WorldPoint[]::new); + } } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/STASHUnit.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/STASHUnit.java index 8e196c421c..bf66bcefb1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/STASHUnit.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/STASHUnit.java @@ -103,7 +103,7 @@ public enum STASHUnit ENTRANCE_OF_THE_CAVE_OF_DAMIS(NullObjectID.NULL_29027, new WorldPoint(2629, 5070, 0)), WARRIORS_GUILD_BANK(NullObjectID.NULL_29028, new WorldPoint(2844, 3537, 0)), SOUTHEAST_CORNER_OF_THE_MONASTERY(NullObjectID.NULL_29029, new WorldPoint(3056, 3482, 0)), - SOUTHEAST_CORNER_OF_THE_FISHING_PLATFORM(NullObjectID.NULL_29030, new WorldPoint(2787, 3277, 1)), + SOUTHEAST_CORNER_OF_THE_FISHING_PLATFORM(NullObjectID.NULL_29030, new WorldPoint(2787, 3277, 0)), OUTSIDE_THE_SLAYER_TOWER_GARGOYLE_ROOM(NullObjectID.NULL_29031, new WorldPoint(3423, 3534, 2)), ON_TOP_OF_TROLLHEIM_MOUNTAIN(NullObjectID.NULL_29032, new WorldPoint(2886, 3676, 0)), FOUNTAIN_OF_HEROES(NullObjectID.NULL_29033, new WorldPoint(2916, 9891, 0)), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java index 1e0079ebd6..b5134f4b9b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatcounter/CombatCounter.java @@ -56,7 +56,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.HitsplatApplied; import net.runelite.api.kit.KitType; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -89,6 +89,9 @@ public class CombatCounter extends Plugin @Inject private CombatCounterConfig config; + @Inject + private EventBus eventBus; + private boolean instanced = false; @Setter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE) @@ -236,6 +239,7 @@ public class CombatCounter extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(tickOverlay); overlayManager.add(damageOverlay); @@ -249,6 +253,8 @@ public class CombatCounter extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(tickOverlay); overlayManager.remove(damageOverlay); @@ -258,8 +264,15 @@ public class CombatCounter extends Plugin this.playerDamage.clear(); } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + } + + private void onAnimationChanged(AnimationChanged event) { Actor actor = event.getActor(); @@ -403,8 +416,7 @@ public class CombatCounter extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (this.resetOnNewInstance) { @@ -554,9 +566,7 @@ public class CombatCounter extends Plugin } } - - @Subscribe - public void onHitsplatApplied(HitsplatApplied event) + private void onHitsplatApplied(HitsplatApplied event) { Actor actor = event.getActor(); @@ -644,8 +654,7 @@ public class CombatCounter extends Plugin return 2 + (int) Math.floor((3d + distance) / 6d); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("combatcounter")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java index 575f59af6f..ae703b6066 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -84,6 +84,9 @@ public class CombatLevelPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean showLevelsUntil; private boolean wildernessAttackLevelRange; @@ -98,6 +101,7 @@ public class CombatLevelPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); @@ -110,6 +114,8 @@ public class CombatLevelPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); Widget combatLevelWidget = client.getWidget(WidgetInfo.COMBAT_LEVEL); @@ -126,8 +132,14 @@ public class CombatLevelPlugin extends Plugin shutDownAttackLevelRange(); } - @Subscribe - public void onGameTick(GameTick event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onGameTick(GameTick event) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -153,8 +165,7 @@ public class CombatLevelPlugin extends Plugin combatLevelWidget.setText("Combat Lvl: " + DECIMAL_FORMAT.format(combatLevelPrecise)); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!CONFIG_GROUP.equals(event.getGroup()) || !ATTACK_RANGE_CONFIG_KEY.equals(event.getKey())) { @@ -173,8 +184,7 @@ public class CombatLevelPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (this.wildernessAttackLevelRange && "wildernessWidgetTextSet".equals(event.getEventName())) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 8a8692b947..0273fb6044 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -30,17 +30,15 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Insets; import java.awt.Rectangle; -import java.awt.Font; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -108,6 +106,7 @@ import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.ComboBoxListRenderer; import net.runelite.client.ui.components.IconButton; import net.runelite.client.ui.components.IconTextField; +import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import net.runelite.client.ui.components.colorpicker.RuneliteColorPicker; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; @@ -136,6 +135,7 @@ public class ConfigPanel extends PluginPanel private final RuneLiteConfig runeLiteConfig; private final RuneLitePlusConfig runeLitePlusConfig; private final ChatColorConfig chatColorConfig; + private final ColorPickerManager colorPickerManager; public static List pluginList = new ArrayList<>(); private final IconTextField searchBar = new IconTextField(); @@ -154,7 +154,8 @@ public class ConfigPanel extends PluginPanel } ConfigPanel(PluginManager pluginManager, ConfigManager configManager, ScheduledExecutorService executorService, - RuneLiteConfig runeLiteConfig, RuneLitePlusConfig runeLitePlusConfig, ChatColorConfig chatColorConfig) + RuneLiteConfig runeLiteConfig, RuneLitePlusConfig runeLitePlusConfig, ChatColorConfig chatColorConfig, + ColorPickerManager colorPickerManager) { super(false); this.pluginManager = pluginManager; @@ -163,6 +164,7 @@ public class ConfigPanel extends PluginPanel this.runeLiteConfig = runeLiteConfig; this.runeLitePlusConfig = runeLitePlusConfig; this.chatColorConfig = chatColorConfig; + this.colorPickerManager = colorPickerManager; searchBar.setIcon(IconTextField.Icon.SEARCH); searchBar.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH - 20, 30)); @@ -250,7 +252,7 @@ public class ConfigPanel extends PluginPanel } lines.add(sb.toString()); - return new Dimension(WIDTH, (lines.size() * fontMetrics.getHeight()) + HEIGHT_PADDING); + return new Dimension(WIDTH, (lines.size() * fontMetrics.getHeight()) + HEIGHT_PADDING); } } @@ -910,8 +912,11 @@ public class ConfigPanel extends PluginPanel @Override public void mouseClicked(MouseEvent e) { - RuneliteColorPicker colorPicker = new RuneliteColorPicker(SwingUtilities.windowForComponent(ConfigPanel.this), - colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null); + RuneliteColorPicker colorPicker = colorPickerManager.create( + SwingUtilities.windowForComponent(ConfigPanel.this), + colorPickerBtn.getBackground(), + cid.getItem().name(), + cid.getAlpha() == null); colorPicker.setLocation(getLocationOnScreen()); colorPicker.setOnColorChange(c -> { @@ -919,14 +924,7 @@ public class ConfigPanel extends PluginPanel colorPickerBtn.setText(ColorUtil.toHexColor(c).toUpperCase()); }); - colorPicker.addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent e) - { - changeConfiguration(listItem, config, colorPicker, cd, cid); - } - }); + colorPicker.setOnClose(c -> changeConfiguration(listItem, config, colorPicker, cd, cid)); colorPicker.setVisible(true); } }); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java index 7df1fbd6cb..16cb909628 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java @@ -37,7 +37,7 @@ import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLitePlusConfig; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PluginChanged; import net.runelite.client.plugins.Plugin; @@ -46,6 +46,7 @@ import net.runelite.client.plugins.PluginManager; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.util.ImageUtil; @@ -80,13 +81,21 @@ public class ConfigPlugin extends Plugin @Inject private ChatColorConfig chatColorConfig; + @Inject + private ColorPickerManager colorPickerManager; + + @Inject + private EventBus eventBus; + private ConfigPanel configPanel; private NavigationButton navButton; @Override protected void startUp() throws Exception { - configPanel = new ConfigPanel(pluginManager, configManager, executorService, runeLiteConfig, runeLitePlusConfig, chatColorConfig); + addSubscriptions(); + + configPanel = new ConfigPanel(pluginManager, configManager, executorService, runeLiteConfig, runeLitePlusConfig, chatColorConfig, colorPickerManager); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "config_icon.png"); @@ -103,6 +112,8 @@ public class ConfigPlugin extends Plugin @Override public void shutDown() throws Exception { + eventBus.unregister(this); + clientToolbar.removeNavigation(navButton); RuneLite.getInjector().getInstance(ClientThread.class).invokeLater(() -> { @@ -122,14 +133,18 @@ public class ConfigPlugin extends Plugin }); } - @Subscribe - public void onPluginChanged(PluginChanged event) + private void addSubscriptions() + { + eventBus.subscribe(PluginChanged.class, this, this::onPluginChanged); + eventBus.subscribe(OverlayMenuClicked.class, this, this::onOverlayMenuClicked); + } + + private void onPluginChanged(PluginChanged event) { SwingUtilities.invokeLater(configPanel::refreshPluginList); } - @Subscribe - public void onOverlayMenuClicked(OverlayMenuClicked overlayMenuClicked) + private void onOverlayMenuClicked(OverlayMenuClicked overlayMenuClicked) { OverlayMenuEntry overlayMenuEntry = overlayMenuClicked.getEntry(); if (overlayMenuEntry.getMenuAction() == MenuAction.RUNELITE_OVERLAY_CONFIG) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java index 96be647e3f..6ab9ecf5ee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/CookingPlugin.java @@ -44,7 +44,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.SpotAnimationChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; @@ -80,6 +80,9 @@ public class CookingPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private CookingSession session; @@ -97,6 +100,8 @@ public class CookingPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + session = null; overlayManager.add(overlay); } @@ -104,13 +109,22 @@ public class CookingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + infoBoxManager.removeIf(FermentTimer.class::isInstance); overlayManager.remove(overlay); session = null; } - @Subscribe - public void onGameTick(GameTick gameTick) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onGameTick(GameTick gameTick) { if (session == null || this.statTimeout == 0) { @@ -126,8 +140,7 @@ public class CookingPlugin extends Plugin } } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged graphicChanged) + void onSpotAnimationChanged(SpotAnimationChanged graphicChanged) { Player player = client.getLocalPlayer(); @@ -156,8 +169,7 @@ public class CookingPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.SPAM) { @@ -194,8 +206,7 @@ public class CookingPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getGroup().equals("cooking")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java index 36ef995fa8..bede4b7236 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cooking/FermentTimer.java @@ -25,7 +25,7 @@ package net.runelite.client.plugins.cooking; import java.awt.Color; -import java.awt.Image; +import java.awt.image.BufferedImage; import java.time.Duration; import java.time.Instant; import javax.inject.Singleton; @@ -39,7 +39,7 @@ final class FermentTimer extends InfoBox private Instant fermentTime; - FermentTimer(Image image, Plugin plugin) + FermentTimer(BufferedImage image, Plugin plugin) { super(image, plugin); reset(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpPlugin.java index 06bbe2701c..526105012a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpPlugin.java @@ -53,7 +53,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -102,6 +102,9 @@ public class CorpPlugin extends Plugin @Inject private CorpConfig config; + @Inject + private EventBus eventBus; + private boolean leftClickCore; @Getter(AccessLevel.PACKAGE) private boolean showDamage; @@ -116,6 +119,7 @@ public class CorpPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(corpOverlay); overlayManager.add(coreOverlay); @@ -124,6 +128,8 @@ public class CorpPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(corpOverlay); overlayManager.remove(coreOverlay); @@ -133,8 +139,18 @@ public class CorpPlugin extends Plugin players.clear(); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOADING) { @@ -142,8 +158,7 @@ public class CorpPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) + private void onNpcSpawned(NpcSpawned npcSpawned) { NPC npc = npcSpawned.getNpc(); @@ -162,8 +177,7 @@ public class CorpPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { NPC npc = npcDespawned.getNpc(); @@ -199,8 +213,7 @@ public class CorpPlugin extends Plugin } } - @Subscribe - public void onHitsplatApplied(HitsplatApplied hitsplatApplied) + private void onHitsplatApplied(HitsplatApplied hitsplatApplied) { Actor actor = hitsplatApplied.getActor(); @@ -218,8 +231,7 @@ public class CorpPlugin extends Plugin totalDamage += hitsplatApplied.getHitsplat().getAmount(); } - @Subscribe - public void onInteractingChanged(InteractingChanged interactingChanged) + private void onInteractingChanged(InteractingChanged interactingChanged) { Actor source = interactingChanged.getSource(); Actor target = interactingChanged.getTarget(); @@ -232,8 +244,7 @@ public class CorpPlugin extends Plugin players.add(source); } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) + private void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) { if (menuEntryAdded.getType() != NPC_SECTION_ACTION || !this.leftClickCore || !menuEntryAdded.getOption().equals(ATTACK)) @@ -256,8 +267,7 @@ public class CorpPlugin extends Plugin client.setMenuEntries(menuEntries); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getGroup().equals("corp")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java index e69be13521..7c2e3e83e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxInfoBox.java @@ -28,7 +28,6 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.inject.Inject; @@ -87,7 +86,7 @@ public class CoxInfoBox extends Overlay if (System.currentTimeMillis() < (plugin.getLastPrayTime() + 120000) && plugin.getPrayAgainstOlm() != null) { InfoBoxComponent prayComponent = new InfoBoxComponent(); - Image prayImg = scaleImg(getPrayerImage(plugin.prayAgainstOlm)); + BufferedImage prayImg = scaleImg(getPrayerImage(plugin.prayAgainstOlm)); prayComponent.setImage(prayImg); prayComponent.setColor(Color.WHITE); prayComponent.setBackgroundColor(client.isPrayerActive(prayAgainst.getPrayer()) @@ -160,7 +159,7 @@ public class CoxInfoBox extends Overlay return null; } - private Image scaleImg(final Image img) + private BufferedImage scaleImg(final BufferedImage img) { if (img == null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java index 9dc12d080f..bde7448e3a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/coxhelper/CoxPlugin.java @@ -63,7 +63,7 @@ import net.runelite.api.events.ProjectileMoved; import net.runelite.api.events.SpotAnimationChanged; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -105,6 +105,8 @@ public class CoxPlugin extends Plugin private CoxConfig config; @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; @Getter(AccessLevel.PACKAGE) private boolean HandCripple; @Getter(AccessLevel.PACKAGE) @@ -207,6 +209,7 @@ public class CoxPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(coxOverlay); overlayManager.add(coxInfoBox); @@ -227,12 +230,24 @@ public class CoxPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(coxOverlay); overlayManager.remove(coxInfoBox); } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onChatMessage(ChatMessage chatMessage) { if (inRaid()) { @@ -305,8 +320,7 @@ public class CoxPlugin extends Plugin } } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void onProjectileMoved(ProjectileMoved event) { if (inRaid()) { @@ -328,8 +342,7 @@ public class CoxPlugin extends Plugin } } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged graphicChanged) + private void onSpotAnimationChanged(SpotAnimationChanged graphicChanged) { if (inRaid()) { @@ -344,8 +357,7 @@ public class CoxPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) + private void onNpcSpawned(NpcSpawned npcSpawned) { if (inRaid()) { @@ -384,8 +396,7 @@ public class CoxPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (inRaid()) { @@ -429,8 +440,7 @@ public class CoxPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (!inRaid()) { @@ -696,8 +706,7 @@ public class CoxPlugin extends Plugin return client.getVar(Varbits.IN_RAID) == 1; } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getGroup().equals("Cox")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/crystalmathlabs/CrystalMathLabs.java b/runelite-client/src/main/java/net/runelite/client/plugins/crystalmathlabs/CrystalMathLabs.java index 77a9ec68b2..8831a7df84 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/crystalmathlabs/CrystalMathLabs.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/crystalmathlabs/CrystalMathLabs.java @@ -35,7 +35,7 @@ import net.runelite.api.Player; import net.runelite.api.Skill; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.http.api.RuneLiteAPI; @@ -64,12 +64,27 @@ public class CrystalMathLabs extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + private String lastUsername; private boolean fetchXp; private long lastXp; - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { GameState state = gameStateChanged.getGameState(); if (state == GameState.LOGGED_IN) @@ -98,8 +113,7 @@ public class CrystalMathLabs extends Plugin } } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { if (fetchXp) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java index feb8729740..aff60c0daf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursorPlugin.java @@ -29,7 +29,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientUI; @@ -48,6 +48,9 @@ public class CustomCursorPlugin extends Plugin @Inject private CustomCursorConfig config; + @Inject + private EventBus eventBus; + @Provides CustomCursorConfig provideConfig(ConfigManager configManager) { @@ -57,17 +60,19 @@ public class CustomCursorPlugin extends Plugin @Override protected void startUp() { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); updateCursor(); } @Override protected void shutDown() { + eventBus.unregister(this); + clientUI.resetCursor(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("customcursor") && event.getKey().equals("cursorStyle")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java index 764b93a308..8bd6c9f770 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dailytaskindicators/DailyTasksPlugin.java @@ -44,7 +44,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -80,6 +80,9 @@ public class DailyTasksPlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + private long lastReset; private boolean loggingIn; @@ -103,6 +106,9 @@ public class DailyTasksPlugin extends Plugin public void startUp() { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + + addSubscriptions(); loggingIn = true; } @@ -110,11 +116,19 @@ public class DailyTasksPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + + eventBus.unregister(this); lastReset = 0L; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGING_IN) { @@ -122,8 +136,7 @@ public class DailyTasksPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { long currentTime = System.currentTimeMillis(); boolean dailyReset = !loggingIn && currentTime - lastReset > ONE_DAY; @@ -174,7 +187,7 @@ public class DailyTasksPlugin extends Plugin { checkArrows(dailyReset); } - + if (this.showDynamite) { checkDynamite(dailyReset); @@ -245,8 +258,9 @@ public class DailyTasksPlugin extends Plugin private void checkArrows(boolean dailyReset) { - if ((client.getVar(Varbits.DIARY_WESTERN_EASY) == 1) - && (dailyReset || client.getVar(Varbits.DAILY_ARROWS_STATE) == 0)) + if (client.getVar(Varbits.DIARY_WESTERN_EASY) == 1 + && (client.getVar(Varbits.DAILY_ARROWS_STATE) == 0 + || dailyReset)) { sendChatMessage(ARROWS_MESSAGE); } @@ -297,8 +311,7 @@ public class DailyTasksPlugin extends Plugin .build()); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getGroup().equals("dailytaskindicators")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java index 16d755049b..5a56dad3b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/deathindicator/DeathIndicatorPlugin.java @@ -43,7 +43,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.LocalPlayerDeath; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -83,6 +83,9 @@ public class DeathIndicatorPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + private BufferedImage mapArrow; private Timer deathTimer; @@ -100,6 +103,8 @@ public class DeathIndicatorPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + if (!hasDied()) { return; @@ -127,6 +132,8 @@ public class DeathIndicatorPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + if (client.hasHintArrow()) { client.clearHintArrow(); @@ -141,8 +148,15 @@ public class DeathIndicatorPlugin extends Plugin worldMapPointManager.removeIf(DeathWorldMapPoint.class::isInstance); } - @Subscribe - public void onLocalPlayerDeath(LocalPlayerDeath death) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(LocalPlayerDeath.class, this, this::onLocalPlayerDeath); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onLocalPlayerDeath(LocalPlayerDeath death) { if (client.isInInstancedRegion()) { @@ -154,8 +168,7 @@ public class DeathIndicatorPlugin extends Plugin lastDeathTime = Instant.now(); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { // Check if player respawned in a death respawn location if (lastDeath != null && !client.getLocalPlayer().getWorldLocation().equals(lastDeath)) @@ -219,8 +232,7 @@ public class DeathIndicatorPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("deathIndicator")) { @@ -251,8 +263,7 @@ public class DeathIndicatorPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (!hasDied()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java index f8a56ffbc6..0999eda3c1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java @@ -33,7 +33,7 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionOpen; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -57,6 +57,9 @@ public class DefaultWorldPlugin extends Plugin @Inject private DefaultWorldConfig config; + @Inject + private EventBus eventBus; + private final WorldClient worldClient = new WorldClient(); private int worldCache; private boolean worldChangeRequired; @@ -64,6 +67,8 @@ public class DefaultWorldPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + worldChangeRequired = true; applyWorld(); } @@ -71,25 +76,31 @@ public class DefaultWorldPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + worldChangeRequired = true; changeWorld(worldCache); } + private void addSubscriptions() + { + eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + @Provides DefaultWorldConfig getConfig(ConfigManager configManager) { return configManager.getConfig(DefaultWorldConfig.class); } - @Subscribe - public void onSessionOpen(SessionOpen event) + private void onSessionOpen(SessionOpen event) { worldChangeRequired = true; applyWorld(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { applyWorld(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaOverlay.java index 53b64457eb..7d841afb5c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaOverlay.java @@ -24,7 +24,6 @@ */ package net.runelite.client.plugins.demonicgorilla; -import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -43,6 +42,7 @@ import net.runelite.client.game.SkillIconManager; 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; @Singleton public class DemonicGorillaOverlay extends Overlay @@ -118,31 +118,11 @@ public class DemonicGorillaOverlay extends Overlay int currentPosX = 0; for (BufferedImage icon : icons) { - graphics.setStroke(new BasicStroke(2)); - graphics.setColor(COLOR_ICON_BACKGROUND); - graphics.fillOval( - point.getX() - totalWidth / 2 + currentPosX - bgPadding, - point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, - icon.getWidth() + bgPadding * 2, - icon.getHeight() + bgPadding * 2); - - graphics.setColor(COLOR_ICON_BORDER); - graphics.drawOval( - point.getX() - totalWidth / 2 + currentPosX - bgPadding, - point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, - icon.getWidth() + bgPadding * 2, - icon.getHeight() + bgPadding * 2); - - graphics.drawImage( - icon, - point.getX() - totalWidth / 2 + currentPosX, - point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE, - null); - - graphics.setColor(COLOR_ICON_BORDER_FILL); + OverlayUtil.setProgressIcon(graphics, point, icon, totalWidth, bgPadding, currentPosX, + COLOR_ICON_BACKGROUND, OVERLAY_ICON_DISTANCE, COLOR_ICON_BORDER, COLOR_ICON_BORDER_FILL); Arc2D.Double arc = new Arc2D.Double( point.getX() - totalWidth / 2 + currentPosX - bgPadding, - point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, + point.getY() - (float) (icon.getHeight() / 2) - OVERLAY_ICON_DISTANCE - bgPadding, icon.getWidth() + bgPadding * 2, icon.getHeight() + bgPadding * 2, 90.0, diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java index 9b4d7f8a21..aa7262b424 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/demonicgorilla/DemonicGorillaPlugin.java @@ -56,7 +56,7 @@ import net.runelite.api.events.PlayerDespawned; import net.runelite.api.events.PlayerSpawned; import net.runelite.api.events.ProjectileMoved; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -81,6 +81,9 @@ public class DemonicGorillaPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Map gorillas; @@ -93,6 +96,7 @@ public class DemonicGorillaPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); overlayManager.add(overlay); gorillas = new HashMap<>(); recentBoulders = new ArrayList<>(); @@ -104,6 +108,7 @@ public class DemonicGorillaPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.remove(overlay); gorillas = null; recentBoulders = null; @@ -111,6 +116,18 @@ public class DemonicGorillaPlugin extends Plugin memorizedPlayers = null; } + private void addSubscriptions() + { + eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + private void clear() { recentBoulders.clear(); @@ -528,8 +545,7 @@ public class DemonicGorillaPlugin extends Plugin } } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void onProjectileMoved(ProjectileMoved event) { Projectile projectile = event.getProjectile(); int projectileId = projectile.getId(); @@ -616,8 +632,7 @@ public class DemonicGorillaPlugin extends Plugin } } - @Subscribe - public void onHitsplatApplied(HitsplatApplied event) + private void onHitsplatApplied(HitsplatApplied event) { if (gorillas.isEmpty()) { @@ -645,8 +660,7 @@ public class DemonicGorillaPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { GameState gs = event.getGameState(); if (gs == GameState.LOGGING_IN || @@ -657,8 +671,7 @@ public class DemonicGorillaPlugin extends Plugin } } - @Subscribe - public void onPlayerSpawned(PlayerSpawned event) + private void onPlayerSpawned(PlayerSpawned event) { if (gorillas.isEmpty()) { @@ -669,8 +682,7 @@ public class DemonicGorillaPlugin extends Plugin memorizedPlayers.put(player, new MemorizedPlayer(player)); } - @Subscribe - public void onPlayerDespawned(PlayerDespawned event) + private void onPlayerDespawned(PlayerDespawned event) { if (gorillas.isEmpty()) { @@ -680,8 +692,7 @@ public class DemonicGorillaPlugin extends Plugin memorizedPlayers.remove(event.getPlayer()); } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); if (isNpcGorilla(npc.getId())) @@ -697,8 +708,7 @@ public class DemonicGorillaPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (gorillas.remove(event.getNpc()) != null && gorillas.isEmpty()) { @@ -706,8 +716,7 @@ public class DemonicGorillaPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { checkGorillaAttacks(); checkPendingAttacks(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java index cc64835acb..1bef2b684f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsPlugin.java @@ -42,15 +42,16 @@ import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.Skill; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.AreaSoundEffectPlayed; import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.CommandExecuted; import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.SoundEffectPlayed; import net.runelite.api.events.VarbitChanged; import net.runelite.api.kit.KitType; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; @@ -143,6 +144,8 @@ public class DevToolsPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + players = new DevToolsButton("Players"); npcs = new DevToolsButton("NPCs"); @@ -200,14 +203,13 @@ public class DevToolsPlugin extends Plugin .build(); clientToolbar.addNavigation(navButton); - - eventBus.register(soundEffectOverlay); } @Override protected void shutDown() throws Exception { - eventBus.unregister(soundEffectOverlay); + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(locationOverlay); overlayManager.remove(sceneOverlay); @@ -218,8 +220,15 @@ public class DevToolsPlugin extends Plugin clientToolbar.removeNavigation(navButton); } - @Subscribe - public void onCommandExecuted(CommandExecuted commandExecuted) + private void addSubscriptions() + { + eventBus.subscribe(CommandExecuted.class, this, this::onCommandExecuted); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(AreaSoundEffectPlayed.class, this, this::onAreaSoundEffectPlayed); + eventBus.subscribe(SoundEffectPlayed.class, this, this::onSoundEffectPlayed); + } + + private void onCommandExecuted(CommandExecuted commandExecuted) { String[] args = commandExecuted.getArguments(); @@ -260,7 +269,7 @@ public class DevToolsPlugin extends Plugin client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Set VarPlayer " + varp + " to " + value, null); VarbitChanged varbitChanged = new VarbitChanged(); varbitChanged.setIndex(varp); - eventBus.post(varbitChanged); // fake event + eventBus.post(VarbitChanged.class, varbitChanged); // fake event break; } case "getvarb": @@ -276,7 +285,7 @@ public class DevToolsPlugin extends Plugin int value = Integer.parseInt(args[1]); client.setVarbitValue(client.getVarps(), varbit, value); client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "Set varbit " + varbit + " to " + value, null); - eventBus.post(new VarbitChanged()); // fake event + eventBus.post(VarbitChanged.class, new VarbitChanged()); // fake event break; } case "addxp": @@ -295,7 +304,7 @@ public class DevToolsPlugin extends Plugin ExperienceChanged experienceChanged = new ExperienceChanged(); experienceChanged.setSkill(skill); - eventBus.post(experienceChanged); + eventBus.post(ExperienceChanged.class, experienceChanged); break; } case "setstat": @@ -314,11 +323,11 @@ public class DevToolsPlugin extends Plugin ExperienceChanged experienceChanged = new ExperienceChanged(); experienceChanged.setSkill(skill); - eventBus.post(experienceChanged); + eventBus.post(ExperienceChanged.class, experienceChanged); BoostedLevelChanged boostedLevelChanged = new BoostedLevelChanged(); boostedLevelChanged.setSkill(skill); - eventBus.post(boostedLevelChanged); + eventBus.post(BoostedLevelChanged.class, boostedLevelChanged); break; } case "anim": @@ -363,8 +372,7 @@ public class DevToolsPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!examine.isActive()) { @@ -401,4 +409,24 @@ public class DevToolsPlugin extends Plugin client.setMenuEntries(entries); } } + + private void onSoundEffectPlayed(SoundEffectPlayed event) + { + if (!getSoundEffects().isActive() || soundEffectOverlay == null) + { + return; + } + + soundEffectOverlay.onSoundEffectPlayed(event); + } + + private void onAreaSoundEffectPlayed(AreaSoundEffectPlayed event) + { + if (!getSoundEffects().isActive() || soundEffectOverlay == null) + { + return; + } + + soundEffectOverlay.onAreaSoundEffectPlayed(event); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/SoundEffectOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/SoundEffectOverlay.java index fbe2254066..e98e0ef01e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/SoundEffectOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/SoundEffectOverlay.java @@ -33,7 +33,6 @@ import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; import net.runelite.api.events.AreaSoundEffectPlayed; import net.runelite.api.events.SoundEffectPlayed; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.components.LineComponent; @@ -74,14 +73,8 @@ class SoundEffectOverlay extends Overlay return panelComponent.render(graphics); } - @Subscribe - public void onSoundEffectPlayed(SoundEffectPlayed event) + void onSoundEffectPlayed(SoundEffectPlayed event) { - if (!plugin.getSoundEffects().isActive()) - { - return; - } - String text = "Id: " + event.getSoundId() + " - D: " + event.getDelay(); @@ -94,14 +87,8 @@ class SoundEffectOverlay extends Overlay checkMaxLines(); } - @Subscribe - public void onAreaSoundEffectPlayed(AreaSoundEffectPlayed event) + void onAreaSoundEffectPlayed(AreaSoundEffectPlayed event) { - if (!plugin.getSoundEffects().isActive()) - { - return; - } - Color textColor = COLOR_AREA_SOUND_EFFECT; // Check if the player is within range to hear the sound diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java index bea864d8bc..3115963a9f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java @@ -56,7 +56,6 @@ import net.runelite.api.events.VarClientIntChanged; import net.runelite.api.events.VarClientStrChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.DynamicGridLayout; @@ -115,6 +114,7 @@ class VarInspector extends JFrame @Override public void windowClosing(WindowEvent e) { + eventBus.unregister(this); close(); plugin.getVarInspector().setActive(false); } @@ -170,6 +170,7 @@ class VarInspector extends JFrame add(trackerOpts, BorderLayout.SOUTH); pack(); + } private void addVarLog(VarType type, String name, int old, int neew) @@ -210,8 +211,7 @@ class VarInspector extends JFrame }); } - @Subscribe - public void onVarbitChanged(VarbitChanged ev) + private void onVarbitChanged(VarbitChanged ev) { int[] varps = client.getVarps(); @@ -274,8 +274,7 @@ class VarInspector extends JFrame System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length); } - @Subscribe - public void onVarClientIntChanged(VarClientIntChanged e) + private void onVarClientIntChanged(VarClientIntChanged e) { int idx = e.getIndex(); int neew = (Integer) client.getVarcMap().getOrDefault(idx, 0); @@ -297,8 +296,7 @@ class VarInspector extends JFrame } } - @Subscribe - public void onVarClientStrChanged(VarClientStrChanged e) + private void onVarClientStrChanged(VarClientStrChanged e) { int idx = e.getIndex(); String neew = (String) client.getVarcMap().getOrDefault(idx, ""); @@ -348,7 +346,11 @@ class VarInspector extends JFrame System.arraycopy(client.getVarps(), 0, oldVarps2, 0, oldVarps2.length); varcs = new HashMap<>(client.getVarcMap()); - eventBus.register(this); + // eventBus.register(this); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(VarClientIntChanged.class, this, this::onVarClientIntChanged); + eventBus.subscribe(VarClientStrChanged.class, this, this::onVarClientStrChanged); + setVisible(true); toFront(); repaint(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java index f622b59677..492206a0aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/WidgetInspector.java @@ -53,7 +53,6 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.callback.ClientThread; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.ClientUI; @Slf4j @@ -86,7 +85,7 @@ class WidgetInspector extends JFrame this.config = config; this.overlay = overlay; - eventBus.register(this); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); setTitle("RuneLite Widget Inspector"); setIconImage(ClientUI.ICON); @@ -97,6 +96,7 @@ class WidgetInspector extends JFrame @Override public void windowClosing(WindowEvent e) { + eventBus.unregister(this); close(); plugin.getWidgetInspector().setActive(false); } @@ -165,9 +165,9 @@ class WidgetInspector extends JFrame add(split, BorderLayout.CENTER); pack(); + } - @Subscribe private void onConfigChanged(ConfigChanged ev) { boolean onTop = config.inspectorAlwaysOnTop(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java index cfeff83a8d..087b51d95e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java @@ -56,7 +56,7 @@ import net.runelite.client.discord.DiscordService; import net.runelite.client.discord.events.DiscordJoinGame; import net.runelite.client.discord.events.DiscordJoinRequest; import net.runelite.client.discord.events.DiscordReady; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.PartyChanged; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -110,6 +110,9 @@ public class DiscordPlugin extends Plugin @Inject private WSClient wsClient; + @Inject + private EventBus eventBus; + private final Map skillExp = new HashMap<>(); private NavigationButton discordButton; private boolean loginFlag; @@ -137,6 +140,7 @@ public class DiscordPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "discord.png"); @@ -162,14 +166,31 @@ public class DiscordPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + clientToolbar.removeNavigation(discordButton); discordState.reset(); partyService.changeParty(null); wsClient.unregisterMessage(DiscordUserInfo.class); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(DiscordReady.class, this, this::onDiscordReady); + eventBus.subscribe(DiscordJoinRequest.class, this, this::onDiscordJoinRequest); + eventBus.subscribe(DiscordJoinGame.class, this, this::onDiscordJoinGame); + eventBus.subscribe(DiscordUserInfo.class, this, this::onDiscordUserInfo); + eventBus.subscribe(UserJoin.class, this, this::onUserJoin); + eventBus.subscribe(UserSync.class, this, this::onUserSync); + eventBus.subscribe(UserPart.class, this, this::onUserPart); + eventBus.subscribe(PartyChanged.class, this, this::onPartyChanged); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -192,8 +213,7 @@ public class DiscordPlugin extends Plugin checkForAreaUpdate(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equalsIgnoreCase("discord")) { @@ -205,8 +225,7 @@ public class DiscordPlugin extends Plugin } } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void onExperienceChanged(ExperienceChanged event) { final int exp = client.getSkillExperience(event.getSkill()); final Integer previous = skillExp.put(event.getSkill(), exp); @@ -224,8 +243,7 @@ public class DiscordPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { if (!this.showRaidingActivity) { @@ -240,14 +258,12 @@ public class DiscordPlugin extends Plugin } } - @Subscribe - public void onDiscordReady(DiscordReady event) + private void onDiscordReady(DiscordReady event) { partyService.setUsername(event.getUsername() + "#" + event.getDiscriminator()); } - @Subscribe - public void onDiscordJoinRequest(DiscordJoinRequest request) + private void onDiscordJoinRequest(DiscordJoinRequest request) { log.debug("Got discord join request {}", request); if (partyService.isOwner() && partyService.getMembers().isEmpty()) @@ -258,8 +274,7 @@ public class DiscordPlugin extends Plugin } } - @Subscribe - public void onDiscordJoinGame(DiscordJoinGame joinGame) + private void onDiscordJoinGame(DiscordJoinGame joinGame) { log.debug("Got discord join game {}", joinGame); UUID partyId = UUID.fromString(joinGame.getJoinSecret()); @@ -267,8 +282,7 @@ public class DiscordPlugin extends Plugin updatePresence(); } - @Subscribe - public void onDiscordUserInfo(final DiscordUserInfo event) + private void onDiscordUserInfo(final DiscordUserInfo event) { final PartyMember memberById = partyService.getMemberById(event.getMemberId()); @@ -327,14 +341,12 @@ public class DiscordPlugin extends Plugin }); } - @Subscribe - public void onUserJoin(final UserJoin event) + private void onUserJoin(final UserJoin event) { updatePresence(); } - @Subscribe - public void onUserSync(final UserSync event) + private void onUserSync(final UserSync event) { final PartyMember localMember = partyService.getLocalMember(); @@ -349,14 +361,12 @@ public class DiscordPlugin extends Plugin } } - @Subscribe - public void onUserPart(final UserPart event) + private void onUserPart(final UserPart event) { updatePresence(); } - @Subscribe - public void onPartyChanged(final PartyChanged event) + private void onPartyChanged(final PartyChanged event) { updatePresence(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java index dff53b98c1..1124dbb9aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java @@ -42,7 +42,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.OverheadTextChanged; import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.ImageUtil; @@ -64,16 +64,32 @@ public class EmojiPlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + private int modIconsStart = -1; @Override protected void startUp() { loadEmojiIcons(); + addSubscriptions(); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(OverheadTextChanged.class, this, this::onOverheadTextChanged); + } + + void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { @@ -113,8 +129,7 @@ public class EmojiPlugin extends Plugin client.setModIcons(newModIcons); } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + void onChatMessage(ChatMessage chatMessage) { if (client.getGameState() != GameState.LOGGED_IN || modIconsStart == -1) { @@ -148,8 +163,7 @@ public class EmojiPlugin extends Plugin client.refreshChat(); } - @Subscribe - public void onOverheadTextChanged(final OverheadTextChanged event) + private void onOverheadTextChanged(final OverheadTextChanged event) { if (!(event.getActor() instanceof Player)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java index 72a13d5fe9..73263e4877 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java @@ -35,7 +35,7 @@ import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -54,6 +54,9 @@ public class EntityHiderPlugin extends Plugin @Inject private EntityHiderConfig config; + @Inject + private EventBus eventBus; + @Provides EntityHiderConfig provideConfig(ConfigManager configManager) { @@ -64,15 +67,23 @@ public class EntityHiderPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); } - @Subscribe - public void onConfigChanged(ConfigChanged e) + private void addSubscriptions() { - updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("entityhider")) + { + updateConfig(); + } } - @Subscribe public void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) @@ -106,6 +117,8 @@ public class EntityHiderPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + client.setIsHidingEntities(false); client.setPlayersHidden(false); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java index 84e784ba48..7059642ddf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java @@ -52,7 +52,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; @@ -94,6 +94,10 @@ public class EquipmentInspectorPlugin extends Plugin @Inject private ClientToolbar pluginToolbar; + + @Inject + private EventBus eventBus; + private NavigationButton navButton; private EquipmentInspectorPanel equipmentInspectorPanel; private int TotalPrice = 0; @@ -116,6 +120,7 @@ public class EquipmentInspectorPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); if (client != null) @@ -140,12 +145,18 @@ public class EquipmentInspectorPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); } - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(PlayerMenuOptionClicked.class, this, this::onPlayerMenuOptionClicked); + } + + private void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) { @@ -297,8 +308,7 @@ public class EquipmentInspectorPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equalsIgnoreCase("equipmentinspector")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 26e77760a7..8583cbe11a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -50,7 +50,7 @@ import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -96,15 +96,34 @@ public class ExaminePlugin extends Plugin @Inject private ScheduledExecutorService executor; + @Inject + private EventBus eventBus; - @Subscribe - public void onGameStateChanged(GameStateChanged event) + @Override + protected void startUp() throws Exception + { + addSubscriptions(); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onGameStateChanged(GameStateChanged event) { pending.clear(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + void onMenuOptionClicked(MenuOptionClicked event) { if (!event.getOption().equals("Examine")) { @@ -161,8 +180,7 @@ public class ExaminePlugin extends Plugin pending.push(pendingExamine); } - @Subscribe - public void onChatMessage(ChatMessage event) + void onChatMessage(ChatMessage event) { ExamineType type; switch (event.getType()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java index ce76c45f00..91e8036c98 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java @@ -55,7 +55,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.NPCManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -89,6 +89,9 @@ public class XpDropPlugin extends Plugin @Inject private XpDropOverlay overlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private int damage = 0; @@ -126,6 +129,7 @@ public class XpDropPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); damageMode = config.showdamagedrops(); @@ -138,11 +142,22 @@ public class XpDropPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("xpdrop")) { @@ -171,15 +186,13 @@ public class XpDropPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { damage = 0; tickShow = 0; } - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged event) + private void onWidgetHiddenChanged(WidgetHiddenChanged event) { Widget widget = event.getWidget(); @@ -303,8 +316,7 @@ public class XpDropPlugin extends Plugin return null; } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { lastOpponent = client.getLocalPlayer().getInteracting(); @@ -339,8 +351,7 @@ public class XpDropPlugin extends Plugin client.runScript(XPDROP_DISABLED, lastSkill.ordinal(), previousExpGained); } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void onExperienceChanged(ExperienceChanged event) { final Skill skill = event.getSkill(); final int xp = client.getSkillExperience(skill); @@ -355,8 +366,7 @@ public class XpDropPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent e) + private void onScriptCallbackEvent(ScriptCallbackEvent e) { if (this.showdamagedrops == XpDropConfig.DamageMode.NONE) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java index ee66d4271f..d7cad2deb9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java @@ -55,7 +55,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxTextInput; import net.runelite.client.plugins.Plugin; @@ -92,6 +92,9 @@ public class FairyRingPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + private ChatboxTextInput searchInput = null; private Widget searchBtn; private Collection codes = null; @@ -115,10 +118,24 @@ public class FairyRingPlugin extends Plugin protected void startUp() throws Exception { this.autoOpen = config.autoOpen(); + addSubscriptions(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("fairyrings")) { @@ -134,14 +151,12 @@ public class FairyRingPlugin extends Plugin return configManager.getConfig(FairyRingConfig.class); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { setWidgetTextToDestination(); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded widgetLoaded) + private void onWidgetLoaded(WidgetLoaded widgetLoaded) { if (widgetLoaded.getGroupId() == WidgetID.FAIRY_RING_PANEL_GROUP_ID) { @@ -227,8 +242,7 @@ public class FairyRingPlugin extends Plugin .build(); } - @Subscribe - public void onGameTick(GameTick t) + private void onGameTick(GameTick t) { // This has to happen because the only widget that gets hidden is the tli one Widget fairyRingTeleportButton = client.getWidget(WidgetInfo.FAIRY_RING_TELEPORT_BUTTON); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPlugin.java index 59de3a4465..f7a6337aa5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPlugin.java @@ -37,7 +37,7 @@ import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.task.Schedule; @@ -66,6 +66,9 @@ public class FeedPlugin extends Plugin @Inject private ScheduledExecutorService executorService; + @Inject + private EventBus eventBus; + private FeedPanel feedPanel; private NavigationButton navButton; @@ -86,6 +89,8 @@ public class FeedPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + feedPanel = new FeedPanel(config, feedSupplier); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "icon.png"); @@ -104,6 +109,7 @@ public class FeedPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); clientToolbar.removeNavigation(navButton); } @@ -112,8 +118,7 @@ public class FeedPlugin extends Plugin feedPanel.rebuildFeed(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("feed")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java index 2376f09fb6..90b84085e0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fightcave/FightCavePlugin.java @@ -52,7 +52,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.NPCManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -130,6 +130,8 @@ public class FightCavePlugin extends Plugin private FightCaveOverlay fightCaveOverlay; @Inject private FightCaveConfig config; + @Inject + private EventBus eventBus; @Getter(AccessLevel.PACKAGE) private Set fightCaveContainer = new HashSet<>(); @Getter(AccessLevel.PACKAGE) @@ -170,6 +172,7 @@ public class FightCavePlugin extends Plugin public void startUp() { updateConfig(); + addSubscriptions(); if (client.getGameState() == GameState.LOGGED_IN && regionCheck()) { @@ -182,13 +185,24 @@ public class FightCavePlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + overlayManager.remove(waveOverlay); overlayManager.remove(fightCaveOverlay); currentWave = -1; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("fightcave")) { @@ -198,8 +212,7 @@ public class FightCavePlugin extends Plugin updateConfig(); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (!validRegion) { @@ -216,8 +229,7 @@ public class FightCavePlugin extends Plugin currentWave = Integer.parseInt(waveMatcher.group(1)); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() != GameState.LOGGED_IN) { @@ -240,8 +252,7 @@ public class FightCavePlugin extends Plugin fightCaveContainer.clear(); } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { if (!validRegion) { @@ -265,8 +276,7 @@ public class FightCavePlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (!validRegion) { @@ -290,8 +300,7 @@ public class FightCavePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick Event) + private void onGameTick(GameTick Event) { if (!validRegion) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java index 074a4d4858..5539fde29e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java @@ -64,7 +64,7 @@ import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; @@ -131,6 +131,9 @@ public class FishingPlugin extends Plugin @Inject private FishingSpotMinimapOverlay fishingSpotMinimapOverlay; + @Inject + private EventBus eventBus; + private boolean trawlerNotificationSent; @Provides @@ -159,6 +162,7 @@ public class FishingPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(spotOverlay); @@ -168,6 +172,8 @@ public class FishingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + spotOverlay.setHidden(true); fishingSpotMinimapOverlay.setHidden(true); overlayManager.remove(overlay); @@ -180,8 +186,21 @@ public class FishingPlugin extends Plugin trawlerStartTime = null; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("fishing")) { @@ -191,8 +210,7 @@ public class FishingPlugin extends Plugin updateConfig(); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { GameState gameState = gameStateChanged.getGameState(); if (gameState == GameState.CONNECTION_LOST || gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING) @@ -202,8 +220,7 @@ public class FishingPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY) && event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT)) @@ -224,8 +241,7 @@ public class FishingPlugin extends Plugin fishingSpotMinimapOverlay.setHidden(!showOverlays); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.SPAM) { @@ -241,8 +257,7 @@ public class FishingPlugin extends Plugin } } - @Subscribe - public void onInteractingChanged(InteractingChanged event) + private void onInteractingChanged(InteractingChanged event) { if (event.getSource() != client.getLocalPlayer()) { @@ -277,8 +292,7 @@ public class FishingPlugin extends Plugin return ItemUtil.containsAnyItemId(itemContainer.getItems(), FISHING_TOOLS); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { // Reset fishing session if (session.getLastFishCaught() != null) @@ -318,8 +332,7 @@ public class FishingPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { final NPC npc = event.getNpc(); @@ -332,8 +345,7 @@ public class FishingPlugin extends Plugin inverseSortSpotDistanceFromPlayer(); } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { final NPC npc = npcDespawned.getNpc(); @@ -346,8 +358,7 @@ public class FishingPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { if (!this.trawlerNotification || client.getGameState() != GameState.LOGGED_IN) { @@ -371,8 +382,7 @@ public class FishingPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() == WidgetID.FISHING_TRAWLER_GROUP_ID) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java index 04dc3bacf8..dca9efe014 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java @@ -90,6 +90,7 @@ import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1508; import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1509; import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1513; import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1515; +import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1516; import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1526; import static net.runelite.api.NpcID.ROD_FISHING_SPOT_1527; import static net.runelite.api.NpcID.ROD_FISHING_SPOT_6825; @@ -127,9 +128,9 @@ enum FishingSpot ), SALMON("Salmon, Trout", ItemID.RAW_SALMON, ROD_FISHING_SPOT, ROD_FISHING_SPOT_1508, ROD_FISHING_SPOT_1509, - ROD_FISHING_SPOT_1513, ROD_FISHING_SPOT_1515, ROD_FISHING_SPOT_1526, - ROD_FISHING_SPOT_1527, ROD_FISHING_SPOT_7463, ROD_FISHING_SPOT_7464, - ROD_FISHING_SPOT_7468, ROD_FISHING_SPOT_8524 + ROD_FISHING_SPOT_1513, ROD_FISHING_SPOT_1515, ROD_FISHING_SPOT_1516, + ROD_FISHING_SPOT_1526, ROD_FISHING_SPOT_1527, ROD_FISHING_SPOT_7463, + ROD_FISHING_SPOT_7464, ROD_FISHING_SPOT_7468, ROD_FISHING_SPOT_8524 ), BARB_FISH("Sturgeon, Salmon, Trout", ItemID.LEAPING_STURGEON, FISHING_SPOT_1542, FISHING_SPOT_7323 diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java index e0e1b57b20..a8a8cdcaa5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java @@ -51,7 +51,7 @@ import net.runelite.api.coords.LocalPoint; import net.runelite.api.events.BeforeRender; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.flexo.Flexo; import net.runelite.client.flexo.FlexoMouse; import net.runelite.client.plugins.Plugin; @@ -104,6 +104,9 @@ public class FlexoPlugin extends Plugin @Inject private FlexoConfig config; + @Inject + private EventBus eventBus; + @Provides FlexoConfig getConfig(ConfigManager configManager) { @@ -138,7 +141,6 @@ public class FlexoPlugin extends Plugin @Getter(AccessLevel.PACKAGE) private List clickPoints = new ArrayList<>(); - @Subscribe private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("flexo") || (!event.getGroup().equals("stretchedmode")) ) @@ -150,9 +152,7 @@ public class FlexoPlugin extends Plugin updateMouseMotionFactory(); } - - @Subscribe - public void onBeforeRender(BeforeRender event) + private void onBeforeRender(BeforeRender event) { if (Flexo.client == null) { @@ -293,6 +293,7 @@ public class FlexoPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); Flexo.isStretched = client.isStretchedEnabled(); overlayManager.add(overlay); @@ -302,9 +303,17 @@ public class FlexoPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(BeforeRender.class, this, this::onBeforeRender); + } + private void updateConfig() { this.overlayEnabled = config.overlayEnabled(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java index fb8bffc9d6..b33699436a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsPlugin.java @@ -38,7 +38,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.DrawManager; @@ -92,6 +92,9 @@ public class FpsPlugin extends Plugin @Inject private FpsConfig fpsConfig; + @Inject + private EventBus eventBus; + private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor()); private boolean loaded = false; @@ -113,8 +116,7 @@ public class FpsPlugin extends Plugin return configManager.getConfig(FpsConfig.class); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals(CONFIG_GROUP_KEY)) { @@ -126,15 +128,13 @@ public class FpsPlugin extends Plugin } } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void onFocusChanged(FocusChanged event) { drawListener.onFocusChanged(event); overlay.onFocusChanged(event); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { shutdown = event.getGameState() != GameState.LOGGED_IN; } @@ -142,6 +142,8 @@ public class FpsPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + limitMode = fpsConfig.limitMode(); drawFps = fpsConfig.drawFps(); drawPing = fpsConfig.drawPing(); @@ -160,11 +162,20 @@ public class FpsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); drawManager.unregisterEveryFrameListener(drawListener); shutdown = true; } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + private void getPingToCurrentWorld() { if (!shutdown && drawPing) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeInfo.java deleted file mode 100644 index 2a5409cd4d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeInfo.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.runelite.client.plugins.freezetimers; - -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import net.runelite.api.Actor; -import net.runelite.api.coords.LocalPoint; - -@Builder -class FreezeInfo -{ - @Getter(AccessLevel.PACKAGE) - private final Actor actor; - @Getter(AccessLevel.PACKAGE) - private final LocalPoint freezePoint; -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java index 3a19f7be49..55085bd094 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/freezetimers/FreezeTimersPlugin.java @@ -25,25 +25,24 @@ package net.runelite.client.plugins.freezetimers; import com.google.inject.Provides; -import java.util.HashMap; -import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.Actor; import net.runelite.api.Client; -import net.runelite.api.Player; +import net.runelite.api.NPC; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.SpotAnimationChanged; -import net.runelite.api.events.PlayerDespawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; +import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "Freeze Timers", @@ -55,7 +54,7 @@ import net.runelite.client.ui.overlay.OverlayManager; @Singleton public class FreezeTimersPlugin extends Plugin { - private final Map freezes = new HashMap<>(); + private static final int VORKATH_REGION = 9023; @Inject private Client client; @@ -75,6 +74,9 @@ public class FreezeTimersPlugin extends Plugin @Inject private FreezeTimersConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean showPlayers; @Getter(AccessLevel.PACKAGE) @@ -97,11 +99,14 @@ public class FreezeTimersPlugin extends Plugin public void startUp() { updateConfig(); + addSubscriptions(); + overlayManager.add(overlay); } public void shutDown() { + eventBus.unregister(this); overlayManager.remove(overlay); } @@ -111,8 +116,15 @@ public class FreezeTimersPlugin extends Plugin return configManager.getConfig(FreezeTimersConfig.class); } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged graphicChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + } + + private void onSpotAnimationChanged(SpotAnimationChanged graphicChanged) { int oldGraphic = prayerTracker.getSpotanimLastTick(graphicChanged.getActor()); int newGraphic = graphicChanged.getActor().getSpotAnimation(); @@ -138,8 +150,7 @@ public class FreezeTimersPlugin extends Plugin System.currentTimeMillis() + length); } - @Subscribe - public void onGameTick(GameTick tickEvent) + private void onGameTick(GameTick tickEvent) { timers.gameTick(); prayerTracker.gameTick(); @@ -149,27 +160,38 @@ public class FreezeTimersPlugin extends Plugin { SpotAnimationChanged callback = new SpotAnimationChanged(); callback.setActor(actor); - client.getCallbacks().post(callback); + client.getCallbacks().post(SpotAnimationChanged.class, callback); } } } - @Subscribe - public void onPlayerDespawned(PlayerDespawned playerDespawned) + private void onNpcDespawned(NpcDespawned event) { - final Player player = playerDespawned.getPlayer(); - // All despawns ok: death, teleports, log out, runs away from screen - this.remove(player); + if (!isAtVorkath()) + { + return; + } + + final NPC npc = event.getNpc(); + + if (npc.getName() == null) + { + return; + } + + if (npc.getName().equals("Zombified Spawn")) + { + timers.setTimerEnd(client.getLocalPlayer(), TimerType.FREEZE, + System.currentTimeMillis()); + } } - private void remove(Actor actor) + private boolean isAtVorkath() { - freezes.remove(actor.getName()); + return ArrayUtils.contains(client.getMapRegions(), VORKATH_REGION); } - - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("freezetimers")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java index b98b68d7eb..1d71c487bf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListPlugin.java @@ -32,7 +32,7 @@ import net.runelite.api.VarPlayer; import net.runelite.api.events.GameTick; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -52,16 +52,26 @@ public class FriendListPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + @Override protected void shutDown() { + eventBus.unregister(this); + final int world = client.getWorld(); setFriendsListTitle("Friends List - World " + world); setIgnoreListTitle("Ignore List - World " + world); } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { final int world = client.getWorld(); final boolean isMember = client.getVar(VarPlayer.MEMBERSHIP_DAYS) > 0; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java index caefd58452..836b3e7fe2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java @@ -46,7 +46,7 @@ import net.runelite.api.events.NameableNameChanged; import net.runelite.api.events.FriendRemoved; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -85,21 +85,35 @@ public class FriendNotesPlugin extends Plugin @Inject private ChatboxPanelManager chatboxPanelManager; + @Inject + private EventBus eventBus; + @Getter private HoveredFriend hoveredFriend = null; @Override protected void startUp() throws Exception { + addSubscriptions(); overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } + private void addSubscriptions() + { + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(NameableNameChanged.class, this, this::onNameableNameChanged); + eventBus.subscribe(FriendRemoved.class, this, this::onFriendRemoved); + } + /** * Set a friend note, or unset by passing a null/empty note. */ @@ -160,8 +174,7 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); @@ -189,8 +202,7 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (WidgetInfo.TO_GROUP(event.getActionParam1()) == WidgetInfo.FRIENDS_LIST.getGroupId()) { @@ -227,8 +239,7 @@ public class FriendNotesPlugin extends Plugin } - @Subscribe - public void onNameableNameChanged(NameableNameChanged event) + private void onNameableNameChanged(NameableNameChanged event) { final Nameable nameable = event.getNameable(); @@ -249,8 +260,7 @@ public class FriendNotesPlugin extends Plugin } } - @Subscribe - public void onFriendRemoved(FriendRemoved event) + private void onFriendRemoved(FriendRemoved event) { // Delete a friend's note if they are removed final String displayName = Text.toJagexName(event.getName()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java index 4a693a64a3..1f273ec5ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendtagging/FriendTaggingPlugin.java @@ -34,7 +34,7 @@ import net.runelite.api.events.FriendRemoved; 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.eventbus.EventBus; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxTextInput; import net.runelite.client.menus.MenuManager; @@ -84,9 +84,14 @@ public class FriendTaggingPlugin extends Plugin @Inject private ChatboxPanelManager chatboxPanelManager; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { + addSubscriptions(); + menuManager.addManagedCustomMenu(friendsTabMenuOption); menuManager.addManagedCustomMenu(ignoreTabMenuOption); menuManager.addManagedCustomMenu(friendTabResizableOption); @@ -97,14 +102,24 @@ public class FriendTaggingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + menuManager.removeManagedCustomMenu(friendsTabMenuOption); menuManager.removeManagedCustomMenu(ignoreTabMenuOption); menuManager.removeManagedCustomMenu(friendTabResizableOption); menuManager.removeManagedCustomMenu(ignoreTabResizableOption); } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void addSubscriptions() + { + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(FriendRemoved.class, this, this::onFriendRemoved); + eventBus.subscribe(NameableNameChanged.class, this, this::onNameableNameChanged); + eventBus.subscribe(WidgetMenuOptionClicked.class, this, this::onWidgetMenuOptionClicked); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + } + + private void onMenuEntryAdded(MenuEntryAdded event) { final int groupId = WidgetInfo.TO_GROUP(event.getActionParam1()); @@ -127,15 +142,13 @@ public class FriendTaggingPlugin extends Plugin } } - @Subscribe - public void onFriendRemoved(FriendRemoved event) + private void onFriendRemoved(FriendRemoved event) { final String displayName = event.getName().trim().toLowerCase(); deleteTag(displayName); } - @Subscribe - public void onNameableNameChanged(NameableNameChanged event) + private void onNameableNameChanged(NameableNameChanged event) { final Nameable nameable = event.getNameable(); @@ -150,8 +163,7 @@ public class FriendTaggingPlugin extends Plugin } } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + private void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) { if (event.getWidget().getId() == WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB.getId() && Text.standardize(event.getMenuTarget()).equals(Text.standardize("clipboard"))) @@ -160,8 +172,7 @@ public class FriendTaggingPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (WidgetInfo.TO_GROUP(event.getActionParam1()) == WidgetInfo.FRIENDS_LIST.getGroupId()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GLUtil.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GLUtil.java index 8c4bf270fc..48b597c2c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GLUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GLUtil.java @@ -27,9 +27,7 @@ package net.runelite.client.plugins.gpu; import com.jogamp.opengl.GL4; import java.io.InputStream; import java.util.Scanner; -import lombok.extern.slf4j.Slf4j; -@Slf4j class GLUtil { private static final int ERR_LEN = 1024; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index e8cbcb9977..a7e1a3505c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -71,7 +71,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.hooks.DrawCallbacks; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginInstantiationException; @@ -121,6 +121,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks @Inject private PluginManager pluginManager; + @Inject + private EventBus eventbus; + private Canvas canvas; private JAWTWindow jawtWindow; private GL4 gl; @@ -238,8 +241,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks private int fogCircularity; private int fogDensity; - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("gpu")) { @@ -259,9 +261,11 @@ public class GpuPlugin extends Plugin implements DrawCallbacks } @Override - protected void startUp() + protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + clientThread.invoke(() -> { try @@ -362,6 +366,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks @Override protected void shutDown() { + eventbus.unregister(this); + clientThread.invoke(() -> { client.setGpu(false); @@ -431,6 +437,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks }); } + private void addSubscriptions() + { + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + @Provides GpuPluginConfig provideConfig(ConfigManager configManager) { @@ -800,8 +812,14 @@ public class GpuPlugin extends Plugin implements DrawCallbacks // We inject code in the game engine mixin to prevent the client from doing canvas replacement, // so this should not ever be hit log.warn("Canvas invalidated!"); - shutDown(); - startUp(); + try + { + shutDown(); + startUp(); + } + catch (Exception e) + { + } return; } @@ -1282,8 +1300,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks textureManager.animate(texture, diff); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() != GameState.LOGGED_IN) { 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 4ce28688b9..8314a1493d 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 @@ -67,7 +67,7 @@ import net.runelite.client.Notifier; import net.runelite.client.account.AccountSession; import net.runelite.client.account.SessionManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.game.ItemManager; @@ -150,6 +150,9 @@ public class GrandExchangePlugin extends Plugin @Inject private ConfigManager configManager; + @Inject + private EventBus eventBus; + private Widget grandExchangeText; private Widget grandExchangeItem; private Map itemGELimits; @@ -191,6 +194,7 @@ public class GrandExchangePlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); itemGELimits = loadGELimits(); panel = injector.getInstance(GrandExchangePanel.class); @@ -223,6 +227,8 @@ public class GrandExchangePlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + clientToolbar.removeNavigation(button); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); @@ -232,8 +238,23 @@ public class GrandExchangePlugin extends Plugin grandExchangeClient = null; } - @Subscribe - public void onSessionOpen(SessionOpen sessionOpen) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); + eventBus.subscribe(SessionClose.class, this, this::onSessionClose); + eventBus.subscribe(GrandExchangeOfferChanged.class, this, this::onGrandExchangeOfferChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onSessionOpen(SessionOpen sessionOpen) { AccountSession accountSession = sessionManager.getAccountSession(); if (accountSession.getUuid() != null) @@ -254,14 +275,12 @@ public class GrandExchangePlugin extends Plugin this.enableGELimits = config.enableGELimits(); } - @Subscribe - public void onSessionClose(SessionClose sessionClose) + private void onSessionClose(SessionClose sessionClose) { grandExchangeClient = null; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("grandexchange")) { @@ -282,8 +301,7 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent) + private void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent) { final int slot = offerEvent.getSlot(); final GrandExchangeOffer offer = offerEvent.getOffer(); @@ -360,8 +378,7 @@ public class GrandExchangePlugin extends Plugin return savedOffer.getState() != grandExchangeOffer.getState(); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (!this.enableNotifications || event.getType() != ChatMessageType.GAMEMESSAGE) { @@ -376,8 +393,7 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN) { @@ -385,8 +401,7 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { // At the moment, if the user disables quick lookup, the input listener gets disabled. Thus, isHotKeyPressed() // should always return false when quick lookup is disabled. @@ -419,8 +434,7 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onFocusChanged(FocusChanged focusChanged) + private void onFocusChanged(FocusChanged focusChanged) { if (!focusChanged.isFocused()) { @@ -428,8 +442,7 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { switch (event.getGroupId()) { @@ -447,8 +460,7 @@ public class GrandExchangePlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!event.getEventName().equals("setGETitle") || !config.showTotal()) { @@ -490,8 +502,7 @@ public class GrandExchangePlugin extends Plugin stringStack[stringStackSize - 1] += titleBuilder.toString(); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (grandExchangeText == null || grandExchangeItem == null || grandExchangeItem.isHidden()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java index 1ef158830f..08b063cef5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grotesqueguardians/GrotesqueGuardiansPlugin.java @@ -26,11 +26,11 @@ package net.runelite.client.plugins.grotesqueguardians; import javax.inject.Inject; import javax.inject.Singleton; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.eventbus.Subscribe; import java.util.ArrayList; import net.runelite.api.events.GameTick; import net.runelite.api.NPC; @@ -57,6 +57,8 @@ public class GrotesqueGuardiansPlugin extends Plugin private OverlayManager overlayManager; @Inject private GrotesqueGuardiansPrayerOverlay prayerOverlay; + @Inject + private EventBus eventBus; @Nullable private DuskAttack prayAgainst; @Nullable @@ -76,6 +78,8 @@ public class GrotesqueGuardiansPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + overlayManager.add(overlay); overlayManager.add(prayerOverlay); dusk = null; @@ -85,14 +89,15 @@ public class GrotesqueGuardiansPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(prayerOverlay); dusk = null; prayAgainst = null; } - @Subscribe - public void onGameTick(final GameTick event) + private void onGameTick(final GameTick event) { final ArrayList regions = new ArrayList<>(); for (final int intValue : client.getMapRegions()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index ee7b8d5ed3..28b1674e00 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -74,7 +74,7 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.GameTick; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.NpcLootReceived; import net.runelite.client.events.PlayerLootReceived; import net.runelite.client.game.ItemManager; @@ -128,7 +128,9 @@ public class GroundItemsPlugin extends Plugin private static final int FIFTH_OPTION = MenuAction.GROUND_ITEM_FIFTH_OPTION.getId(); private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId(); private static final int WALK = MenuAction.WALK.getId(); + private static final int CAST_ON_ITEM = MenuAction.SPELL_CAST_ON_GROUND_ITEM.getId(); + private static final String TELEGRAB_TEXT = ColorUtil.wrapWithColorTag("Telekinetic Grab", Color.GREEN) + ColorUtil.prependColorTag(" -> ", Color.WHITE); @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) @@ -180,6 +182,9 @@ public class GroundItemsPlugin extends Plugin @Inject private Notifier notifier; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PUBLIC) public static final Map collectedGroundItems = new LinkedHashMap<>(); private final Map priceChecks = new LinkedHashMap<>(); @@ -247,6 +252,8 @@ public class GroundItemsPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); + overlayManager.add(overlay); reset(); mouseManager.registerMouseListener(inputListener); @@ -256,6 +263,8 @@ public class GroundItemsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); mouseManager.unregisterMouseListener(inputListener); keyManager.unregisterKeyListener(inputListener); @@ -268,8 +277,22 @@ public class GroundItemsPlugin extends Plugin collectedGroundItems.clear(); } - @Subscribe - public void onGameTick(GameTick event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ItemSpawned.class, this, this::onItemSpawned); + eventBus.subscribe(ItemDespawned.class, this, this::onItemDespawned); + eventBus.subscribe(ItemQuantityChanged.class, this, this::onItemQuantityChanged); + eventBus.subscribe(NpcLootReceived.class, this, this::onNpcLootReceived); + eventBus.subscribe(PlayerLootReceived.class, this, this::onPlayerLootReceived); + eventBus.subscribe(ClientTick.class, this, this::onClientTick); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + + private void onGameTick(GameTick event) { for (GroundItem item : collectedGroundItems.values()) { @@ -281,8 +304,7 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("grounditems")) { @@ -291,8 +313,7 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(final GameStateChanged event) + private void onGameStateChanged(final GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { @@ -300,8 +321,7 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onItemSpawned(ItemSpawned itemSpawned) + private void onItemSpawned(ItemSpawned itemSpawned) { Item item = itemSpawned.getItem(); Tile tile = itemSpawned.getTile(); @@ -326,8 +346,7 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onItemDespawned(ItemDespawned itemDespawned) + private void onItemDespawned(ItemDespawned itemDespawned) { Item item = itemDespawned.getItem(); Tile tile = itemDespawned.getTile(); @@ -349,8 +368,7 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) + private void onItemQuantityChanged(ItemQuantityChanged itemQuantityChanged) { Item item = itemQuantityChanged.getItem(); Tile tile = itemQuantityChanged.getTile(); @@ -366,8 +384,7 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onNpcLootReceived(NpcLootReceived npcLootReceived) + private void onNpcLootReceived(NpcLootReceived npcLootReceived) { npcLootReceived.getItems().forEach(item -> { @@ -384,8 +401,7 @@ public class GroundItemsPlugin extends Plugin lootNotifier(items); } - @Subscribe - public void onPlayerLootReceived(PlayerLootReceived playerLootReceived) + private void onPlayerLootReceived(PlayerLootReceived playerLootReceived) { Collection items = playerLootReceived.getItems(); lootReceived(items); @@ -432,8 +448,7 @@ public class GroundItemsPlugin extends Plugin notifier.notify(notification); } - @Subscribe - public void onClientTick(ClientTick event) + private void onClientTick(ClientTick event) { final MenuEntry[] menuEntries = client.getMenuEntries(); final List newEntries = new ArrayList<>(menuEntries.length); @@ -670,13 +685,16 @@ public class GroundItemsPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { - if (this.itemHighlightMode != OVERLAY - && event.getOption().equals("Take") - && event.getType() == THIRD_OPTION) + if (this.itemHighlightMode != OVERLAY) { + final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM; + if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry) + { + return; + } + int itemId = event.getIdentifier(); Scene scene = client.getScene(); Tile tile = scene.getTiles()[client.getPlane()][event.getActionParam0()][event.getActionParam1()]; @@ -720,13 +738,27 @@ public class GroundItemsPlugin extends Plugin if (mode == BOTH || mode == OPTION) { - lastEntry.setOption(ColorUtil.prependColorTag("Take", color)); + final String optionText = telegrabEntry ? "Cast" : "Take"; + lastEntry.setOption(ColorUtil.prependColorTag(optionText, color)); } if (mode == BOTH || mode == NAME) { - String target = lastEntry.getTarget().substring(lastEntry.getTarget().indexOf(">") + 1); - lastEntry.setTarget(ColorUtil.prependColorTag(target, color)); + String target = lastEntry.getTarget(); + + if (telegrabEntry) + { + target = target.substring(TELEGRAB_TEXT.length()); + } + + target = ColorUtil.prependColorTag(target.substring(target.indexOf('>') + 1), color); + + if (telegrabEntry) + { + target = TELEGRAB_TEXT + target; + } + + lastEntry.setTarget(target); } } @@ -905,8 +937,7 @@ public class GroundItemsPlugin extends Plugin return this.defaultColor; } - @Subscribe - public void onFocusChanged(FocusChanged focusChanged) + private void onFocusChanged(FocusChanged focusChanged) { if (!focusChanged.isFocused()) { 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 f5ed119b16..fffc957c4a 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 @@ -58,7 +58,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.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -112,6 +112,9 @@ public class GroundMarkerPlugin extends Plugin @Inject private GroundMarkerMinimapOverlay minimapOverlay; + @Inject + private EventBus eventBus; + @Inject private KeyManager keyManager; @@ -272,8 +275,7 @@ public class GroundMarkerPlugin extends Plugin return point; } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() != GameState.LOGGED_IN) { @@ -284,8 +286,7 @@ public class GroundMarkerPlugin extends Plugin loadPoints(); } - @Subscribe - public void onFocusChanged(FocusChanged focusChanged) + private void onFocusChanged(FocusChanged focusChanged) { if (!focusChanged.isFocused()) { @@ -293,8 +294,7 @@ public class GroundMarkerPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (hotKeyPressed && event.getOption().equals(WALK_HERE)) { @@ -328,8 +328,7 @@ public class GroundMarkerPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (!event.getOption().contains(MARK) && !event.getOption().contains(UNMARK)) { @@ -356,6 +355,7 @@ public class GroundMarkerPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(minimapOverlay); @@ -366,12 +366,22 @@ public class GroundMarkerPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); overlayManager.remove(overlay); overlayManager.remove(minimapOverlay); keyManager.unregisterKeyListener(inputListener); points.clear(); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + } + private void markTile(LocalPoint localPoint, int group) { if (localPoint == null) @@ -424,8 +434,7 @@ public class GroundMarkerPlugin extends Plugin return color; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("groundMarker")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/herbiboars/HerbiboarPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/herbiboars/HerbiboarPlugin.java index cc6dc7258d..118e9c1faa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/herbiboars/HerbiboarPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/herbiboars/HerbiboarPlugin.java @@ -57,7 +57,7 @@ import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.VarbitChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -112,6 +112,9 @@ public class HerbiboarPlugin extends Plugin @Inject private HerbiboarConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean inHerbiboarArea; @@ -172,6 +175,7 @@ public class HerbiboarPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(minimapOverlay); @@ -181,10 +185,25 @@ public class HerbiboarPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(minimapOverlay); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(GroundObjectChanged.class, this, this::onGroundObjectChanged); + eventBus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned); + } + private void updateTrailData() { currentTrail = null; @@ -241,8 +260,7 @@ public class HerbiboarPlugin extends Plugin tunnels.clear(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -259,8 +277,7 @@ public class HerbiboarPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { if (isInHerbiboarArea()) { @@ -268,38 +285,32 @@ public class HerbiboarPlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { onGameObject(event.getTile(), null, event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { onGameObject(event.getTile(), event.getPrevious(), event.getGameObject()); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { onGameObject(event.getTile(), event.getGameObject(), null); } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { onGroundObject( null, event.getGroundObject()); } - @Subscribe - public void onGroundObjectChanged(GroundObjectChanged event) + private void onGroundObjectChanged(GroundObjectChanged event) { onGroundObject(event.getPrevious(), event.getGroundObject()); } - @Subscribe - public void onGroundObjectDespawned(GroundObjectDespawned event) + private void onGroundObjectDespawned(GroundObjectDespawned event) { onGroundObject(event.getGroundObject(), null); } @@ -382,8 +393,7 @@ public class HerbiboarPlugin extends Plugin return END_LOCATIONS; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("herbiboar")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java index 0fb87507c7..75385bfa4b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hideprayers/HidePrayersPlugin.java @@ -47,7 +47,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -109,6 +109,9 @@ public class HidePrayersPlugin extends Plugin @Inject private HidePrayersConfig config; + @Inject + private EventBus eventBus; + private boolean showindividualprayers; private boolean ShowTHICK_SKIN; private boolean ShowBURST_OF_STRENGTH; @@ -169,17 +172,27 @@ public class HidePrayersPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + hidePrayers(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + restorePrayers(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -188,8 +201,7 @@ public class HidePrayersPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("hideprayers")) { @@ -198,8 +210,7 @@ public class HidePrayersPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/highalchemy/HighAlchemyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/highalchemy/HighAlchemyPlugin.java index 79be6bbac4..38a6ae8ea8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/highalchemy/HighAlchemyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/highalchemy/HighAlchemyPlugin.java @@ -46,7 +46,7 @@ import static net.runelite.api.widgets.WidgetID.GUIDE_PRICES_INVENTORY_GROUP_ID; import static net.runelite.api.widgets.WidgetID.INVENTORY_GROUP_ID; import static net.runelite.api.widgets.WidgetID.SHOP_INVENTORY_GROUP_ID; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -76,6 +76,9 @@ public class HighAlchemyPlugin extends Plugin @Inject private HighAlchemyOverlay overlay; + @Inject + private EventBus eventBus; + @Provides HighAlchemyConfig getConfig(ConfigManager configManager) { @@ -95,6 +98,8 @@ public class HighAlchemyPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + buildGroupList(); overlayManager.add(overlay); } @@ -105,8 +110,7 @@ public class HighAlchemyPlugin extends Plugin overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals(CONFIG_GROUP)) { 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 a90ca7b8ba..cf21d1f2d7 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 @@ -47,7 +47,7 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -87,6 +87,9 @@ public class HiscorePlugin extends Plugin @Inject private HiscoreConfig config; + @Inject + private EventBus eventBus; + private NavigationButton navButton; private HiscorePanel hiscorePanel; @@ -102,6 +105,8 @@ public class HiscorePlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + hiscorePanel = injector.getInstance(HiscorePanel.class); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "normal.png"); @@ -128,6 +133,8 @@ public class HiscorePlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + hiscorePanel.removeInputKeyListener(autocompleter); clientToolbar.removeNavigation(navButton); @@ -137,8 +144,15 @@ public class HiscorePlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(PlayerMenuOptionClicked.class, this, this::onPlayerMenuOptionClicked); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("hiscore")) { @@ -166,8 +180,7 @@ public class HiscorePlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!config.menuOption()) { @@ -201,8 +214,7 @@ public class HiscorePlugin extends Plugin } } - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + private void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { if (event.getMenuOption().equals(LOOKUP)) { @@ -210,8 +222,7 @@ public class HiscorePlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (!config.bountylookup() || !event.getType().equals(ChatMessageType.GAMEMESSAGE)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java index 8601a91289..8d8437ec71 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hunter/HunterPlugin.java @@ -48,7 +48,7 @@ import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameTick; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -77,6 +77,9 @@ public class HunterPlugin extends Plugin @Inject private HunterConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final Map traps = new HashMap<>(); @@ -105,6 +108,7 @@ public class HunterPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlay.updateConfig(); @@ -113,13 +117,21 @@ public class HunterPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); lastActionTime = Instant.ofEpochMilli(0); traps.clear(); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + } + + private void onGameObjectSpawned(GameObjectSpawned event) { final GameObject gameObject = event.getGameObject(); final WorldPoint trapLocation = gameObject.getWorldLocation(); @@ -309,8 +321,7 @@ public class HunterPlugin extends Plugin * checks if the trap is still there. If the trap is gone, it removes * the trap from the local players trap collection. */ - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { // Check if all traps are still there, and remove the ones that are not. Iterator> it = traps.entrySet().iterator(); @@ -387,8 +398,7 @@ public class HunterPlugin extends Plugin lastTickLocalPlayerLocation = client.getLocalPlayer().getWorldLocation(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("hunterplugin")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/BabyHydraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/BabyHydraPlugin.java index 8c2f0fff42..10deba1016 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hydra/BabyHydraPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hydra/BabyHydraPlugin.java @@ -39,7 +39,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -73,6 +73,9 @@ public class BabyHydraPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + @Provides BabyHydraConfig provideConfig(ConfigManager configManager) { @@ -97,6 +100,7 @@ public class BabyHydraPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); if (this.TextIndicator) { @@ -112,6 +116,8 @@ public class BabyHydraPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(hydraOverlay); overlayManager.remove(hydraPrayOverlay); overlayManager.remove(hydraIndicatorOverlay); @@ -119,8 +125,15 @@ public class BabyHydraPlugin extends Plugin hydraattacks.clear(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("hydra")) { @@ -155,8 +168,7 @@ public class BabyHydraPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { NPC hydra = event.getNpc(); if (hydra.getCombatLevel() != 0 && hydra.getName() != null && hydra.getName().equalsIgnoreCase("Hydra") && !hydras.containsKey(hydra.getIndex())) @@ -165,8 +177,7 @@ public class BabyHydraPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { NPC hydra = event.getNpc(); if (hydra.getCombatLevel() != 0 && hydra.getName() != null && hydra.getName().equalsIgnoreCase("Hydra")) @@ -176,8 +187,7 @@ public class BabyHydraPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { Actor monster = event.getActor(); Actor local = client.getLocalPlayer(); 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 f8ad288e45..6e5a9f6974 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 @@ -32,10 +32,10 @@ import net.runelite.client.config.ConfigItem; public interface IdleNotifierConfig extends Config { @ConfigItem( - keyName = "animationidle", - name = "Idle Animation Notifications", - description = "Configures if idle animation notifications are enabled", - position = 1 + keyName = "animationidle", + name = "Idle Animation Notifications", + description = "Configures if idle animation notifications are enabled", + position = 1 ) default boolean animationIdle() { @@ -43,21 +43,32 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "animationidlesound", - name = "Idle Animation Sound", - description = "Plays a custom sound accompanying Idle Animation notifications", - position = 2 + keyName = "outOfItemsIdle", + name = "Out of Items Idle Notifications", + position = 2, + description = "Configures if notifications for running out of items for another action are enabled." ) - default boolean animationIdleSound() + default boolean outOfItemsIdle() + { + return true; + } + + @ConfigItem( + keyName = "animationidlesound", + name = "Idle Animation Sound", + description = "Plays a custom sound accompanying Idle Animation notifications", + position = 3 + ) + default boolean animationIdleSound() { return false; } @ConfigItem( - keyName = "interactionidle", - name = "Idle Interaction Notifications", - description = "Configures if idle interaction notifications are enabled e.g. combat, fishing", - position = 3 + keyName = "interactionidle", + name = "Idle Interaction Notifications", + description = "Configures if idle interaction notifications are enabled e.g. combat, fishing", + position = 4 ) default boolean interactionIdle() { @@ -65,21 +76,21 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "interactionidlesound", - name = "Idle Interaction Sound", - description = "Plays a custom sound accompanying Idle Interaction notifications", - position = 4 + keyName = "interactionidlesound", + name = "Idle Interaction Sound", + description = "Plays a custom sound accompanying Idle Interaction notifications", + position = 5 ) - default boolean interactionIdleSound() + default boolean interactionIdleSound() { return false; } @ConfigItem( - keyName = "logoutidle", - name = "Idle Logout Notifications", - description = "Configures if the idle logout notifications are enabled", - position = 5 + keyName = "logoutidle", + name = "Idle Logout Notifications", + description = "Configures if the idle logout notifications are enabled", + position = 6 ) default boolean logoutIdle() { @@ -87,21 +98,21 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "outofcombatsound", - name = "Out of Combat Sound", - description = "Plays a custom sound whenever you leave combat", - position = 6 + keyName = "outofcombatsound", + name = "Out of Combat Sound", + description = "Plays a custom sound whenever you leave combat", + position = 7 ) - default boolean outOfCombatSound() + default boolean outOfCombatSound() { return false; } @ConfigItem( - position = 7, - keyName = "skullNotification", - name = "Skull Notification", - description = "Receive a notification when you skull." + position = 8, + keyName = "skullNotification", + name = "Skull Notification", + description = "Receive a notification when you skull." ) default boolean showSkullNotification() { @@ -109,10 +120,10 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - position = 8, - keyName = "unskullNotification", - name = "Unskull Notification", - description = "Receive a notification when you unskull." + position = 9, + keyName = "unskullNotification", + name = "Unskull Notification", + description = "Receive a notification when you unskull." ) default boolean showUnskullNotification() { @@ -120,10 +131,10 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "timeout", - name = "Idle Notification Delay (ms)", - description = "The notification delay after the player is idle", - position = 9 + keyName = "timeout", + name = "Idle Notification Delay (ms)", + description = "The notification delay after the player is idle", + position = 10 ) default int getIdleNotificationDelay() { @@ -131,10 +142,10 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "hitpoints", - name = "Hitpoints Notification Threshold", - description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.", - position = 10 + keyName = "hitpoints", + name = "Hitpoints Notification Threshold", + description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.", + position = 11 ) default int getHitpointsThreshold() { @@ -142,21 +153,21 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "playHealthSound", - name = "Play sound for Low Health", - description = "Will play a sound for every Low Health notification sent", - position = 12 + keyName = "playHealthSound", + name = "Play sound for Low Health", + description = "Will play a sound for every Low Health notification sent", + position = 12 ) - default boolean getPlayHealthSound() + default boolean getPlayHealthSound() { return false; } @ConfigItem( - keyName = "prayer", - name = "Prayer Notification Threshold", - description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.", - position = 12 + keyName = "prayer", + name = "Prayer Notification Threshold", + description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.", + position = 13 ) default int getPrayerThreshold() { @@ -164,21 +175,21 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "playPrayerSound", - name = "Play sound for Low Prayer", - description = "Will play a sound for every Low Prayer notification sent", - position = 13 + keyName = "playPrayerSound", + name = "Play sound for Low Prayer", + description = "Will play a sound for every Low Prayer notification sent", + position = 14 ) - default boolean getPlayPrayerSound() + default boolean getPlayPrayerSound() { return false; } @ConfigItem( - keyName = "oxygen", - name = "Oxygen Notification Threshold", - position = 14, - description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification." + keyName = "oxygen", + name = "Oxygen Notification Threshold", + position = 15, + description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification." ) default int getOxygenThreshold() { @@ -186,10 +197,10 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "spec", - name = "Special Attack Energy Notification Threshold", - position = 15, - description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification." + keyName = "spec", + name = "Special Attack Energy Notification Threshold", + position = 16, + description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification." ) default int getSpecEnergyThreshold() { @@ -197,34 +208,34 @@ public interface IdleNotifierConfig extends Config } @ConfigItem( - keyName = "specSound", - name = "Special Attack Energy Sound", - description = "Plays a custom sound accompanying Special Attack energy notifications", - position = 16 + keyName = "specSound", + name = "Special Attack Energy Sound", + description = "Plays a custom sound accompanying Special Attack energy notifications", + position = 17 ) - default boolean getSpecSound() + default boolean getSpecSound() { return false; } @ConfigItem( - keyName = "overspec", - name = "Over Special Energy Notification", - description = "Will repeat notifications for any value over the special energy threshold", - position = 17 + keyName = "overspec", + name = "Over Special Energy Notification", + description = "Will repeat notifications for any value over the special energy threshold", + position = 18 ) - default boolean getOverSpecEnergy() + default boolean getOverSpecEnergy() { return false; } @ConfigItem( - keyName = "pkers", - name = "PKer Notifier", - position = 18, - description = "Notifies if an attackable player based on your level range appears on screen.", - group = "PvP", - warning = "This will not notify you if the player is in your cc or is online on your friends list." + keyName = "pkers", + name = "PKer Notifier", + position = 19, + description = "Notifies if an attackable player based on your level range appears on screen.", + group = "PvP", + warning = "This will not notify you if the player is in your cc or is online on your friends list." ) default boolean notifyPkers() { 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 3d84a2f099..57f2bbab2f 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 @@ -29,6 +29,7 @@ import com.google.inject.Provides; import java.awt.TrayIcon; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.List; @@ -44,6 +45,9 @@ import net.runelite.api.Constants; import net.runelite.api.GameState; import net.runelite.api.GraphicID; import net.runelite.api.Hitsplat; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; import net.runelite.api.NPC; import net.runelite.api.NPCDefinition; import net.runelite.api.Player; @@ -58,11 +62,12 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.HitsplatApplied; import net.runelite.api.events.InteractingChanged; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.PlayerSpawned; import net.runelite.api.events.SpotAnimationChanged; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.Sound; import net.runelite.client.game.SoundManager; import net.runelite.client.plugins.Plugin; @@ -104,6 +109,9 @@ public class IdleNotifierPlugin extends Plugin @Inject private IdleNotifierConfig config; + @Inject + private EventBus eventBus; + private Instant lastAnimating; private int lastAnimation = AnimationID.IDLE; private Instant lastInteracting; @@ -117,7 +125,12 @@ public class IdleNotifierPlugin extends Plugin private int lastCombatCountdown = 0; private Instant sixHourWarningTime; private boolean ready; + private Instant lastTimeItemsUsedUp; + private List itemIdsPrevious = new ArrayList<>(); + private List itemQuantitiesPrevious = new ArrayList<>(); + private final List itemQuantitiesChange = new ArrayList<>(); private boolean lastInteractWasCombat; + private boolean interactingNotified; private SkullIcon lastTickSkull = null; private boolean isFirstTick = true; @@ -146,6 +159,7 @@ public class IdleNotifierPlugin extends Plugin private boolean getSpecSound; private boolean getOverSpecEnergy; private boolean notifyPkers; + private boolean outOfItemsIdle; @Provides IdleNotifierConfig provideConfig(ConfigManager configManager) @@ -153,8 +167,7 @@ public class IdleNotifierPlugin extends Plugin return configManager.getConfig(IdleNotifierConfig.class); } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + void onAnimationChanged(AnimationChanged event) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -222,6 +235,17 @@ public class IdleNotifierPlugin extends Plugin /* Fishing */ case FISHING_CRUSHING_INFERNAL_EELS: case FISHING_CUTTING_SACRED_EELS: + case FISHING_BIG_NET: + case FISHING_NET: + case FISHING_POLE_CAST: + case FISHING_CAGE: + case FISHING_HARPOON: + case FISHING_BARBTAIL_HARPOON: + case FISHING_DRAGON_HARPOON: + case FISHING_INFERNAL_HARPOON: + case FISHING_OILY_ROD: + case FISHING_KARAMBWAN: + case FISHING_BAREHAND: /* Mining(Normal) */ case MINING_BRONZE_PICKAXE: case MINING_IRON_PICKAXE: @@ -236,7 +260,7 @@ public class IdleNotifierPlugin extends Plugin case MINING_3A_PICKAXE: case DENSE_ESSENCE_CHIPPING: case DENSE_ESSENCE_CHISELING: - /* Herblore */ + /* Herblore */ case HERBLORE_PESTLE_AND_MORTAR: case HERBLORE_POTIONMAKING: case HERBLORE_MAKE_TAR: @@ -258,13 +282,14 @@ public class IdleNotifierPlugin extends Plugin case FARMING_HARVEST_FRUIT_TREE: case FARMING_HARVEST_FLOWER: case FARMING_HARVEST_ALLOTMENT: - /* Misc */ + /* Misc */ case PISCARILIUS_CRANE_REPAIR: case HOME_MAKE_TABLET: case SAND_COLLECTION: resetTimers(); lastAnimation = animation; lastAnimating = Instant.now(); + interactingNotified = false; break; case MAGIC_LUNAR_SHARED: if (graphic == GraphicID.BAKE_PIE) @@ -272,10 +297,12 @@ public class IdleNotifierPlugin extends Plugin resetTimers(); lastAnimation = animation; lastAnimating = Instant.now(); + interactingNotified = false; break; } case IDLE: lastAnimating = Instant.now(); + interactingNotified = false; break; default: // On unknown animation simply assume the animation is invalid and dont throw notification @@ -284,7 +311,6 @@ public class IdleNotifierPlugin extends Plugin } } - @Subscribe private void onPlayerSpawned(PlayerSpawned event) { final Player p = event.getPlayer(); @@ -299,8 +325,84 @@ public class IdleNotifierPlugin extends Plugin } } - @Subscribe - public void onInteractingChanged(InteractingChanged event) + private void onItemContainerChanged(ItemContainerChanged event) + { + ItemContainer itemContainer = event.getItemContainer(); + + if (itemContainer != client.getItemContainer(InventoryID.INVENTORY) || !config.outOfItemsIdle()) + { + return; + } + + Item[] items = itemContainer.getItems(); + ArrayList itemQuantities = new ArrayList<>(); + ArrayList itemIds = new ArrayList<>(); + + // Populate list of items in inventory without duplicates + for (Item value : items) + { + int itemId = OutOfItemsMapping.mapFirst(value.getId()); + if (itemIds.indexOf(itemId) == -1) // -1 if item not yet in list + { + itemIds.add(itemId); + } + } + + // Populate quantity of each item in inventory + for (int j = 0; j < itemIds.size(); j++) + { + itemQuantities.add(0); + for (Item item : items) + { + if (itemIds.get(j) == OutOfItemsMapping.mapFirst(item.getId())) + { + itemQuantities.set(j, itemQuantities.get(j) + item.getQuantity()); + } + } + } + + itemQuantitiesChange.clear(); + + // Calculate the quantity of each item consumed by the last action + if (!itemIdsPrevious.isEmpty()) + { + for (int i = 0; i < itemIdsPrevious.size(); i++) + { + int id = itemIdsPrevious.get(i); + int currentIndex = itemIds.indexOf(id); + int currentQuantity; + if (currentIndex != -1) // -1 if item is no longer in inventory + { + currentQuantity = itemQuantities.get(currentIndex); + } + else + { + currentQuantity = 0; + } + itemQuantitiesChange.add(currentQuantity - itemQuantitiesPrevious.get(i)); + } + } + else + { + itemIdsPrevious = itemIds; + itemQuantitiesPrevious = itemQuantities; + return; + } + + // Check we have enough items left for another action. + for (int i = 0; i < itemQuantitiesPrevious.size(); i++) + { + if (-itemQuantitiesChange.get(i) * 2 > itemQuantitiesPrevious.get(i)) + { + lastTimeItemsUsedUp = Instant.now(); + return; + } + } + itemIdsPrevious = itemIds; + itemQuantitiesPrevious = itemQuantities; + } + + void onInteractingChanged(InteractingChanged event) { final Actor source = event.getSource(); if (source != client.getLocalPlayer()) @@ -350,8 +452,7 @@ public class IdleNotifierPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + void onGameStateChanged(GameStateChanged gameStateChanged) { lastInteracting = null; @@ -383,8 +484,7 @@ public class IdleNotifierPlugin extends Plugin } } - @Subscribe - public void onHitsplatApplied(HitsplatApplied event) + void onHitsplatApplied(HitsplatApplied event) { if (event.getActor() != client.getLocalPlayer()) { @@ -400,8 +500,7 @@ public class IdleNotifierPlugin extends Plugin } } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged event) + private void onSpotAnimationChanged(SpotAnimationChanged event) { Actor actor = event.getActor(); @@ -416,8 +515,7 @@ public class IdleNotifierPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + void onGameTick(GameTick event) { skullNotifier(); @@ -432,6 +530,7 @@ public class IdleNotifierPlugin extends Plugin || client.getKeyboardIdleTicks() < 10) { resetTimers(); + resetOutOfItemsIdleChecks(); return; } @@ -445,14 +544,13 @@ public class IdleNotifierPlugin extends Plugin notifier.notify("[" + local.getName() + "] is about to log out from being online for 6 hours!"); } - if (this.animationIdle && checkAnimationIdle(waitDuration, local)) + if (this.outOfItemsIdle && checkOutOfItemsIdle(waitDuration)) { - notifier.notify("[" + local.getName() + "] is now idle!"); - if (this.animationIdleSound) - { - soundManager.playSound(Sound.IDLE); - } + notifier.notify("[" + local.getName() + "] has run out of items!"); + // If this triggers, don't also trigger animation idle notification afterwards. + lastAnimation = IDLE; } + if (this.interactionIdle && checkInteractionIdle(waitDuration, local)) { if (lastInteractWasCombat) @@ -471,6 +569,16 @@ public class IdleNotifierPlugin extends Plugin soundManager.playSound(Sound.IDLE); } } + interactingNotified = true; + } + + if (this.animationIdle && checkAnimationIdle(waitDuration, local)) + { + notifier.notify("[" + local.getName() + "] is now idle!"); + if (this.animationIdleSound) + { + soundManager.playSound(Sound.IDLE); + } } if (checkLowHitpoints()) @@ -689,7 +797,7 @@ public class IdleNotifierPlugin extends Plugin private boolean checkAnimationIdle(Duration waitDuration, Player local) { - if (lastAnimation == IDLE) + if (lastAnimation == IDLE || interactingNotified) { return false; } @@ -713,6 +821,23 @@ public class IdleNotifierPlugin extends Plugin return false; } + private boolean checkOutOfItemsIdle(Duration waitDuration) + { + if (lastTimeItemsUsedUp == null) + { + return false; + } + + if (Instant.now().compareTo(lastTimeItemsUsedUp.plus(waitDuration)) >= 0) + { + resetTimers(); + resetOutOfItemsIdleChecks(); + return true; + } + + return false; + } + private void resetTimers() { final Player local = client.getLocalPlayer(); @@ -732,6 +857,14 @@ public class IdleNotifierPlugin extends Plugin } } + private void resetOutOfItemsIdleChecks() + { + lastTimeItemsUsedUp = null; + itemQuantitiesChange.clear(); + itemIdsPrevious.clear(); + itemQuantitiesPrevious.clear(); + } + private void skullNotifier() { final Player local = client.getLocalPlayer(); @@ -765,8 +898,26 @@ public class IdleNotifierPlugin extends Plugin updateConfig(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("idlenotifier")) { @@ -796,5 +947,6 @@ public class IdleNotifierPlugin extends Plugin this.getSpecSound = config.getSpecSound(); this.getOverSpecEnergy = config.getOverSpecEnergy(); this.notifyPkers = config.notifyPkers(); + this.outOfItemsIdle = config.outOfItemsIdle(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/OutOfItemsMapping.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/OutOfItemsMapping.java new file mode 100644 index 0000000000..10738f1273 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/OutOfItemsMapping.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019, Twiglet1022 + * 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.idlenotifier; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import java.util.Collection; +import static net.runelite.api.ItemID.*; + +public enum OutOfItemsMapping +{ + AERIAL_FISHING_CUTTING(BLUEGILL, COMMON_TENCH, MOTTLED_EEL, GREATER_SIREN); + + private static final Multimap MAPPINGS = HashMultimap.create(); + private final int groupedItemKey; + private final int[] groupedItemIDs; + + static + { + for (final OutOfItemsMapping item : values()) + { + for (int itemId : item.groupedItemIDs) + { + MAPPINGS.put(itemId, item.groupedItemKey); + } + } + } + + OutOfItemsMapping(int groupedItemKey, int... groupedItemIDs) + { + this.groupedItemKey = groupedItemKey; + this.groupedItemIDs = groupedItemIDs; + } + + /** + * Some actions consume multiple different items. To properly handle these + * cases for the out of items notification the different items must be + * recognised as belonging to a single group. + * + * Map an item that is part of a group of items that are consumed by a single + * action to the first item in that group. + */ + public static int mapFirst(int itemId) + { + final Collection mapping = MAPPINGS.get(itemId); + + if (mapping == null || mapping.isEmpty()) + { + return itemId; + } + + return mapping.iterator().next(); + } + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java index 8458b45735..d005a30af3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/implings/ImplingsPlugin.java @@ -39,21 +39,19 @@ import net.runelite.api.NPC; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.NpcDefinitionChanged; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -/** - * @author robin - */ @PluginDescriptor( name = "Implings", description = "Highlight nearby implings on the minimap and on-screen", - tags = {"hunter", "minimap", "overlay"} + tags = {"hunter", "minimap", "overlay", "imp"} ) @Singleton public class ImplingsPlugin extends Plugin @@ -77,7 +75,6 @@ public class ImplingsPlugin extends Plugin @Inject private ImplingCounterOverlay implingCounterOverlay; - @Inject private OverlayManager overlayManager; @@ -87,6 +84,9 @@ public class ImplingsPlugin extends Plugin @Inject private ImplingsConfig config; + @Inject + private EventBus eventBus; + private boolean showBaby; private Color getBabyColor; private boolean showYoung; @@ -125,9 +125,10 @@ public class ImplingsPlugin extends Plugin } @Override - protected void startUp() throws Exception + protected void startUp() { updateConfig(); + addSubscriptions(); dynamicSpawns.put(DYNAMIC_SPAWN_NATURE_DRAGON, "T3 Nature-Lucky Dynamic"); dynamicSpawns.put(DYNAMIC_SPAWN_ECLECTIC, "T2 Eclectic Dynamic"); @@ -139,15 +140,27 @@ public class ImplingsPlugin extends Plugin } @Override - protected void shutDown() throws Exception + protected void shutDown() { + eventBus.unregister(this); + + implings.clear(); overlayManager.remove(overlay); overlayManager.remove(minimapOverlay); overlayManager.remove(implingCounterOverlay); } - @Subscribe - public void onGameTick(GameTick event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged); + } + + private void onGameTick(GameTick event) { implingCounterMap.clear(); for (NPC npc : implings) @@ -171,8 +184,7 @@ public class ImplingsPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) + private void onNpcSpawned(NpcSpawned npcSpawned) { NPC npc = npcSpawned.getNpc(); Impling impling = Impling.findImpling(npc.getId()); @@ -183,8 +195,18 @@ public class ImplingsPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onNpcDefinitionChanged(NpcDefinitionChanged npcCompositionChanged) + { + NPC npc = npcCompositionChanged.getNpc(); + Impling impling = Impling.findImpling(npc.getId()); + + if (impling != null && !implings.contains(npc)) + { + implings.add(npc); + } + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING) { @@ -193,8 +215,7 @@ public class ImplingsPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { if (implings.isEmpty()) { @@ -291,8 +312,7 @@ public class ImplingsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("implings")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inferno/InfernoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inferno/InfernoPlugin.java index 9230985b1b..0fc2fc89ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inferno/InfernoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inferno/InfernoPlugin.java @@ -51,7 +51,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -94,6 +94,9 @@ public class InfernoPlugin extends Plugin @Inject private InfernoConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private int currentWave = -1; @@ -143,6 +146,8 @@ public class InfernoPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + waveOverlay.setDisplayMode(this.waveDisplay); if (isInInferno()) @@ -177,6 +182,8 @@ public class InfernoPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(infernoInfobox); overlayManager.remove(infernoOverlay); overlayManager.remove(nibblerOverlay); @@ -188,7 +195,17 @@ public class InfernoPlugin extends Plugin currentWaveNumber = -1; } - @Subscribe + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + } + private void onConfigChanged(ConfigChanged event) { if (!"inferno".equals(event.getGroup())) @@ -216,8 +233,7 @@ public class InfernoPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { if (client.getMapRegions()[0] != 9043) { @@ -251,8 +267,7 @@ public class InfernoPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (client.getMapRegions()[0] != 9043) { @@ -283,8 +298,7 @@ public class InfernoPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() != GameState.LOGGED_IN) { @@ -316,8 +330,7 @@ public class InfernoPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (!isInInferno() || event.getType() != ChatMessageType.GAMEMESSAGE) { @@ -333,8 +346,7 @@ public class InfernoPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (client.getMapRegions()[0] != 9043) { @@ -403,8 +415,7 @@ public class InfernoPlugin extends Plugin calculatePriorityNPC(); } - @Subscribe - public void onAnimationChanged(final AnimationChanged event) + private void onAnimationChanged(final AnimationChanged event) { if (event.getActor() != jad) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index 9227aba3af..0e9700812b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -53,7 +53,6 @@ import net.runelite.client.RuneLiteProperties; import net.runelite.client.account.SessionManager; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.ui.ColorScheme; @@ -187,7 +186,7 @@ public class InfoPanel extends PluginPanel add(actionsContainer, BorderLayout.CENTER); updateLoggedIn(); - eventBus.register(this); + // eventBus.register(this); } /** @@ -316,13 +315,11 @@ public class InfoPanel extends PluginPanel return "" + key + "" + value + ""; } - @Subscribe public void onSessionOpen(SessionOpen sessionOpen) { updateLoggedIn(); } - @Subscribe public void onSessionClose(SessionClose e) { updateLoggedIn(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java index 1578ee408b..79fd350150 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java @@ -27,6 +27,9 @@ package net.runelite.client.plugins.info; import java.awt.image.BufferedImage; import javax.inject.Inject; import javax.inject.Singleton; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.events.SessionClose; +import net.runelite.client.events.SessionOpen; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; @@ -44,12 +47,18 @@ public class InfoPlugin extends Plugin @Inject private ClientToolbar clientToolbar; + @Inject + private EventBus eventbus; + private NavigationButton navButton; + + private InfoPanel panel; + @Override protected void startUp() throws Exception { - final InfoPanel panel = injector.getInstance(InfoPanel.class); + panel = injector.getInstance(InfoPanel.class); panel.init(); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "info_icon.png"); @@ -62,11 +71,21 @@ public class InfoPlugin extends Plugin .build(); clientToolbar.addNavigation(navButton); + + addSubscriptions(); } @Override - protected void shutDown() + protected void shutDown() throws Exception { + eventbus.unregister(this); + clientToolbar.removeNavigation(navButton); } + + private void addSubscriptions() + { + eventbus.subscribe(SessionOpen.class, this, event -> panel.onSessionOpen(event)); + eventbus.subscribe(SessionClose.class, this, event -> panel.onSessionClose(event)); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapOverlay.java index 2ef28d51b1..0db24547e1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapOverlay.java @@ -29,6 +29,7 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.image.BufferedImage; +import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; @@ -88,8 +89,10 @@ class InstanceMapOverlay extends Overlay @Setter(AccessLevel.PACKAGE) private boolean isCloseButtonHovered; - @Getter(AccessLevel.PACKAGE) + + @Getter private Rectangle closeButtonBounds; + private BufferedImage closeButtonImage; private BufferedImage closeButtonHoveredImage; @@ -167,8 +170,6 @@ class InstanceMapOverlay extends Overlay if (image == null) { - BufferedImage closeButton = getCloseButtonImage(); - Sprite map = client.drawInstanceMap(viewedPlane); image = minimapToBufferedImage(map); synchronized (this) @@ -178,7 +179,12 @@ class InstanceMapOverlay extends Overlay mapImage = image; } } + } + BufferedImage closeButton = getCloseButtonImage(); + BufferedImage closeButtonHover = getCloseButtonHoveredImage(); + if (closeButton != null && closeButtonBounds == null) + { closeButtonBounds = new Rectangle(image.getWidth() - closeButton.getWidth() - 5, 6, closeButton.getWidth(), closeButton.getHeight()); } @@ -192,8 +198,15 @@ class InstanceMapOverlay extends Overlay drawPlayerDot(graphics, client.getLocalPlayer(), Color.white, Color.black); } - graphics.drawImage(isCloseButtonHovered ? getCloseButtonHoveredImage() : getCloseButtonImage(), - (int) closeButtonBounds.getX(), (int) closeButtonBounds.getY(), null); + if (isCloseButtonHovered) + { + closeButton = closeButtonHover; + } + + if (closeButton != null) + { + graphics.drawImage(closeButton, (int) closeButtonBounds.getX(), (int) closeButtonBounds.getY(), null); + } return new Dimension(image.getWidth(), image.getHeight()); } @@ -253,6 +266,7 @@ class InstanceMapOverlay extends Overlay return img; } + @Nullable private BufferedImage getCloseButtonImage() { if (closeButtonImage == null) @@ -262,6 +276,7 @@ class InstanceMapOverlay extends Overlay return closeButtonImage; } + @Nullable private BufferedImage getCloseButtonHoveredImage() { if (closeButtonHoveredImage == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java index d6f4cb3e17..8110db2eb3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/instancemap/InstanceMapPlugin.java @@ -31,7 +31,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_OPTION; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseManager; import net.runelite.client.menus.MenuManager; @@ -67,6 +67,9 @@ public class InstanceMapPlugin extends Plugin @Inject private MouseManager mouseManager; + @Inject + private EventBus eventBus; + @Override public void configure(Binder binder) { @@ -86,6 +89,8 @@ public class InstanceMapPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + overlayManager.add(overlay); addCustomOptions(); keyManager.registerKeyListener(inputListener); @@ -96,6 +101,8 @@ public class InstanceMapPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlay.setShowMap(false); overlayManager.remove(overlay); removeCustomOptions(); @@ -104,8 +111,13 @@ public class InstanceMapPlugin extends Plugin mouseManager.unregisterMouseWheelListener(inputListener); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetMenuOptionClicked.class, this, this::onWidgetMenuOptionClicked); + } + + private void onGameStateChanged(GameStateChanged event) { overlay.onGameStateChange(event); } @@ -115,8 +127,7 @@ public class InstanceMapPlugin extends Plugin return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget()); } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + private void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) { if (event.getWidget() != WORLD_MAP_OPTION) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java index 9758434681..809169da28 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -73,6 +73,9 @@ public class InterfaceStylesPlugin extends Plugin @Inject private SpriteManager spriteManager; + @Inject + private EventBus eventBus; + private Sprite[] defaultCrossSprites; private Skin skin; @@ -90,12 +93,15 @@ public class InterfaceStylesPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); clientThread.invoke(this::updateAllOverrides); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + clientThread.invoke(() -> { restoreWidgetDimensions(); @@ -105,8 +111,16 @@ public class InterfaceStylesPlugin extends Plugin }); } - @Subscribe - public void onConfigChanged(ConfigChanged config) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetPositioned.class, this, this::onWidgetPositioned); + eventBus.subscribe(PostHealthBar.class, this, this::onPostHealthBar); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(BeforeMenuRender.class, this, this::onBeforeMenuRender); + } + + private void onConfigChanged(ConfigChanged config) { if (config.getGroup().equals("interfaceStyles")) { @@ -115,14 +129,12 @@ public class InterfaceStylesPlugin extends Plugin } } - @Subscribe - public void onWidgetPositioned(WidgetPositioned widgetPositioned) + private void onWidgetPositioned(WidgetPositioned widgetPositioned) { adjustWidgetDimensions(); } - @Subscribe - public void onPostHealthBar(PostHealthBar postHealthBar) + private void onPostHealthBar(PostHealthBar postHealthBar) { if (!this.hdHealthBars) { @@ -140,8 +152,7 @@ public class InterfaceStylesPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() != GameState.LOGIN_SCREEN) { @@ -167,8 +178,7 @@ public class InterfaceStylesPlugin extends Plugin overrideCrossSprites(); } - @Subscribe - public void onBeforeMenuRender(BeforeMenuRender event) + private void onBeforeMenuRender(BeforeMenuRender event) { if (this.hdMenu) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOffset.java b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOffset.java index 920aa0a818..0d5b7ea54e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOffset.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOffset.java @@ -111,7 +111,7 @@ enum WidgetOffset RESIZABLE_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_EQUIPMENT_ICON, null, 2, null, null), RESIZABLE_2005_MUSIC_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_MUSIC_ICON, null, 3, null, null), - RESIZABLE_BOTTOM_2005_INVENTORY_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_ICON, null, -2, null, null), + RESIZABLE_BOTTOM_2005_INVENTORY_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_ICON, 98, 2, null, null), RESIZABLE_BOTTOM_2005_QUESTS_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_QUESTS_ICON, 67, 0, null, null), RESIZABLE_BOTTOM_2005_EQUIPMENT_ICON(Skin.AROUND_2005, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_EQUIPMENT_ICON, 132, 2, null, null), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java index 0ab7d78067..a537c97d83 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridPlugin.java @@ -33,7 +33,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -56,6 +56,9 @@ public class InventoryGridPlugin extends Plugin @Inject private InventoryGridConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean showItem; @Getter(AccessLevel.PACKAGE) @@ -73,12 +76,16 @@ public class InventoryGridPlugin extends Plugin public void startUp() { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override public void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); } @@ -88,8 +95,7 @@ public class InventoryGridPlugin extends Plugin return configManager.getConfig(InventoryGridConfig.class); } - @Subscribe - public void onConfigChanged(ConfigChanged config) + private void onConfigChanged(ConfigChanged config) { if (config.getGroup().equals("inventorygrid")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java index f7d8cba390..b5161af6ec 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorysetups/InventorySetupPlugin.java @@ -54,7 +54,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemVariationMapping; import net.runelite.client.plugins.Plugin; @@ -104,6 +104,9 @@ public class InventorySetupPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + @Inject private ConfigManager configManager; @@ -131,6 +134,7 @@ public class InventorySetupPlugin extends Plugin public void startUp() { updateConfigOptions(); + addSubscriptions(); overlayManager.add(overlay); @@ -257,8 +261,7 @@ public class InventorySetupPlugin extends Plugin return configManager.getConfig(InventorySetupConfig.class); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals(CONFIG_GROUP)) { @@ -313,8 +316,7 @@ public class InventorySetupPlugin extends Plugin } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (!highlightDifference || client.getGameState() != GameState.LOGGED_IN) @@ -347,8 +349,7 @@ public class InventorySetupPlugin extends Plugin } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -422,10 +423,18 @@ public class InventorySetupPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); overlayManager.remove(overlay); clientToolbar.removeNavigation(navButton); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + final int[] getCurrentInventorySetupIds() { InventorySetup setup = inventorySetups.get(panel.getSelectedInventorySetup()); 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 0a87706e6e..e6986c1503 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 @@ -40,7 +40,7 @@ import net.runelite.api.events.MenuOptionClicked; 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.eventbus.EventBus; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.plugins.Plugin; @@ -104,6 +104,9 @@ public class InventoryTagsPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; + private boolean editorMode; private Color group1Color; @@ -142,6 +145,8 @@ public class InventoryTagsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + refreshInventoryMenuOptions(); overlayManager.add(overlay); } @@ -149,13 +154,22 @@ public class InventoryTagsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + removeInventoryMenuOptions(); overlayManager.remove(overlay); editorMode = false; } - @Subscribe - public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetMenuOptionClicked.class, this, this::onWidgetMenuOptionClicked); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(MenuOpened.class, this, this::onMenuOpened); + } + + private void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) { if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB @@ -166,8 +180,7 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) + private void onMenuOptionClicked(final MenuOptionClicked event) { if (event.getMenuAction() != MenuAction.RUNELITE) { @@ -186,8 +199,7 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onMenuOpened(final MenuOpened event) + private void onMenuOpened(final MenuOpened event) { final MenuEntry firstEntry = event.getFirstEntry(); @@ -277,8 +289,7 @@ public class InventoryTagsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("inventorytags")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java index 114809287e..23ccdb8a95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerPlugin.java @@ -31,7 +31,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -56,6 +56,9 @@ public class InventoryViewerPlugin extends Plugin @Inject private InventoryViewerConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private InventoryViewerMode viewerMode; @Getter(AccessLevel.PACKAGE) @@ -73,11 +76,12 @@ public class InventoryViewerPlugin extends Plugin public void startUp() { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals(CONFIG_GROUP_KEY)) { @@ -88,6 +92,8 @@ public class InventoryViewerPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java index 0cf44d6f25..e217d000ad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java @@ -55,7 +55,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -161,6 +161,9 @@ public class ItemChargePlugin extends Plugin @Inject private ItemChargeConfig config; + @Inject + private EventBus eventBus; + // Limits destroy callback to once per tick private int lastCheckTick; @@ -233,6 +236,7 @@ public class ItemChargePlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(recoilOverlay); @@ -242,14 +246,26 @@ public class ItemChargePlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(recoilOverlay); infoBoxManager.removeIf(ItemChargeInfobox.class::isInstance); lastCheckTick = -1; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("itemCharge")) { @@ -296,8 +312,7 @@ public class ItemChargePlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + void onChatMessage(ChatMessage event) { String message = event.getMessage(); Matcher dodgyCheckMatcher = DODGY_CHECK_PATTERN.matcher(message); @@ -420,8 +435,7 @@ public class ItemChargePlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT) || !this.showInfoboxes) { @@ -462,8 +476,7 @@ public class ItemChargePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { Widget braceletBreakWidget = client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT); @@ -564,8 +577,7 @@ public class ItemChargePlugin extends Plugin } } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged event) + private void onSpotAnimationChanged(SpotAnimationChanged event) { if (event.getActor() == client.getLocalPlayer() && client.getLocalPlayer().getSpotAnimation() == GraphicID.XERIC_TELEPORT) { @@ -574,7 +586,6 @@ public class ItemChargePlugin extends Plugin } } - @Subscribe private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!"destroyOnOpKey".equals(event.getEventName())) @@ -589,7 +600,6 @@ public class ItemChargePlugin extends Plugin } } - @Subscribe private void onVarbitChanged(VarbitChanged event) { int explorerRingCharge = client.getVar(Varbits.EXPLORER_RING_ALCHS); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java index c1ccaada8e..d71bcc0074 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java @@ -85,7 +85,41 @@ enum ItemIdentification TEAK_SAPLING(Type.SAPLING, "Teak", "TEAK", ItemID.TEAK_SAPLING, ItemID.TEAK_SEEDLING, ItemID.TEAK_SEEDLING_W), MAHOGANY_SAPLING(Type.SAPLING, "Mahog", "MAHOG", ItemID.MAHOGANY_SAPLING, ItemID.MAHOGANY_SEEDLING, ItemID.MAHOGANY_SEEDLING_W), CALQUAT_SAPLING(Type.SAPLING, "Calquat", "CALQ", ItemID.CALQUAT_SAPLING, ItemID.CALQUAT_SEEDLING, ItemID.CALQUAT_SEEDLING_W), - CELASTRUS_SAPLING(Type.SAPLING, "Celas", "CEL", ItemID.CELASTRUS_SAPLING, ItemID.CELASTRUS_SEEDLING, ItemID.CELASTRUS_SEEDLING_W); + CELASTRUS_SAPLING(Type.SAPLING, "Celas", "CEL", ItemID.CELASTRUS_SAPLING, ItemID.CELASTRUS_SEEDLING, ItemID.CELASTRUS_SEEDLING_W), + + //Ores + COPPER_ORE(Type.ORE, "Copper", "COP", ItemID.COPPER_ORE), + TIN_ORE(Type.ORE, "Tin", "TIN", ItemID.TIN_ORE), + IRON_ORE(Type.ORE, "Iron", "IRO", ItemID.IRON_ORE), + SILVER_ORE(Type.ORE, "Silver", "SIL", ItemID.SILVER_ORE), + COAL_ORE(Type.ORE, "Coal", "COA", ItemID.COAL), + GOLD_ORE(Type.ORE, "Gold", "GOL", ItemID.GOLD_ORE), + MITHRIL_ORE(Type.ORE, "Mithril", "MIT", ItemID.MITHRIL_ORE), + ADAMANTITE_ORE(Type.ORE, "Adaman", "ADA", ItemID.ADAMANTITE_ORE), + RUNITE_ORE(Type.ORE, "Runite", "RUN", ItemID.RUNITE_ORE), + + RUNE_ESSENCE(Type.ORE, "R.Ess", "R.E.", ItemID.RUNE_ESSENCE), + PURE_ESSENCE(Type.ORE, "P.Ess", "P.E.", ItemID.PURE_ESSENCE), + + PAYDIRT(Type.ORE, "Paydirt", "PAY", ItemID.PAYDIRT), + AMETHYST(Type.ORE, "Amethy", "AME", ItemID.AMETHYST), + LOVAKITE_ORE(Type.ORE, "Lovakit", "LOV", ItemID.LOVAKITE_ORE), + BLURITE_ORE(Type.ORE, "Blurite", "BLU", ItemID.BLURITE_ORE), + ELEMENTAL_ORE(Type.ORE, "Element", "ELE", ItemID.ELEMENTAL_ORE), + DAEYALT_ORE(Type.ORE, "Daeyalt", "DAE", ItemID.DAEYALT_ORE), + LUNAR_ORE(Type.ORE, "Lunar", "LUN", ItemID.LUNAR_ORE), + + //Gems + SAPPHIRE(Type.GEM, "Sapphir", "S", ItemID.UNCUT_SAPPHIRE, ItemID.SAPPHIRE), + EMERALD(Type.GEM, "Emerald", "E", ItemID.UNCUT_EMERALD, ItemID.EMERALD), + RUBY(Type.GEM, "Ruby", "R", ItemID.UNCUT_RUBY, ItemID.RUBY), + DIAMOND(Type.GEM, "Diamon", "DI", ItemID.UNCUT_DIAMOND, ItemID.DIAMOND), + OPAL(Type.GEM, "Opal", "OP", ItemID.UNCUT_OPAL, ItemID.OPAL), + JADE(Type.GEM, "Jade", "J", ItemID.UNCUT_JADE, ItemID.JADE), + RED_TOPAZ(Type.GEM, "Topaz", "T", ItemID.UNCUT_RED_TOPAZ, ItemID.RED_TOPAZ), + DRAGONSTONE(Type.GEM, "Dragon", "DR", ItemID.UNCUT_DRAGONSTONE, ItemID.DRAGONSTONE), + ONYX(Type.GEM, "Onyx", "ON", ItemID.UNCUT_ONYX, ItemID.ONYX), + ZENYTE(Type.GEM, "Zenyte", "Z", ItemID.UNCUT_ZENYTE, ItemID.ZENYTE); final Type type; final String medName; @@ -126,6 +160,8 @@ enum ItemIdentification { SEED, HERB, - SAPLING + SAPLING, + ORE, + GEM } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java index 12009a284f..f8e524b35a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java @@ -83,4 +83,24 @@ public interface ItemIdentificationConfig extends Config { return true; } + + @ConfigItem( + keyName = "showOres", + name = "Ores", + description = "Show identification on Ores" + ) + default boolean showOres() + { + return false; + } + + @ConfigItem( + keyName = "showGems", + name = "Gems", + description = "Show identification on Gems" + ) + default boolean showGems() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java index 416073704f..edfc850851 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java @@ -82,6 +82,18 @@ class ItemIdentificationOverlay extends WidgetItemOverlay return; } break; + case ORE: + if (!plugin.isShowOres()) + { + return; + } + break; + case GEM: + if (!plugin.isShowGems()) + { + return; + } + break; } graphics.setFont(FontManager.getRunescapeSmallFont()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationPlugin.java index 1a8e9fa293..73538e1ad5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationPlugin.java @@ -32,7 +32,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -54,6 +54,9 @@ public class ItemIdentificationPlugin extends Plugin @Inject private ItemIdentificationConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private ItemIdentificationMode identificationType; @Getter(AccessLevel.PACKAGE) @@ -64,6 +67,10 @@ public class ItemIdentificationPlugin extends Plugin private boolean showHerbs; @Getter(AccessLevel.PACKAGE) private boolean showSaplings; + @Getter(AccessLevel.PACKAGE) + private boolean showOres; + @Getter(AccessLevel.PACKAGE) + private boolean showGems; @Provides ItemIdentificationConfig getConfig(ConfigManager configManager) @@ -75,17 +82,20 @@ public class ItemIdentificationPlugin extends Plugin protected void startUp() { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("itemidentification")) { @@ -102,5 +112,7 @@ public class ItemIdentificationPlugin extends Plugin this.showSeeds = config.showSeeds(); this.showHerbs = config.showHerbs(); this.showSaplings = config.showSaplings(); + this.showOres = config.showOres(); + this.showGems = config.showGems(); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesPlugin.java index 302c9d8728..12e929dfd1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesPlugin.java @@ -31,7 +31,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -54,6 +54,9 @@ public class ItemPricesPlugin extends Plugin @Inject private ItemPricesConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean showGEPrice; @Getter(AccessLevel.PACKAGE) @@ -75,17 +78,19 @@ public class ItemPricesPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("itemprices")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java index 89115daa29..6006eb658a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java @@ -57,7 +57,7 @@ import net.runelite.api.vars.AccountType; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetType; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemMapping; import net.runelite.client.plugins.Plugin; @@ -112,6 +112,9 @@ public class ItemsKeptOnDeathPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + private WidgetButton deepWildyButton; private WidgetButton lowWildyButton; @@ -122,8 +125,19 @@ public class ItemsKeptOnDeathPlugin extends Plugin @VisibleForTesting int wildyLevel; - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (event.getEventName().equals("itemsKeptOnDeath")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java index a9a3c766ee..50cd663854 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java @@ -48,7 +48,7 @@ import net.runelite.http.api.item.ItemStats; public class ItemStatOverlay extends Overlay { // Unarmed attack speed is 6 - private static final ItemStats UNARMED = new ItemStats(false, true, 0, + private static final ItemStats UNARMED = new ItemStats("", false, true, 0, ItemEquipmentStats.builder() .aspeed(6) .build()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java index f94a17df0c..06dbfe1c50 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatPlugin.java @@ -58,7 +58,7 @@ import net.runelite.api.widgets.WidgetTextAlignment; import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -98,6 +98,9 @@ public class ItemStatPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + private Widget itemInformationTitle; @Getter(AccessLevel.PACKAGE) @@ -140,18 +143,28 @@ public class ItemStatPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); clientThread.invokeLater(this::resetGEInventory); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getKey().equals("geStats")) { @@ -160,8 +173,7 @@ public class ItemStatPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (itemInformationTitle != null && this.geStats && (client.getWidget(WidgetInfo.GRAND_EXCHANGE_WINDOW_CONTAINER) == null @@ -171,8 +183,8 @@ public class ItemStatPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + + private void onVarbitChanged(VarbitChanged event) { if (client.getVar(VarPlayer.CURRENT_GE_ITEM) == -1 && this.geStats) { @@ -180,8 +192,7 @@ public class ItemStatPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (event.getEventName().equals("geBuilt") && this.geStats) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java index 55e2122ef1..3de235562c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/keyremapping/KeyRemappingPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ModifierlessKeybind; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -80,6 +80,9 @@ public class KeyRemappingPlugin extends Plugin @Inject private KeyRemappingListener inputListener; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) private boolean typing; @@ -128,6 +131,7 @@ public class KeyRemappingPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); typing = false; keyManager.registerKeyListener(inputListener); @@ -144,6 +148,8 @@ public class KeyRemappingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + clientThread.invoke(() -> { if (client.getGameState() == GameState.LOGGED_IN) @@ -155,6 +161,12 @@ public class KeyRemappingPlugin extends Plugin keyManager.unregisterKeyListener(inputListener); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + @Provides KeyRemappingConfig getConfig(ConfigManager configManager) { @@ -195,8 +207,7 @@ public class KeyRemappingPlugin extends Plugin return w == null || w.isSelfHidden(); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (!configChanged.getGroup().equals("keyremapping")) { @@ -216,8 +227,7 @@ public class KeyRemappingPlugin extends Plugin ); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) + private void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent) { switch (scriptCallbackEvent.getEventName()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomPlugin.java index e0445d6576..39e99d8a7f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kingdomofmiscellania/KingdomPlugin.java @@ -37,7 +37,7 @@ import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.VarbitChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -64,19 +64,35 @@ public class KingdomPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private int favor = 0, coffer = 0; private KingdomCounter counter; + @Override + protected void startUp() throws Exception + { + addSubscriptions(); + } + @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + removeKingdomInfobox(); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void addSubscriptions() + { + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onVarbitChanged(VarbitChanged event) { if (isInKingdom()) { @@ -86,7 +102,6 @@ public class KingdomPlugin extends Plugin } } - @Subscribe public void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java index 54e60eb415..0d8450e0f2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java @@ -53,7 +53,7 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -98,6 +98,9 @@ public class KourendLibraryPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + private KourendLibraryPanel panel; private NavigationButton navButton; private boolean buttonAttached = false; @@ -118,6 +121,8 @@ public class KourendLibraryPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + hideButton = config.hideButton(); hideDuplicateBook = config.hideDuplicateBook(); @@ -148,6 +153,8 @@ public class KourendLibraryPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlay.setHidden(true); overlayManager.remove(overlay); clientToolbar.removeNavigation(navButton); @@ -157,8 +164,17 @@ public class KourendLibraryPlugin extends Plugin playerBooks = null; } - @Subscribe - public void onConfigChanged(ConfigChanged ev) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + } + + private void onConfigChanged(ConfigChanged ev) { if (!KourendLibraryConfig.GROUP_KEY.equals(ev.getGroup())) { @@ -190,8 +206,7 @@ public class KourendLibraryPlugin extends Plugin }); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked menuOpt) + private void onMenuOptionClicked(MenuOptionClicked menuOpt) { if (MenuAction.GAME_OBJECT_FIRST_OPTION == menuOpt.getMenuAction() && menuOpt.getTarget().contains("Bookshelf")) { @@ -200,8 +215,7 @@ public class KourendLibraryPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged anim) + private void onAnimationChanged(AnimationChanged anim) { if (anim.getActor() == client.getLocalPlayer() && anim.getActor().getAnimation() == AnimationID.LOOKING_INTO) { @@ -209,8 +223,7 @@ public class KourendLibraryPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (lastBookcaseAnimatedOn != null && event.getType() == ChatMessageType.GAMEMESSAGE) { @@ -223,8 +236,7 @@ public class KourendLibraryPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { boolean inRegion = client.getLocalPlayer().getWorldLocation().getRegionID() == REGION; if (this.hideButton && inRegion != buttonAttached) @@ -295,8 +307,7 @@ public class KourendLibraryPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged itemContainerChangedEvent) + private void onItemContainerChanged(ItemContainerChanged itemContainerChangedEvent) { updatePlayerBooks(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/learntoclick/LearnToClickPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/learntoclick/LearnToClickPlugin.java index 94d1aa6c18..6e92d4165a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/learntoclick/LearnToClickPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/learntoclick/LearnToClickPlugin.java @@ -24,7 +24,7 @@ import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -50,6 +50,9 @@ public class LearnToClickPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + private boolean shouldBlockCompass; private boolean shouldRightClickMap; private boolean shouldRightClickXp; @@ -66,17 +69,27 @@ public class LearnToClickPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + forceRightClickFlag = false; hideOrbWidgets(false); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(MenuShouldLeftClick.class, this, this::onMenuShouldLeftClick); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("learntoclick")) { @@ -96,8 +109,7 @@ public class LearnToClickPlugin extends Plugin } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (!this.hideOrbs) { @@ -109,8 +121,7 @@ public class LearnToClickPlugin extends Plugin } } - @Subscribe - public void onMenuShouldLeftClick(MenuShouldLeftClick event) + private void onMenuShouldLeftClick(MenuShouldLeftClick event) { if (!forceRightClickFlag) { @@ -131,8 +142,7 @@ public class LearnToClickPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if ((event.getOption().equals("Floating") && this.shouldRightClickMap) || (event.getOption().equals("Hide") && this.shouldRightClickXp) || (event.getOption().equals("Show") && this.shouldRightClickXp) || diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java index 64cc513f22..41f9c61624 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lizardmenshaman/LizardmenShamanPlugin.java @@ -40,7 +40,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -75,6 +75,9 @@ public class LizardmenShamanPlugin extends Plugin @Inject private Notifier notifier; + @Inject + private EventBus eventBus; + private boolean showTimer; private boolean notifyOnSpawn; @@ -87,6 +90,8 @@ public class LizardmenShamanPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.showTimer = config.showTimer(); this.notifyOnSpawn = config.notifyOnSpawn(); @@ -96,12 +101,20 @@ public class LizardmenShamanPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); spawns.clear(); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + } + + private void onChatMessage(ChatMessage event) { if (this.notifyOnSpawn && /* event.getType() == ChatMessageType.GAMEMESSAGE && */event.getMessage().contains(MESSAGE)) // ChatMessageType should probably be SPAM <- should be tested first though @@ -110,8 +123,7 @@ public class LizardmenShamanPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { Actor actor = event.getActor(); if (actor == null || actor.getName() == null) @@ -125,8 +137,7 @@ public class LizardmenShamanPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("shaman")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java index dbf0a6df64..3737a23677 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loginscreen/LoginScreenPlugin.java @@ -38,9 +38,9 @@ import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionOpen; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; @@ -68,6 +68,9 @@ public class LoginScreenPlugin extends Plugin implements KeyListener @Inject private KeyManager keyManager; + @Inject + private EventBus eventBus; + private String usernameCache; private boolean syncUsername; @@ -78,6 +81,8 @@ public class LoginScreenPlugin extends Plugin implements KeyListener protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + applyUsername(); keyManager.registerKeyListener(this); } @@ -85,6 +90,8 @@ public class LoginScreenPlugin extends Plugin implements KeyListener @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + if (this.syncUsername) { client.getPreferences().setRememberedUsername(usernameCache); @@ -93,14 +100,20 @@ public class LoginScreenPlugin extends Plugin implements KeyListener keyManager.unregisterKeyListener(this); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); + } + @Provides LoginScreenConfig getConfig(ConfigManager configManager) { return configManager.getConfig(LoginScreenConfig.class); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (!this.syncUsername) { @@ -131,8 +144,7 @@ public class LoginScreenPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onSessionOpen(SessionOpen event) + private void onSessionOpen(SessionOpen event) { // configuation for the account is available now, so update the username applyUsername(); @@ -230,8 +242,7 @@ public class LoginScreenPlugin extends Plugin implements KeyListener } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("loginscreen")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistOverlay.java index 2aa5705337..10ef9f2f04 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistOverlay.java @@ -79,20 +79,20 @@ public class LootAssistOverlay extends Overlay Point timeLoc = Perspective.getCanvasTextLocation(client, graphics, lp, timeOverlay, graphics.getFontMetrics().getHeight()); OverlayUtil.renderPolygon(graphics, poly, Color.WHITE); - if (timeRemaining < 5) + if (timeRemaining < 5 && timeRemaining > 0) { OverlayUtil.renderTextLocation(graphics, timeLoc, timeOverlay, Color.RED); OverlayUtil.renderTextLocation(graphics, textLoc, nameOverlay, Color.RED); } - if (timeRemaining < 2) - { - client.setHintArrow(WorldPoint.fromLocal(client, lp)); - } - else + else if (timeRemaining <= 60) { OverlayUtil.renderTextLocation(graphics, timeLoc, timeOverlay, Color.WHITE); OverlayUtil.renderTextLocation(graphics, textLoc, nameOverlay, Color.WHITE); } + if (timeRemaining < 2) + { + client.setHintArrow(WorldPoint.fromLocal(client, lp)); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistPlugin.java index b896912eec..4e5215656a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootAssistPlugin.java @@ -9,7 +9,7 @@ import net.runelite.api.Player; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -26,34 +26,45 @@ import net.runelite.client.ui.overlay.OverlayManager; public class LootAssistPlugin extends Plugin { @Inject - OverlayManager overlayManager; + private OverlayManager overlayManager; @Inject - LootAssistOverlay lootAssistOverlay; + private LootAssistOverlay lootAssistOverlay; + + @Inject + private EventBus eventBus; static final ConcurrentHashMap lootPiles = new ConcurrentHashMap<>(); @Override protected void startUp() throws Exception { + addSubscriptions(); + overlayManager.add(lootAssistOverlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + lootPiles.clear(); overlayManager.remove(lootAssistOverlay); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + } + + private void onGameStateChanged(GameStateChanged event) { lootPiles.clear(); } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { final Actor actor = event.getActor(); if (actor.getAnimation() == AnimationID.DEATH && actor instanceof Player) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootPile.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootPile.java index f59e842730..e3798d1c64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootPile.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootassist/LootPile.java @@ -7,7 +7,7 @@ import net.runelite.api.coords.WorldPoint; class LootPile { - private static final long TIME_UNTIL_VISIBLE = 60000; + private static final long TIME_UNTIL_VISIBLE = 62400; @Getter(AccessLevel.PACKAGE) private final long timeAppearing; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java index a0e3591dbf..b7ec37c10b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -40,7 +40,7 @@ import net.runelite.api.events.WidgetHiddenChanged; import net.runelite.api.widgets.Widget; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -80,6 +80,9 @@ public class LootingBagViewerPlugin extends Plugin @Inject private LootingBagViewerConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) private int valueToShow = -1; @@ -93,6 +96,8 @@ public class LootingBagViewerPlugin extends Plugin @Override public void startUp() { + addSubscriptions(); + if (config.renderViewer()) { overlayManager.add(overlay); @@ -107,12 +112,19 @@ public class LootingBagViewerPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(widgetOverlay); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + } + + private void onConfigChanged(ConfigChanged configChanged) { if (configChanged.getKey().equals("renderViewer")) { @@ -142,8 +154,7 @@ public class LootingBagViewerPlugin extends Plugin /** * @param widgetHiddenChanged */ - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged) + private void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged) { Widget widget = widgetHiddenChanged.getWidget(); if (widget.getParentId() == 5308416 && !widget.isHidden()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index cb4ce03bf2..f504ccea15 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -393,7 +393,7 @@ class LootTrackerPanel extends PluginPanel layoutPanel.add(logsContainer); // Add error pane - errorPanel.setContent("Loot trackers", "You have not received any loot yet."); + errorPanel.setContent("Loot tracker", "You have not received any loot yet."); add(errorPanel); } 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 c1bb032c55..3344305fa3 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 @@ -63,6 +63,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import net.runelite.api.GameState; import net.runelite.api.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemContainer; @@ -75,6 +76,7 @@ import net.runelite.api.WorldType; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.LocalPlayerDeath; import net.runelite.api.events.PlayerSpawned; @@ -89,7 +91,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.NpcLootReceived; import net.runelite.client.events.PlayerLootReceived; import net.runelite.client.events.SessionClose; @@ -165,9 +167,13 @@ public class LootTrackerPlugin extends Plugin private SessionManager sessionManager; @Inject private ScheduledExecutorService executor; + @Inject + private EventBus eventBus; private LootTrackerPanel panel; private NavigationButton navButton; private String eventType; + private boolean chestLooted; + private List ignoredItems = new ArrayList<>(); private List ignoredNPCs = new ArrayList<>(); private Multiset inventorySnapshot; @@ -228,8 +234,7 @@ public class LootTrackerPlugin extends Plugin return configManager.getConfig(LootTrackerConfig.class); } - @Subscribe - public void onSessionOpen(SessionOpen sessionOpen) + private void onSessionOpen(SessionOpen sessionOpen) { AccountSession accountSession = sessionManager.getAccountSession(); if (accountSession.getUuid() != null) @@ -242,14 +247,12 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe - public void onSessionClose(SessionClose sessionClose) + private void onSessionClose(SessionClose sessionClose) { lootTrackerClient = null; } - @Subscribe - public void onLocalPlayerDeath(LocalPlayerDeath event) + private void onLocalPlayerDeath(LocalPlayerDeath event) { if (client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isPvpWorld(client.getWorldType())) { @@ -258,8 +261,7 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("loottracker")) { @@ -287,6 +289,8 @@ public class LootTrackerPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + ignoredItems = Text.fromCSV(config.getIgnoredItems()); ignoredNPCs = Text.fromCSV(config.getIgnoredNPCs()); updateConfig(); @@ -373,13 +377,38 @@ public class LootTrackerPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + clientToolbar.removeNavigation(navButton); lootTrackerClient = null; lootRecords = new ArrayList<>(); + chestLooted = false; } - @Subscribe - public void onNpcLootReceived(final NpcLootReceived npcLootReceived) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); + eventBus.subscribe(SessionClose.class, this, this::onSessionClose); + eventBus.subscribe(LocalPlayerDeath.class, this, this::onLocalPlayerDeath); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcLootReceived.class, this, this::onNpcLootReceived); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + eventBus.subscribe(PlayerLootReceived.class, this, this::onPlayerLootReceived); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + } + + private void onGameStateChanged(final GameStateChanged event) + { + if (event.getGameState() == GameState.LOADING) + { + chestLooted = false; + } + } + + private void onNpcLootReceived(final NpcLootReceived npcLootReceived) { final NPC npc = npcLootReceived.getNpc(); final Collection items = npcLootReceived.getItems(); @@ -421,8 +450,7 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe - public void onPlayerSpawned(PlayerSpawned event) + private void onPlayerSpawned(PlayerSpawned event) { if (event.getPlayer().equals(client.getLocalPlayer())) { @@ -430,8 +458,7 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe - public void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) + private void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) { if (this.sendLootValueMessages) { @@ -465,8 +492,7 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { final ItemContainer container; switch (event.getGroupId()) @@ -476,10 +502,19 @@ public class LootTrackerPlugin extends Plugin container = client.getItemContainer(InventoryID.BARROWS_REWARD); break; case (WidgetID.CHAMBERS_OF_XERIC_REWARD_GROUP_ID): + if (chestLooted) + { + return; + } eventType = "Chambers of Xeric"; container = client.getItemContainer(InventoryID.CHAMBERS_OF_XERIC_CHEST); + chestLooted = true; break; - case (WidgetID.THEATRE_OF_BLOOD_REWARD_GROUP_ID): + case (WidgetID.THEATRE_OF_BLOOD_GROUP_ID): + if (chestLooted) + { + return; + } int region = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()).getRegionID(); if (region != THEATRE_OF_BLOOD_REGION) { @@ -487,6 +522,7 @@ public class LootTrackerPlugin extends Plugin } eventType = "Theatre of Blood"; container = client.getItemContainer(InventoryID.THEATRE_OF_BLOOD_CHEST); + chestLooted = true; break; case (WidgetID.CLUE_SCROLL_REWARD_GROUP_ID): // event type should be set via ChatMessage for clue scrolls. @@ -558,8 +594,7 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM) { @@ -619,7 +654,6 @@ public class LootTrackerPlugin extends Plugin } } - @Subscribe public void onItemContainerChanged(ItemContainerChanged event) { if (pvpDeath && RESPAWN_REGIONS.contains(client.getLocalPlayer().getWorldLocation().getRegionID())) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java index 589ac4e202..14047a43b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lowmemory/LowMemoryPlugin.java @@ -29,7 +29,7 @@ import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -45,9 +45,14 @@ public class LowMemoryPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + if (client.getGameState() == GameState.LOGGED_IN) { client.changeMemoryMode(true); @@ -57,10 +62,11 @@ public class LowMemoryPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + client.changeMemoryMode(false); } - @Subscribe private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java index b711aa37a5..f525c6ff8e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/maxhit/MaxHitPlugin.java @@ -35,7 +35,7 @@ import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -56,20 +56,39 @@ public class MaxHitPlugin extends Plugin @Inject private Client client; - @Subscribe - public void onItemContainerChanged(final ItemContainerChanged event) + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + addSubscriptions(); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + + private void onItemContainerChanged(final ItemContainerChanged event) { this.updateMaxHitWidget(); } - @Subscribe - public void onConfigChanged(final ConfigChanged event) + private void onConfigChanged(final ConfigChanged event) { this.updateMaxHitWidget(); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { this.updateMaxHitWidget(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 121b1f395c..06850797da 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1,7 +1,8 @@ /* * Copyright (c) 2018, Adam - * Copyright (c) 2018, Kyle - * Copyright (c) 2018, lucouswin + * Copyright (c) 2019, alanbaumgartner + * Copyright (c) 2019, Kyle + * Copyright (c) 2019, lucouswin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1668,28 +1669,56 @@ default CharterOption charterOption() //------------------------------------------------------------// @ConfigItem( - keyName = "removeFreezePlayerToB", - name = "Remove freeze in ToB", - description = "Removes the freeze option for ice barrage, ice blitz, entangle etc. in ToB", + keyName = "hideCastToB", + name = "Hide cast in ToB", + description = "Hides the cast option for clanmates and friends in ToB", position = 0, group = "PVM" ) - default boolean getRemoveFreezePlayerToB() + default boolean hideCastToB() { return true; } @ConfigItem( - keyName = "removeFreezePlayerCoX", - name = "Remove freeze in CoX", - description = "Removes the freeze option for ice barrage, ice blitz, entangle etc. in CoX", + keyName = "hideCastIgnoredToB", + name = "Ignored spells", + description = "Spells that should not be hidden from being cast, separated by a comma", position = 1, + group = "PVM", + hidden = true, + unhide = "hideCastToB" + ) + default String hideCastIgnoredToB() + { + return "cure other, energy transfer, heal other, vengeance other"; + } + + @ConfigItem( + keyName = "hideCastCoX", + name = "Hide cast in CoX", + description = "Hides the cast option for clanmates and friends in CoX", + position = 2, group = "PVM" ) - default boolean getRemoveFreezePlayerCoX() - { - return true; - } -} \ No newline at end of file + default boolean hideCastCoX() + { + return true; + } + + @ConfigItem( + keyName = "hideCastIgnoredCoX", + name = "Ignored spells", + description = "Spells that should not be hidden from being cast, separated by a comma", + position = 3, + group = "PVM", + hidden = true, + unhide = "hideCastCoX" + ) + default String hideCastIgnoredCoX() + { + return "cure other, energy transfer, heal other, vengeance other"; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 06dee1c828..78bd1037e7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -1,8 +1,9 @@ /* * Copyright (c) 2018, Adam * Copyright (c) 2018, Kamiel - * Copyright (c) 2018, Kyle - * Copyright (c) 2018, lucouswin + * Copyright (c) 2019, alanbaumgartner + * Copyright (c) 2019, Kyle + * Copyright (c) 2019, lucouswin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +31,7 @@ package net.runelite.client.plugins.menuentryswapper; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import com.google.inject.Provides; import java.util.ArrayList; import java.util.Arrays; @@ -57,6 +59,8 @@ import net.runelite.api.NPC; import net.runelite.api.Player; import net.runelite.api.Varbits; import static net.runelite.api.Varbits.BUILDING_MODE; + +import net.runelite.api.WorldType; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; @@ -70,7 +74,7 @@ import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemVariationMapping; import net.runelite.client.input.KeyManager; @@ -78,7 +82,9 @@ import net.runelite.client.menus.ComparableEntry; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginManager; import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.menuentryswapper.util.BurningAmuletMode; import net.runelite.client.plugins.menuentryswapper.util.CombatBraceletMode; @@ -100,6 +106,9 @@ import net.runelite.client.plugins.menuentryswapper.util.SlayerRingMode; import net.runelite.client.plugins.menuentryswapper.util.XericsTalismanMode; import net.runelite.client.plugins.menuentryswapper.util.teleEquippedMode; import static net.runelite.client.util.MenuUtil.swap; + +import net.runelite.client.plugins.pvptools.PvpToolsConfig; +import net.runelite.client.plugins.pvptools.PvpToolsPlugin; import net.runelite.client.util.MiscUtils; import net.runelite.client.util.Text; import org.apache.commons.lang3.ArrayUtils; @@ -112,6 +121,7 @@ import org.apache.commons.lang3.ArrayUtils; enabledByDefault = false ) @Singleton +@PluginDependency(PvpToolsPlugin.class) public class MenuEntrySwapperPlugin extends Plugin { private static final String CONFIGURE = "Configure"; @@ -127,6 +137,8 @@ public class MenuEntrySwapperPlugin extends Plugin private MenuEntry[] entries; private final Set leftClickConstructionItems = new HashSet<>(); private boolean buildingMode; + private boolean inTobRaid = false; + private boolean inCoxRaid = false; private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE, MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); @@ -176,6 +188,9 @@ public class MenuEntrySwapperPlugin extends Plugin @Inject private ConfigManager configManager; + @Inject + private PluginManager pluginManager; + @Inject private KeyManager keyManager; @@ -185,6 +200,15 @@ public class MenuEntrySwapperPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + + @Inject + private PvpToolsPlugin pvpTools; + + @Inject + private PvpToolsConfig pvpToolsConfig; + @Getter(AccessLevel.PACKAGE) private boolean configuringShiftClick = false; @@ -312,8 +336,10 @@ public class MenuEntrySwapperPlugin extends Plugin private boolean hideDestroyBoltpouch; private boolean hideDestroyGembag; private boolean hideDropRunecraftingPouch; - private boolean getRemoveFreezePlayerToB; - private boolean getRemoveFreezePlayerCoX; + private boolean hideCastToB; + private Set hideCastIgnoredToB; + private boolean hideCastCoX; + private Set hideCastIgnoredCoX; @Provides MenuEntrySwapperConfig provideConfig(ConfigManager configManager) @@ -325,10 +351,10 @@ public class MenuEntrySwapperPlugin extends Plugin public void startUp() { updateConfig(); + addSubscriptions(); + addSwaps(); loadConstructionItems(config.getEasyConstructionItems()); - client.setHideFriendCastOptions(config.getRemoveFreezePlayerToB()); - client.setHideFriendCastOptions(config.getRemoveFreezePlayerCoX()); if (config.shiftClickCustomization()) { @@ -336,26 +362,49 @@ public class MenuEntrySwapperPlugin extends Plugin } loadCustomSwaps(config.customSwaps()); + + if (client.getGameState() == GameState.LOGGED_IN) + { + setCastOptions(true); + } } @Override public void shutDown() { - client.setHideFriendCastOptions(false); + eventBus.unregister(this); + disableCustomization(); loadConstructionItems(""); loadCustomSwaps(""); // Removes all custom swaps removeSwaps(); + + if (client.getGameState() == GameState.LOGGED_IN) + { + resetCastOptions(); + } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetMenuOptionClicked.class, this, this::onWidgetMenuOptionClicked); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(MenuOpened.class, this, this::onMenuOpened); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(PostItemDefinition.class, this, this::onPostItemDefinition); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + + private void onConfigChanged(ConfigChanged event) { if (!"menuentryswapper".equals(event.getGroup())) { return; } - + updateConfig(); loadConstructionItems(this.getEasyConstructionItems); @@ -368,8 +417,6 @@ public class MenuEntrySwapperPlugin extends Plugin { loadCustomSwaps(this.configCustomSwaps); } - - return; } if (event.getKey().equals("shiftClickCustomization")) @@ -388,19 +435,27 @@ public class MenuEntrySwapperPlugin extends Plugin clientThread.invoke(this::resetItemDefinitionCache); } - if (event.getKey().equals("removeFreezePlayerToB")) + else if ((event.getKey().equals("hideCastToB") || event.getKey().equals("hideCastIgnoredToB"))) { - if (this.getRemoveFreezePlayerToB && client.getVar(Varbits.THEATRE_OF_BLOOD) == 2) + if (this.hideCastToB) { - client.setHideFriendCastOptions(config.getRemoveFreezePlayerToB()); + setCastOptions(true); + } + else + { + resetCastOptions(); } } - if (event.getKey().equals("removeFreezePlayerCoX")) + else if ((event.getKey().equals("hideCastCoX") || event.getKey().equals("hideCastIgnoredCoX"))) { - if (this.getRemoveFreezePlayerCoX && client.getVar(Varbits.IN_RAID) == 1) + if (this.hideCastCoX) { - client.setHideFriendCastOptions(config.getRemoveFreezePlayerCoX()); + setCastOptions(true); + } + else + { + resetCastOptions(); } } } @@ -450,8 +505,7 @@ public class MenuEntrySwapperPlugin extends Plugin clientThread.invoke(this::resetItemDefinitionCache); } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + private void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) { if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_INVENTORY_TAB @@ -462,8 +516,7 @@ public class MenuEntrySwapperPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -473,14 +526,14 @@ public class MenuEntrySwapperPlugin extends Plugin loadConstructionItems(this.getEasyConstructionItems); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { buildingMode = client.getVar(BUILDING_MODE) == 1; + + setCastOptions(false); } - @Subscribe - public void onMenuOpened(MenuOpened event) + private void onMenuOpened(MenuOpened event) { Player localPlayer = client.getLocalPlayer(); @@ -632,8 +685,7 @@ public class MenuEntrySwapperPlugin extends Plugin client.setMenuEntries(ArrayUtils.addAll(entries, resetShiftClickEntry)); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (event.getMenuAction() != MenuAction.RUNELITE || event.getActionParam1() != WidgetInfo.INVENTORY.getId()) { @@ -689,7 +741,6 @@ public class MenuEntrySwapperPlugin extends Plugin } } - @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { if (client.getGameState() != GameState.LOGGED_IN) @@ -1299,6 +1350,10 @@ public class MenuEntrySwapperPlugin extends Plugin swap(client, "empty", option, target, true); } + else if (this.swapQuick && option.equals("enter")) + { + swap(client, "quick-enter", option, target, true); + } else if (this.swapQuick && option.equals("ring")) { swap(client, "quick-start", option, target, true); @@ -1384,8 +1439,7 @@ public class MenuEntrySwapperPlugin extends Plugin } } - @Subscribe - public void onPostItemDefinition(PostItemDefinition event) + private void onPostItemDefinition(PostItemDefinition event) { ItemDefinition itemComposition = event.getItemDefinition(); Integer option = getSwapConfig(itemComposition.getId()); @@ -1396,8 +1450,7 @@ public class MenuEntrySwapperPlugin extends Plugin } } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void onFocusChanged(FocusChanged event) { if (!event.isFocused()) { @@ -1694,6 +1747,59 @@ public class MenuEntrySwapperPlugin extends Plugin menuManager.removePriorityEntry("climb-down"); } + private void setCastOptions(boolean force) + { + clientThread.invoke(() -> + { + boolean tmpInCoxRaid = client.getVar(Varbits.IN_RAID) == 1; + if (tmpInCoxRaid != inCoxRaid || force) + { + if (tmpInCoxRaid && this.hideCastCoX) + { + client.setHideFriendCastOptions(true); + client.setHideClanmateCastOptions(true); + client.setUnhiddenCasts(this.hideCastIgnoredCoX); + } + + inCoxRaid = tmpInCoxRaid; + } + + boolean tmpInTobRaid = client.getVar(Varbits.THEATRE_OF_BLOOD) == 2; + if (tmpInTobRaid != inTobRaid || force) + { + if (tmpInTobRaid && this.hideCastToB) + { + client.setHideFriendCastOptions(true); + client.setHideClanmateCastOptions(true); + client.setUnhiddenCasts(this.hideCastIgnoredToB); + } + + inTobRaid = tmpInTobRaid; + } + + if (!inCoxRaid && !inTobRaid) + { + resetCastOptions(); + } + }); + } + + private void resetCastOptions() + { + clientThread.invoke(() -> + { + if (client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isAllPvpWorld(client.getWorldType()) && pluginManager.isPluginEnabled(pvpTools) && pvpToolsConfig.hideCast()) + { + pvpTools.setCastOptions(); + } + else + { + client.setHideFriendCastOptions(false); + client.setHideClanmateCastOptions(false); + } + }); + } + private void updateConfig() { this.getWithdrawOne = config.getWithdrawOne(); @@ -1817,7 +1923,9 @@ public class MenuEntrySwapperPlugin extends Plugin this.hideDestroyBoltpouch = config.hideDestroyBoltpouch(); this.hideDestroyGembag = config.hideDestroyGembag(); this.hideDropRunecraftingPouch = config.hideDropRunecraftingPouch(); - this.getRemoveFreezePlayerToB = config.getRemoveFreezePlayerToB(); - this.getRemoveFreezePlayerCoX = config.getRemoveFreezePlayerCoX(); + this.hideCastToB = config.hideCastToB(); + this.hideCastIgnoredToB = Sets.newHashSet(Text.fromCSV(config.hideCastIgnoredToB().toLowerCase())); + this.hideCastCoX = config.hideCastCoX(); + this.hideCastIgnoredCoX = Sets.newHashSet(Text.fromCSV(config.hideCastIgnoredCoX().toLowerCase())); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java index b0d9e42f3f..bd19159ca6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java @@ -43,7 +43,7 @@ import net.runelite.api.SoundEffectID; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -63,6 +63,9 @@ public class MetronomePlugin extends Plugin @Inject private MetronomePluginConfiguration config; + @Inject + private EventBus eventBus; + private int tickCounter = 0; private int tockCounter = 0; private Clip tickClip; @@ -111,6 +114,7 @@ public class MetronomePlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); tickClip = GetAudioClip(this.tickPath); tockClip = GetAudioClip(this.tockPath); @@ -119,6 +123,8 @@ public class MetronomePlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + if (tickClip != null) { tickClip.close(); @@ -129,8 +135,13 @@ public class MetronomePlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("metronome")) { @@ -166,8 +177,7 @@ public class MetronomePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { if (this.tickCount == 0) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/minimap/MinimapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/minimap/MinimapPlugin.java index 205e67d03e..d71938b5e3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/minimap/MinimapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/minimap/MinimapPlugin.java @@ -38,7 +38,7 @@ import net.runelite.api.events.WidgetHiddenChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -58,6 +58,9 @@ public class MinimapPlugin extends Plugin @Inject private MinimapConfig config; + @Inject + private EventBus eventBus; + private Sprite[] originalDotSprites; private Color itemColor; @@ -78,6 +81,7 @@ public class MinimapPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); updateMinimapWidgetVisibility(this.hideMinimap); storeOriginalDots(); @@ -87,12 +91,20 @@ public class MinimapPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + updateMinimapWidgetVisibility(false); restoreOriginalDots(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN && originalDotSprites == null) { @@ -101,8 +113,7 @@ public class MinimapPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("minimap")) { @@ -120,8 +131,7 @@ public class MinimapPlugin extends Plugin replaceMapDots(); } - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged event) + private void onWidgetHiddenChanged(WidgetHiddenChanged event) { updateMinimapWidgetVisibility(this.hideMinimap); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java index f0ca9fea59..763d52b38c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java @@ -32,8 +32,6 @@ import java.util.Iterator; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; -import lombok.AccessLevel; -import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.Perspective; import net.runelite.api.Point; @@ -47,9 +45,8 @@ import net.runelite.client.ui.overlay.components.ProgressPieComponent; @Singleton class MiningOverlay extends Overlay { - // Range of Motherlode vein respawn time not 100% confirmed but based on observation - @Getter(AccessLevel.PACKAGE) - public static final int ORE_VEIN_MAX_RESPAWN_TIME = 123; + // Range of Motherlode vein respawn time - not 100% confirmed but based on observation + static final int ORE_VEIN_MAX_RESPAWN_TIME = 166; private static final int ORE_VEIN_MIN_RESPAWN_TIME = 90; private static final float ORE_VEIN_RANDOM_PERCENT_THRESHOLD = (float) ORE_VEIN_MIN_RESPAWN_TIME / ORE_VEIN_MAX_RESPAWN_TIME; private static final Color DARK_GREEN = new Color(0, 100, 0); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java index c77ff5ce24..4460e8a970 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java @@ -37,7 +37,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameObject; @@ -67,12 +66,11 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -@Slf4j @PluginDescriptor( name = "Mining", description = "Show ore respawn timers and coal bag overlay", @@ -110,6 +108,9 @@ public class MiningPlugin extends Plugin @Inject private MiningConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final List respawns = new ArrayList<>(); private boolean recentlyLoggedIn; @@ -122,6 +123,8 @@ public class MiningPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + this.showCoalBagOverlay = config.showCoalBagOverlay(); this.amountOfCoalInCoalBag = config.amountOfCoalInCoalBag(); @@ -132,19 +135,30 @@ public class MiningPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(miningOverlay); overlayManager.remove(coalBagOverlay); respawns.clear(); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + @Provides MiningConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(MiningConfig.class); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -161,14 +175,12 @@ public class MiningPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { recentlyLoggedIn = false; } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { if (client.getGameState() != GameState.LOGGED_IN || recentlyLoggedIn) { @@ -185,8 +197,7 @@ public class MiningPlugin extends Plugin } } - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) + private void onWallObjectSpawned(WallObjectSpawned event) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -227,8 +238,7 @@ public class MiningPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { //TODO: should work hopefully if (event.getMenuAction() != MenuAction.RUNELITE || event.getActionParam1() != WidgetInfo.INVENTORY.getId()) @@ -258,8 +268,7 @@ public class MiningPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE) { @@ -305,8 +314,7 @@ public class MiningPlugin extends Plugin return client.getLocalPlayer().getWorldLocation().getRegionID() == MINING_GUILD_REGION; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("mining")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java index 19207b7fd6..b87b46d3ff 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -29,27 +29,7 @@ import java.time.Duration; import java.util.Map; import lombok.AccessLevel; import lombok.Getter; -import static net.runelite.api.ObjectID.ROCKS_10943; -import static net.runelite.api.ObjectID.ROCKS_11161; -import static net.runelite.api.ObjectID.ROCKS_11360; -import static net.runelite.api.ObjectID.ROCKS_11361; -import static net.runelite.api.ObjectID.ROCKS_11364; -import static net.runelite.api.ObjectID.ROCKS_11365; -import static net.runelite.api.ObjectID.ROCKS_11366; -import static net.runelite.api.ObjectID.ROCKS_11367; -import static net.runelite.api.ObjectID.ROCKS_11368; -import static net.runelite.api.ObjectID.ROCKS_11369; -import static net.runelite.api.ObjectID.ROCKS_11370; -import static net.runelite.api.ObjectID.ROCKS_11371; -import static net.runelite.api.ObjectID.ROCKS_11372; -import static net.runelite.api.ObjectID.ROCKS_11373; -import static net.runelite.api.ObjectID.ROCKS_11374; -import static net.runelite.api.ObjectID.ROCKS_11375; -import static net.runelite.api.ObjectID.ROCKS_11376; -import static net.runelite.api.ObjectID.ROCKS_11377; -import static net.runelite.api.ObjectID.ROCKS_11386; -import static net.runelite.api.ObjectID.ROCKS_11387; -import static net.runelite.api.ObjectID.ASH_PILE; +import static net.runelite.api.ObjectID.*; enum Rock { @@ -101,7 +81,8 @@ enum Rock }, ORE_VEIN(Duration.ofSeconds(MiningOverlay.ORE_VEIN_MAX_RESPAWN_TIME), 150), AMETHYST(Duration.ofSeconds(75), 120), - ASH_VEIN(Duration.ofSeconds(30), 0, ASH_PILE); + ASH_VEIN(Duration.ofSeconds(30), 0, ASH_PILE), + GEM_ROCK(Duration.ofMinutes(1), 0, ROCKS_11380, ROCKS_11381); private static final Map ROCKS; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java index 68c1dce8ca..880a74c8fe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/motherlode/MotherlodePlugin.java @@ -105,7 +105,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.task.Schedule; @@ -169,6 +169,9 @@ public class MotherlodePlugin extends Plugin @Inject private Notifier notifier; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean inMlm; @@ -230,6 +233,7 @@ public class MotherlodePlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(rocksOverlay); @@ -248,6 +252,8 @@ public class MotherlodePlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(rocksOverlay); overlayManager.remove(motherlodeGemOverlay); @@ -267,8 +273,27 @@ public class MotherlodePlugin extends Plugin }); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(WallObjectChanged.class, this, this::onWallObjectChanged); + eventBus.subscribe(WallObjectDespawned.class, this, this::onWallObjectDespawned); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(OverheadTextChanged.class, this, this::onOverheadTextChanged); + } + + void onVarbitChanged(VarbitChanged event) { if (inMlm) { @@ -290,8 +315,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (!inMlm || event.getType() != ChatMessageType.SPAM) { @@ -354,8 +378,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked menu) + private void onMenuOptionClicked(MenuOptionClicked menu) { if (!inMlm) { @@ -371,8 +394,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (!inMlm) { @@ -404,8 +426,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onAnimationChanged (AnimationChanged event) + private void onAnimationChanged (AnimationChanged event) { if (!inMlm) { @@ -472,8 +493,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (!inMlm || targetVeinLocation == null) { @@ -509,8 +529,7 @@ public class MotherlodePlugin extends Plugin notifier.notify(client.getLocalPlayer().getName() + " has stopped mining!"); } - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) + private void onWallObjectSpawned(WallObjectSpawned event) { if (!inMlm) { @@ -531,8 +550,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onWallObjectChanged(WallObjectChanged event) + private void onWallObjectChanged(WallObjectChanged event) { if (!inMlm) { @@ -549,8 +567,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onWallObjectDespawned(WallObjectDespawned event) + private void onWallObjectDespawned(WallObjectDespawned event) { if (!inMlm) { @@ -561,8 +578,7 @@ public class MotherlodePlugin extends Plugin veins.remove(wallObject); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { if (!inMlm) { @@ -576,8 +592,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { if (!inMlm) { @@ -595,8 +610,7 @@ public class MotherlodePlugin extends Plugin } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { if (!inMlm) { @@ -607,17 +621,14 @@ public class MotherlodePlugin extends Plugin rocks.remove(gameObject); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { // on region changes the tiles get set to null veins.clear(); rocks.clear(); - } - else if (event.getGameState() == GameState.LOGGED_IN) - { + inMlm = checkInMlm(); } else if (event.getGameState() == GameState.LOGIN_SCREEN) @@ -627,8 +638,7 @@ public class MotherlodePlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + void onItemContainerChanged(ItemContainerChanged event) { final ItemContainer container = event.getItemContainer(); @@ -700,7 +710,9 @@ public class MotherlodePlugin extends Plugin private boolean checkInMlm() { - if (client.getGameState() != GameState.LOGGED_IN) + GameState gameState = client.getGameState(); + if (gameState != GameState.LOGGED_IN + && gameState != GameState.LOADING) { return false; } @@ -735,8 +747,7 @@ public class MotherlodePlugin extends Plugin return Perspective.getTileHeight(client, localPoint, 0) < UPPER_FLOOR_HEIGHT; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("motherlode")) { @@ -762,7 +773,6 @@ public class MotherlodePlugin extends Plugin this.payDirtMsg = config.payDirtMsg(); } - @Subscribe private void onOverheadTextChanged(OverheadTextChanged event) { if (!payDirtMsg || Strings.isNullOrEmpty(event.getOverheadText()) || !(event.getActor() instanceof NPC)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightPlugin.java index ded370e957..aedf4adf95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mousehighlight/MouseHighlightPlugin.java @@ -39,7 +39,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -63,6 +63,9 @@ public class MouseHighlightPlugin extends Plugin @Inject private MouseHighlightOverlay overlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean mainTooltip; @Getter(AccessLevel.PACKAGE) @@ -84,6 +87,7 @@ public class MouseHighlightPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); adjustTips(); overlayManager.add(overlay); @@ -92,12 +96,21 @@ public class MouseHighlightPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + resetTips(); overlayManager.remove(overlay); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -105,8 +118,7 @@ public class MouseHighlightPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() == WidgetID.SPELLBOOK_GROUP_ID || event.getGroupId() == WidgetID.COMBAT_GROUP_ID) { @@ -114,8 +126,7 @@ public class MouseHighlightPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { adjustTips(); } @@ -168,8 +179,7 @@ public class MouseHighlightPlugin extends Plugin widget.setHidden(hidden); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("motherlode")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAPlugin.java index 907f66f03d..a5531dbcde 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAPlugin.java @@ -82,11 +82,6 @@ public class MTAPlugin extends Plugin overlayManager.add(inventoryOverlay); this.rooms = new MTARoom[]{alchemyRoom, graveyardRoom, telekineticRoom, enchantmentRoom}; - - for (MTARoom room : rooms) - { - eventBus.register(room); - } } @Override @@ -102,5 +97,4 @@ public class MTAPlugin extends Plugin telekineticRoom.resetRoom(); } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/alchemy/AlchemyRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/alchemy/AlchemyRoom.java index 186497182f..98f129bb61 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/alchemy/AlchemyRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/alchemy/AlchemyRoom.java @@ -51,7 +51,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetItem; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.mta.MTAConfig; import net.runelite.client.plugins.mta.MTAPlugin; @@ -79,6 +79,7 @@ public class AlchemyRoom extends MTARoom private final Client client; private final ItemManager itemManager; private final InfoBoxManager infoBoxManager; + private final EventBus eventBus; private AlchemyItem best; private Cupboard suggestion; @@ -86,19 +87,30 @@ public class AlchemyRoom extends MTARoom private boolean alchemy; @Inject - private AlchemyRoom(final Client client, final MTAConfig config, final MTAPlugin plugin, final ItemManager itemManager, final InfoBoxManager infoBoxManager) + private AlchemyRoom(final Client client, final MTAConfig config, final MTAPlugin plugin, final ItemManager itemManager, final InfoBoxManager infoBoxManager, final EventBus eventBus) { super(config); this.client = client; this.plugin = plugin; this.itemManager = itemManager; this.infoBoxManager = infoBoxManager; + this.eventBus = eventBus; this.alchemy = config.alchemy(); + + addSubscriptions(); } - @Subscribe - public void onGameTick(GameTick event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onGameTick(GameTick event) { if (!inside() || !this.alchemy) { @@ -130,9 +142,7 @@ public class AlchemyRoom extends MTARoom } } - - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { if (!inside()) { @@ -203,8 +213,7 @@ public class AlchemyRoom extends MTARoom } } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { @@ -215,8 +224,7 @@ public class AlchemyRoom extends MTARoom } } - @Subscribe - public void onChatMessage(ChatMessage wrapper) + private void onChatMessage(ChatMessage wrapper) { if (!inside() || !config.alchemy()) { @@ -259,8 +267,7 @@ public class AlchemyRoom extends MTARoom } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("mta") || !event.getKey().equals("alchemy")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java index 40a46c332d..4e72118d6e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/enchantment/EnchantmentRoom.java @@ -40,7 +40,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemDespawned; import net.runelite.api.events.ItemSpawned; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.mta.MTAConfig; import net.runelite.client.plugins.mta.MTARoom; @@ -50,21 +50,33 @@ public class EnchantmentRoom extends MTARoom private static final int MTA_ENCHANT_REGION = 13462; private final Client client; + private final EventBus eventBus; private final List dragonstones = new ArrayList<>(); private boolean enchantment; @Inject - private EnchantmentRoom(final MTAConfig config, final Client client) + private EnchantmentRoom(final MTAConfig config, final Client client, final EventBus eventBus) { super(config); this.client = client; + this.eventBus = eventBus; this.enchantment = config.enchantment(); + + addSubscriptions(); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ItemSpawned.class, this, this::onItemSpawned); + eventBus.subscribe(ItemDespawned.class, this, this::onItemDespawned); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOADING) { @@ -72,8 +84,7 @@ public class EnchantmentRoom extends MTARoom } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (!inside() || !this.enchantment) { @@ -108,8 +119,7 @@ public class EnchantmentRoom extends MTARoom return nearest; } - @Subscribe - public void onItemSpawned(ItemSpawned itemSpawned) + private void onItemSpawned(ItemSpawned itemSpawned) { final Item item = itemSpawned.getItem(); final Tile tile = itemSpawned.getTile(); @@ -122,8 +132,7 @@ public class EnchantmentRoom extends MTARoom } } - @Subscribe - public void onItemDespawned(ItemDespawned itemDespawned) + private void onItemDespawned(ItemDespawned itemDespawned) { final Item item = itemDespawned.getItem(); final Tile tile = itemDespawned.getTile(); @@ -136,8 +145,7 @@ public class EnchantmentRoom extends MTARoom } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("mta") || !event.getKey().equals("enchantment")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardRoom.java index 5cfe0f16fa..901509a2b0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/graveyard/GraveyardRoom.java @@ -38,7 +38,7 @@ import net.runelite.api.Player; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.mta.MTAConfig; import net.runelite.client.plugins.mta.MTAPlugin; @@ -55,21 +55,32 @@ public class GraveyardRoom extends MTARoom private final MTAPlugin plugin; private final ItemManager itemManager; private final InfoBoxManager infoBoxManager; + private final EventBus eventBus; private GraveyardCounter counter; private boolean graveyard; @Inject - private GraveyardRoom(final MTAConfig config, final Client client, final MTAPlugin plugin, final ItemManager itemManager, final InfoBoxManager infoBoxManager) + private GraveyardRoom(final MTAConfig config, final Client client, final MTAPlugin plugin, final ItemManager itemManager, final InfoBoxManager infoBoxManager, final EventBus eventBus) { super(config); this.client = client; this.plugin = plugin; this.itemManager = itemManager; this.infoBoxManager = infoBoxManager; + this.eventBus = eventBus; this.graveyard = config.graveyard(); + + addSubscriptions(); + } + + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); } @Override @@ -80,8 +91,7 @@ public class GraveyardRoom extends MTARoom && player.getWorldLocation().getPlane() == 1; } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { if ((!inside() || !this.graveyard) && this.counter != null) { @@ -90,8 +100,7 @@ public class GraveyardRoom extends MTARoom } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (!inside()) { @@ -114,8 +123,7 @@ public class GraveyardRoom extends MTARoom } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("mta") || !event.getKey().equals("graveyard")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/telekinetic/TelekineticRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/telekinetic/TelekineticRoom.java index 2023ff3166..262cd5b53e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/telekinetic/TelekineticRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/telekinetic/TelekineticRoom.java @@ -46,15 +46,12 @@ import net.runelite.api.NPC; import net.runelite.api.NpcID; import net.runelite.api.NullObjectID; import net.runelite.api.Perspective; -import net.runelite.api.Projectile; -import net.runelite.api.ProjectileID; import net.runelite.api.WallObject; import net.runelite.api.coords.Angle; import net.runelite.api.coords.Direction; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; -import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.GroundObjectSpawned; @@ -62,7 +59,7 @@ import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.widgets.WidgetID; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.mta.MTAConfig; import net.runelite.client.plugins.mta.MTARoom; @@ -84,16 +81,26 @@ public class TelekineticRoom extends MTARoom private Rectangle bounds; private NPC guardian; private Maze maze; - - private boolean telekinetic; + private EventBus eventBus; @Inject - private TelekineticRoom(final MTAConfig config, final Client client) + private TelekineticRoom(MTAConfig config, Client client, EventBus eventBus) { super(config); this.client = client; + this.eventBus = eventBus; - this.telekinetic = config.telekinetic(); + addSubscriptions(); + } + + private void addSubscriptions() + { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); } public void resetRoom() @@ -102,7 +109,6 @@ public class TelekineticRoom extends MTARoom telekineticWalls.clear(); } - @Subscribe public void onWallObjectSpawned(WallObjectSpawned event) { final WallObject wall = event.getWallObject(); @@ -114,7 +120,6 @@ public class TelekineticRoom extends MTARoom telekineticWalls.add(wall); } - @Subscribe public void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) @@ -125,8 +130,7 @@ public class TelekineticRoom extends MTARoom } } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { final GroundObject object = event.getGroundObject(); if (object.getId() == TELEKINETIC_FINISH) @@ -135,12 +139,11 @@ public class TelekineticRoom extends MTARoom } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { - if (!this.telekinetic - || !inside() - || client.getGameState() != GameState.LOGGED_IN) + if (!config.telekinetic() + || !inside() + || client.getGameState() != GameState.LOGGED_IN) { maze = null; moves.clear(); @@ -183,14 +186,6 @@ public class TelekineticRoom extends MTARoom } else { - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == ProjectileID.TELEKINETIC_SPELL) - { - return; - } - } - log.debug("Rebuilding moves due to guardian move"); this.moves = build(); } @@ -203,8 +198,7 @@ public class TelekineticRoom extends MTARoom } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); @@ -214,28 +208,16 @@ public class TelekineticRoom extends MTARoom } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { NPC npc = event.getNpc(); - if (npc.equals(guardian)) + if (npc == guardian) { guardian = null; } } - @Subscribe - public void onConfigChanged(ConfigChanged event) - { - if (!event.getGroup().equals("mta") || !event.getKey().equals("telekinetic")) - { - return; - } - - this.telekinetic = config.telekinetic(); - } - @Override public boolean inside() { @@ -286,11 +268,7 @@ public class TelekineticRoom extends MTARoom Direction next = moves.pop(); WorldArea areaNext = getIndicatorLine(next); - WorldPoint nearestNext = null; - if (areaNext != null) - { - nearestNext = nearest(areaNext, current); - } + WorldPoint nearestNext = nearest(areaNext, current); if (moves.isEmpty()) { @@ -302,20 +280,9 @@ public class TelekineticRoom extends MTARoom Direction after = moves.peek(); moves.push(next); WorldArea areaAfter = getIndicatorLine(after); - WorldPoint nearestAfter = null; - if (areaAfter != null) - { - nearestAfter = nearest(areaAfter, nearestNext); - } + WorldPoint nearestAfter = nearest(areaAfter, nearestNext); - if (areaNext != null) - { - return nearest(areaNext, nearestAfter); - } - else - { - return nearestAfter; - } + return nearest(areaNext, nearestAfter); } private static int manhattan(WorldPoint point1, WorldPoint point2) @@ -405,7 +372,7 @@ public class TelekineticRoom extends MTARoom WorldPoint nghbWorld = WorldPoint.fromLocal(client, neighbour); if (!nghbWorld.equals(next) - && !closed.contains(nghbWorld)) + && !closed.contains(nghbWorld)) { int score = scores.get(next) + 1; @@ -457,10 +424,10 @@ public class TelekineticRoom extends MTARoom private LocalPoint[] neighbours(LocalPoint point) { return new LocalPoint[] - { - neighbour(point, Direction.NORTH), neighbour(point, Direction.SOUTH), - neighbour(point, Direction.EAST), neighbour(point, Direction.WEST) - }; + { + neighbour(point, Direction.NORTH), neighbour(point, Direction.SOUTH), + neighbour(point, Direction.EAST), neighbour(point, Direction.WEST) + }; } private LocalPoint neighbour(LocalPoint point, Direction direction) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java index 9f6fb91f2b..337b9539b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/multiindicators/MultiIndicatorsPlugin.java @@ -51,7 +51,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.geometry.Geometry; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -86,6 +86,9 @@ public class MultiIndicatorsPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private GeneralPath[] multicombatPathToDisplay; @@ -130,6 +133,7 @@ public class MultiIndicatorsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(minimapOverlay); @@ -148,12 +152,20 @@ public class MultiIndicatorsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(minimapOverlay); uninitializePaths(); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + private void initializePaths() { multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z]; @@ -366,8 +378,7 @@ public class MultiIndicatorsPlugin extends Plugin return false; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("multiindicators")) { @@ -386,8 +397,7 @@ public class MultiIndicatorsPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java index 1974109215..cac7bd30f0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java @@ -45,7 +45,7 @@ import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -79,6 +79,9 @@ public class MusicIndicatorPlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + // Mapping of relevant varps to their values, used to compare against new values private final Map musicTrackVarpValues = new HashMap<>(); @@ -87,17 +90,25 @@ public class MusicIndicatorPlugin extends Plugin @Override public void startUp() { + addSubscriptions(); loggingIn = true; } @Override public void shutDown() { + eventBus.unregister(this); musicTrackVarpValues.clear(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -109,8 +120,7 @@ public class MusicIndicatorPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (!loggingIn) { @@ -126,8 +136,7 @@ public class MusicIndicatorPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { int idx = event.getIndex(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java index 683666c2bc..715f9ee64a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/musiclist/MusicListPlugin.java @@ -48,7 +48,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxTextInput; import net.runelite.client.plugins.Plugin; @@ -70,6 +70,9 @@ public class MusicListPlugin extends Plugin @Inject private ChatboxPanelManager chatboxPanelManager; + @Inject + private EventBus eventBus; + private ChatboxTextInput searchInput; private Widget musicSearchButton; @@ -82,12 +85,16 @@ public class MusicListPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + clientThread.invoke(this::addMusicButtons); } @Override protected void shutDown() { + eventBus.unregister(this); + Widget header = client.getWidget(WidgetInfo.MUSIC_WINDOW); if (header != null) { @@ -97,8 +104,14 @@ public class MusicListPlugin extends Plugin tracks = null; } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(VarClientIntChanged.class, this, this::onVarClientIntChanged); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN) { @@ -108,8 +121,7 @@ public class MusicListPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded widgetLoaded) + private void onWidgetLoaded(WidgetLoaded widgetLoaded) { if (widgetLoaded.getGroupId() == WidgetID.MUSIC_GROUP_ID) { @@ -160,8 +172,7 @@ public class MusicListPlugin extends Plugin musicFilterButton.revalidate(); } - @Subscribe - public void onVarClientIntChanged(VarClientIntChanged varClientIntChanged) + private void onVarClientIntChanged(VarClientIntChanged varClientIntChanged) { if (isChatboxOpen() && !isOnMusicTab()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java index 63fffe5396..9c32dabc51 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZonePlugin.java @@ -41,7 +41,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -72,6 +72,9 @@ public class NightmareZonePlugin extends Plugin @Inject private NightmareZoneOverlay overlay; + @Inject + private EventBus eventBus; + // This starts as true since you need to get // above the threshold before sending notifications private boolean absorptionNotificationSend = true; @@ -97,6 +100,7 @@ public class NightmareZonePlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlay.removeAbsorptionCounter(); @@ -105,6 +109,8 @@ public class NightmareZonePlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlay.removeAbsorptionCounter(); @@ -116,8 +122,14 @@ public class NightmareZonePlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("nightmareZone")) { @@ -134,8 +146,7 @@ public class NightmareZonePlugin extends Plugin return configManager.getConfig(NightmareZoneConfig.class); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (isNotInNightmareZone()) { @@ -153,8 +164,7 @@ public class NightmareZonePlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE || isNotInNightmareZone()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java index e765944fbd..4b5777c8fc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/notes/NotesPlugin.java @@ -29,7 +29,7 @@ import java.awt.image.BufferedImage; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.SessionOpen; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -52,6 +52,9 @@ public class NotesPlugin extends Plugin @Inject private NotesConfig config; + @Inject + private EventBus eventBus; + private NotesPanel panel; private NavigationButton navButton; @@ -64,6 +67,8 @@ public class NotesPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(SessionOpen.class, this, this::onSessionOpen); + panel = injector.getInstance(NotesPanel.class); panel.init(config); @@ -82,11 +87,12 @@ public class NotesPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + clientToolbar.removeNavigation(navButton); } - @Subscribe - public void onSessionOpen(SessionOpen event) + private void onSessionOpen(SessionOpen event) { // update notes String data = config.notesData(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 0f8f150190..62cf808211 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -66,7 +66,7 @@ import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -116,6 +116,9 @@ public class NpcIndicatorsPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventbus; + @Setter(AccessLevel.PACKAGE) private boolean hotKeyPressed = false; @@ -207,6 +210,7 @@ public class NpcIndicatorsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(npcSceneOverlay); overlayManager.add(npcMinimapOverlay); @@ -222,6 +226,8 @@ public class NpcIndicatorsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventbus.unregister(this); + overlayManager.remove(npcSceneOverlay); overlayManager.remove(npcMinimapOverlay); deadNpcsToDisplay.clear(); @@ -234,8 +240,21 @@ public class NpcIndicatorsPlugin extends Plugin keyManager.unregisterKeyListener(inputListener); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventbus.subscribe(FocusChanged.class, this, this::onFocusChanged); + eventbus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventbus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventbus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventbus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged); + eventbus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventbus.subscribe(GraphicsObjectCreated.class, this, this::onGraphicsObjectCreated); + eventbus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING) @@ -248,8 +267,7 @@ public class NpcIndicatorsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (!configChanged.getGroup().equals("npcindicators")) { @@ -262,8 +280,7 @@ public class NpcIndicatorsPlugin extends Plugin rebuildAllNpcs(); } - @Subscribe - public void onFocusChanged(FocusChanged focusChanged) + private void onFocusChanged(FocusChanged focusChanged) { if (!focusChanged.isFocused()) { @@ -271,8 +288,7 @@ public class NpcIndicatorsPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { MenuEntry[] menuEntries = client.getMenuEntries(); String target = event.getTarget(); @@ -306,8 +322,7 @@ public class NpcIndicatorsPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked click) + private void onMenuOptionClicked(MenuOptionClicked click) { if (click.getMenuAction() != MenuAction.RUNELITE || (!click.getOption().equals(TAG) @@ -344,8 +359,7 @@ public class NpcIndicatorsPlugin extends Plugin click.consume(); } - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) + private void onNpcSpawned(NpcSpawned npcSpawned) { NPC npc = npcSpawned.getNpc(); highlightNpcIfMatch(npc); @@ -356,8 +370,7 @@ public class NpcIndicatorsPlugin extends Plugin } } - @Subscribe - public void onNpcDefinitionChanged(NpcDefinitionChanged event) + private void onNpcDefinitionChanged(NpcDefinitionChanged event) { NPC npc = event.getNpc(); highlightNpcIfMatch(npc); @@ -373,8 +386,7 @@ public class NpcIndicatorsPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { final NPC npc = npcDespawned.getNpc(); @@ -386,8 +398,7 @@ public class NpcIndicatorsPlugin extends Plugin highlightedNpcs.remove(npc); } - @Subscribe - public void onGraphicsObjectCreated(GraphicsObjectCreated event) + private void onGraphicsObjectCreated(GraphicsObjectCreated event) { final GraphicsObject go = event.getGraphicsObject(); @@ -397,8 +408,7 @@ public class NpcIndicatorsPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { removeOldHighlightedRespawns(); validateSpawnedNpcs(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java index 18e9d4b38b..c4129f3007 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcstatus/NpcStatusPlugin.java @@ -47,7 +47,7 @@ import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.SpotAnimationChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.NPCManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -80,6 +80,9 @@ public class NpcStatusPlugin extends Plugin @Inject private NpcStatusOverlay npcStatusOverlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final Set memorizedNPCs = new HashSet<>(); @@ -101,6 +104,8 @@ public class NpcStatusPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.getRange = config.getRange(); overlayManager.add(npcStatusOverlay); } @@ -108,12 +113,24 @@ public class NpcStatusPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(npcStatusOverlay); memorizedNPCs.clear(); } - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onNpcSpawned(NpcSpawned npcSpawned) { final NPC npc = npcSpawned.getNpc(); final String npcName = npc.getName(); @@ -130,15 +147,13 @@ public class NpcStatusPlugin extends Plugin memorizedNPCs.add(new MemorizedNPC(npc, AttackSpeed, npc.getWorldArea())); } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { final NPC npc = npcDespawned.getNpc(); memorizedNPCs.removeIf(c -> c.getNpc() == npc); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING) @@ -147,8 +162,7 @@ public class NpcStatusPlugin extends Plugin } } - @Subscribe - public void onHitsplatApplied(HitsplatApplied event) + private void onHitsplatApplied(HitsplatApplied event) { if (event.getActor().getInteracting() != client.getLocalPlayer()) { @@ -181,8 +195,7 @@ public class NpcStatusPlugin extends Plugin } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged event) + private void onSpotAnimationChanged(SpotAnimationChanged event) { if ((event.getActor().getSpotAnimation() == GraphicID.SPLASH) && event.getActor() instanceof NPC) { @@ -272,15 +285,13 @@ public class NpcStatusPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { checkStatus(); lastPlayerLocation = client.getLocalPlayer().getWorldArea(); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (!configChanged.getGroup().equals("npcstatus")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java index 75335426cb..f4f78126c7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java @@ -41,7 +41,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Constants; import net.runelite.api.ItemID; @@ -59,7 +58,7 @@ import net.runelite.api.events.NpcSpawned; import net.runelite.api.geometry.Geometry; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -67,7 +66,6 @@ import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.WildcardMatcher; -@Slf4j @PluginDescriptor( name = "NPC Aggression Timer", description = "Highlights the unaggressive area of NPCs nearby and timer until it becomes active", @@ -121,6 +119,9 @@ public class NpcAggroAreaPlugin extends Plugin @Inject private Notifier notifier; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final WorldPoint[] safeCenters = new WorldPoint[2]; @@ -162,6 +163,7 @@ public class NpcAggroAreaPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); if (this.showNotWorkingOverlay) @@ -177,6 +179,8 @@ public class NpcAggroAreaPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + removeTimer(); overlayManager.remove(overlay); if (notWorkingOverlayShown) @@ -194,6 +198,14 @@ public class NpcAggroAreaPlugin extends Plugin Arrays.fill(linesToDisplay, null); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + private Area generateSafeArea() { final Area area = new Area(); @@ -339,8 +351,7 @@ public class NpcAggroAreaPlugin extends Plugin checkAreaNpcs(client.getCachedNPCs()); } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { if (this.alwaysActive) { @@ -350,8 +361,7 @@ public class NpcAggroAreaPlugin extends Plugin checkAreaNpcs(event.getNpc()); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { WorldPoint newLocation = client.getLocalPlayer().getWorldLocation(); if (lastPlayerLocation != null && safeCenters[1] == null && newLocation.distanceTo2D(lastPlayerLocation) > SAFE_AREA_RADIUS * 4) @@ -390,8 +400,7 @@ public class NpcAggroAreaPlugin extends Plugin lastPlayerLocation = newLocation; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("npcUnaggroArea")) { @@ -481,8 +490,7 @@ public class NpcAggroAreaPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { 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 0f20e4c8df..f8f86cd241 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 @@ -42,7 +42,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import static net.runelite.api.Constants.REGION_SIZE; import net.runelite.api.DecorativeObject; @@ -65,14 +64,13 @@ 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.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -@Slf4j @PluginDescriptor( name = "Object Markers", description = "Enable marking of objects using the Shift key", @@ -110,6 +108,9 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener @Inject private KeyManager keyManager; + @Inject + private EventBus eventbus; + @Getter(AccessLevel.PACKAGE) private RenderStyle objectMarkerRenderStyle; @Getter(AccessLevel.PACKAGE) @@ -129,6 +130,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); keyManager.registerKeyListener(this); @@ -137,6 +139,8 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener @Override protected void shutDown() { + eventbus.unregister(this); + overlayManager.remove(overlay); keyManager.unregisterKeyListener(this); points.clear(); @@ -144,6 +148,19 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener hotKeyPressed = false; } + private void addSubscriptions() + { + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(FocusChanged.class, this, this::onFocusChanged); + eventbus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventbus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned); + eventbus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventbus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned); + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventbus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventbus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + @Override public void keyTyped(KeyEvent e) { @@ -168,8 +185,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onFocusChanged(final FocusChanged event) + private void onFocusChanged(final FocusChanged event) { if (!event.isFocused()) { @@ -177,34 +193,29 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { final GameObject eventObject = event.getGameObject(); checkObjectPoints(eventObject); } - @Subscribe - public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + private void onDecorativeObjectSpawned(DecorativeObjectSpawned event) { final DecorativeObject eventObject = event.getDecorativeObject(); checkObjectPoints(eventObject); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { objects.remove(event.getGameObject()); } - @Subscribe - public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + private void onDecorativeObjectDespawned(DecorativeObjectDespawned event) { objects.remove(event.getDecorativeObject()); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { GameState gameState = gameStateChanged.getGameState(); if (gameState == GameState.LOADING) @@ -229,8 +240,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!hotKeyPressed || event.getType() != MenuAction.EXAMINE_OBJECT.getId()) { @@ -286,8 +296,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener client.setMenuEntries(menuEntries); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (event.getMenuAction() != MenuAction.RUNELITE || (!event.getOption().equals(MARK) @@ -445,8 +454,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener }.getType()); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("objectindicators")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java index e65b070674..4b1a5a223f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/opponentinfo/OpponentInfoPlugin.java @@ -42,7 +42,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.InteractingChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -73,6 +73,9 @@ public class OpponentInfoPlugin extends Plugin @Inject private PlayerComparisonOverlay playerComparisonOverlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private HiscoreEndpoint hiscoreEndpoint = HiscoreEndpoint.NORMAL; @@ -98,6 +101,7 @@ public class OpponentInfoPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(opponentInfoOverlay); overlayManager.add(playerComparisonOverlay); @@ -106,14 +110,23 @@ public class OpponentInfoPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + lastOpponent = null; lastTime = null; overlayManager.remove(opponentInfoOverlay); overlayManager.remove(playerComparisonOverlay); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() != GameState.LOGGED_IN) { @@ -139,8 +152,7 @@ public class OpponentInfoPlugin extends Plugin } } - @Subscribe - public void onInteractingChanged(InteractingChanged event) + private void onInteractingChanged(InteractingChanged event) { if (event.getSource() != client.getLocalPlayer()) { @@ -158,8 +170,7 @@ public class OpponentInfoPlugin extends Plugin lastOpponent = opponent; } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { if (lastOpponent != null && lastTime != null @@ -171,8 +182,7 @@ public class OpponentInfoPlugin extends Plugin } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("opponentinfo")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index ac83ef69e1..738d1179ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -61,7 +61,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.input.KeyListener; @@ -126,6 +126,9 @@ public class PartyPlugin extends Plugin implements KeyListener @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + @Inject @Named("developerMode") boolean developerMode; @@ -158,6 +161,7 @@ public class PartyPlugin extends Plugin implements KeyListener protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(partyStatsOverlay); overlayManager.add(partyPingOverlay); @@ -171,6 +175,8 @@ public class PartyPlugin extends Plugin implements KeyListener @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + partyDataMap.clear(); pendingTilePings.clear(); worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); @@ -185,14 +191,30 @@ public class PartyPlugin extends Plugin implements KeyListener sendAlert = false; } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(OverlayMenuClicked.class, this, this::onOverlayMenuClicked); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(TilePing.class, this, this::onTilePing); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(SkillUpdate.class, this, this::onSkillUpdate); + eventBus.subscribe(LocationUpdate.class, this, this::onLocationUpdate); + eventBus.subscribe(UserJoin.class, this, this::onUserJoin); + eventBus.subscribe(UserSync.class, this, this::onUserSync); + eventBus.subscribe(UserPart.class, this, this::onUserPart); + eventBus.subscribe(PartyChanged.class, this, this::onPartyChanged); + eventBus.subscribe(CommandExecuted.class, this, this::onCommandExecuted); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + @Provides public PartyConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(PartyConfig.class); } - @Subscribe - public void onOverlayMenuClicked(OverlayMenuClicked event) + private void onOverlayMenuClicked(OverlayMenuClicked event) { if (event.getEntry().getMenuAction() == MenuAction.RUNELITE_OVERLAY && event.getEntry().getTarget().equals("Party") && @@ -217,8 +239,7 @@ public class PartyPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (!hotkeyDown || client.isMenuOpen() || party.getMembers().isEmpty() || !this.pings) { @@ -257,8 +278,7 @@ public class PartyPlugin extends Plugin implements KeyListener wsClient.send(tilePing); } - @Subscribe - public void onTilePing(TilePing event) + private void onTilePing(TilePing event) { if (this.pings) { @@ -303,8 +323,7 @@ public class PartyPlugin extends Plugin implements KeyListener wsClient.send(locationUpdate); } - @Subscribe - public void onGameTick(final GameTick event) + private void onGameTick(final GameTick event) { if (sendAlert && client.getGameState() == GameState.LOGGED_IN) { @@ -349,8 +368,7 @@ public class PartyPlugin extends Plugin implements KeyListener lastPray = currentPrayer; } - @Subscribe - public void onSkillUpdate(final SkillUpdate event) + private void onSkillUpdate(final SkillUpdate event) { final PartyData partyData = getPartyData(event.getMemberId()); @@ -371,8 +389,7 @@ public class PartyPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onLocationUpdate(final LocationUpdate event) + private void onLocationUpdate(final LocationUpdate event) { final PartyData partyData = getPartyData(event.getMemberId()); @@ -384,8 +401,7 @@ public class PartyPlugin extends Plugin implements KeyListener partyData.getWorldMapPoint().setWorldPoint(event.getWorldPoint()); } - @Subscribe - public void onUserJoin(final UserJoin event) + private void onUserJoin(final UserJoin event) { final PartyData partyData = getPartyData(event.getMemberId()); @@ -413,8 +429,7 @@ public class PartyPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onUserSync(final UserSync event) + private void onUserSync(final UserSync event) { final int currentHealth = client.getBoostedSkillLevel(Skill.HITPOINTS); final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER); @@ -434,8 +449,7 @@ public class PartyPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onUserPart(final UserPart event) + private void onUserPart(final UserPart event) { final PartyData removed = partyDataMap.remove(event.getMemberId()); @@ -459,8 +473,7 @@ public class PartyPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onPartyChanged(final PartyChanged event) + private void onPartyChanged(final PartyChanged event) { // Reset party partyDataMap.clear(); @@ -468,8 +481,7 @@ public class PartyPlugin extends Plugin implements KeyListener worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); } - @Subscribe - public void onCommandExecuted(CommandExecuted commandExecuted) + private void onCommandExecuted(CommandExecuted commandExecuted) { if (!developerMode || !commandExecuted.getCommand().equals("partyinfo")) { @@ -515,8 +527,7 @@ public class PartyPlugin extends Plugin implements KeyListener }); } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void onFocusChanged(FocusChanged event) { if (!event.isFocused()) { @@ -561,8 +572,7 @@ public class PartyPlugin extends Plugin implements KeyListener .build()); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("party")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/performancestats/PerformanceStatsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/performancestats/PerformanceStatsPlugin.java index 41fdfedfc6..b6bc491ce4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/performancestats/PerformanceStatsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/performancestats/PerformanceStatsPlugin.java @@ -52,7 +52,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.game.NPCManager; @@ -109,6 +109,9 @@ public class PerformanceStatsPlugin extends Plugin @Inject private WSClient wsClient; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean enabled = false; @Getter(AccessLevel.PACKAGE) @@ -138,6 +141,8 @@ public class PerformanceStatsPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + this.submitTimeout = config.submitTimeout(); overlayManager.add(performanceTrackerOverlay); @@ -147,14 +152,30 @@ public class PerformanceStatsPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(performanceTrackerOverlay); wsClient.unregisterMessage(Performance.class); disable(); reset(); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(OverlayMenuClicked.class, this, this::onOverlayMenuClicked); + eventBus.subscribe(Performance.class, this, this::onPerformance); + eventBus.subscribe(UserSync.class, this, this::onUserSync); + eventBus.subscribe(UserPart.class, this, this::onUserPart); + eventBus.subscribe(PartyChanged.class, this, this::onPartyChanged); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -167,8 +188,7 @@ public class PerformanceStatsPlugin extends Plugin } } - @Subscribe - public void onHitsplatApplied(HitsplatApplied e) + private void onHitsplatApplied(HitsplatApplied e) { if (isPaused()) { @@ -187,8 +207,7 @@ public class PerformanceStatsPlugin extends Plugin } } - @Subscribe - public void onExperienceChanged(ExperienceChanged c) + private void onExperienceChanged(ExperienceChanged c) { if (isPaused() || hopping) { @@ -223,8 +242,7 @@ public class PerformanceStatsPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent e) + private void onScriptCallbackEvent(ScriptCallbackEvent e) { // Handles Fake XP drops (Ironman in PvP, DMM Cap, 200m xp, etc) if (isPaused()) @@ -255,8 +273,7 @@ public class PerformanceStatsPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick t) + private void onGameTick(GameTick t) { oldTarget = client.getLocalPlayer().getInteracting(); @@ -295,8 +312,7 @@ public class PerformanceStatsPlugin extends Plugin sendPerformance(); } - @Subscribe - public void onOverlayMenuClicked(OverlayMenuClicked c) + private void onOverlayMenuClicked(OverlayMenuClicked c) { if (!c.getOverlay().equals(performanceTrackerOverlay)) { @@ -429,14 +445,12 @@ public class PerformanceStatsPlugin extends Plugin } } - @Subscribe - public void onPerformance(final Performance performance) + private void onPerformance(final Performance performance) { partyDataMap.put(performance.getMemberId(), performance); } - @Subscribe - public void onUserSync(final UserSync event) + private void onUserSync(final UserSync event) { if (isEnabled()) { @@ -444,21 +458,18 @@ public class PerformanceStatsPlugin extends Plugin } } - @Subscribe - public void onUserPart(final UserPart event) + private void onUserPart(final UserPart event) { partyDataMap.remove(event.getMemberId()); } - @Subscribe - public void onPartyChanged(final PartyChanged event) + private void onPartyChanged(final PartyChanged event) { // Reset party partyDataMap.clear(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("performancestats")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java index 3329f6f520..c178ffb901 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pestcontrol/PestControlPlugin.java @@ -58,7 +58,7 @@ import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -132,6 +132,9 @@ public class PestControlPlugin extends Plugin @Inject private PortalWeaknessOverlay portalWeaknessOverlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Game game; @@ -185,17 +188,33 @@ public class PestControlPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); loadPlugin(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); unloadPlugin(); } - @Subscribe - public void onConfigChanged(ConfigChanged configEvent) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(GroundObjectChanged.class, this, this::onGroundObjectChanged); + eventBus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned); + } + + private void onConfigChanged(ConfigChanged configEvent) { if (configEvent.getGroup().equals("pestcontrol")) { @@ -341,7 +360,6 @@ public class PestControlPlugin extends Plugin } } - @Subscribe public void onGameStateChanged(GameStateChanged event) { // LOGGED_IN also triggers when teleporting to the island @@ -486,8 +504,7 @@ public class PestControlPlugin extends Plugin handlePointsInfoboxCounter(); } - @Subscribe - public void onGameTick(GameTick gameTickEvent) + private void onGameTick(GameTick gameTickEvent) { // Check for widgets on main island if (game == null && isOnPestControlMainIsland()) @@ -551,8 +568,7 @@ public class PestControlPlugin extends Plugin game.onGameTick(gameTickEvent); } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { if (game != null && chatMessage.getType() == ChatMessageType.GAMEMESSAGE) { @@ -564,8 +580,7 @@ public class PestControlPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (game != null) { @@ -640,40 +655,34 @@ public class PestControlPlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { handleTileObject(event.getTile(), event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { unlistTileObject(event.getPrevious()); handleTileObject(event.getTile(), event.getGameObject()); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { unlistTileObject(event.getGameObject()); } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { handleTileObject(event.getTile(), event.getGroundObject()); } - @Subscribe - public void onGroundObjectChanged(GroundObjectChanged event) + private void onGroundObjectChanged(GroundObjectChanged event) { unlistTileObject(event.getPrevious()); handleTileObject(event.getTile(), event.getGroundObject()); } - @Subscribe - public void onGroundObjectDespawned(GroundObjectDespawned event) + private void onGroundObjectDespawned(GroundObjectDespawned event) { unlistTileObject(event.getGroundObject()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java index 50e04c26ee..cd90a63b47 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pileindicators/PileIndicatorsPlugin.java @@ -40,7 +40,7 @@ import net.runelite.api.Player; import net.runelite.api.Varbits; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -71,6 +71,9 @@ public class PileIndicatorsPlugin extends Plugin @Inject private PileIndicatorsOverlay overlay; + @Inject + private EventBus eventBus; + private boolean enablePlayers; private boolean wildyOnlyPlayer; private Color playerPileColor; @@ -95,12 +98,16 @@ public class PileIndicatorsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.remove(overlay); } @@ -196,8 +203,7 @@ public class PileIndicatorsPlugin extends Plugin return pileType; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("pileindicators")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java index a883d18e77..82c5e42bfa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerindicators/PlayerIndicatorsPlugin.java @@ -57,7 +57,7 @@ import net.runelite.api.events.ClanMemberLeft; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ClanManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -94,6 +94,9 @@ public class PlayerIndicatorsPlugin extends Plugin @Inject private ClanManager clanManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean highlightOwnPlayer; @Getter(AccessLevel.PACKAGE) @@ -162,6 +165,7 @@ public class PlayerIndicatorsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(playerIndicatorsOverlay); overlayManager.add(playerIndicatorsTileOverlay); @@ -172,15 +176,24 @@ public class PlayerIndicatorsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(playerIndicatorsOverlay); overlayManager.remove(playerIndicatorsTileOverlay); overlayManager.remove(playerIndicatorsMinimapOverlay); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ClanMemberJoined.class, this, this::onClanMemberJoined); + eventBus.subscribe(ClanMemberLeft.class, this, this::onClanMemberLeft); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + private List callers = new ArrayList<>(); - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("playerindicators")) { @@ -195,14 +208,12 @@ public class PlayerIndicatorsPlugin extends Plugin } } - @Subscribe - public void onClanMemberJoined(ClanMemberJoined event) + private void onClanMemberJoined(ClanMemberJoined event) { getCallerList(); } - @Subscribe - public void onClanMemberLeft(ClanMemberLeft event) + private void onClanMemberLeft(ClanMemberLeft event) { getCallerList(); } @@ -250,9 +261,7 @@ public class PlayerIndicatorsPlugin extends Plugin return false; } - - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) + private void onMenuEntryAdded(MenuEntryAdded menuEntryAdded) { int type = menuEntryAdded.getType(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/playerinfo/PlayerInfoCustomIndicator.java b/runelite-client/src/main/java/net/runelite/client/plugins/playerinfo/PlayerInfoCustomIndicator.java index 906cd981fb..85d155dac9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/playerinfo/PlayerInfoCustomIndicator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/playerinfo/PlayerInfoCustomIndicator.java @@ -25,7 +25,7 @@ package net.runelite.client.plugins.playerinfo; import java.awt.Color; -import java.awt.Image; +import java.awt.image.BufferedImage; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -54,7 +54,7 @@ public class PlayerInfoCustomIndicator extends InfoBox private final Client client; private final IndicatorType type; - PlayerInfoCustomIndicator(final Image image, final PlayerInfoPlugin plugin, final Client client, final IndicatorType type) + PlayerInfoCustomIndicator(final BufferedImage image, final PlayerInfoPlugin plugin, final Client client, final IndicatorType type) { super(image, plugin); this.plugin = plugin; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java index c2f09c8371..2be385662d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java @@ -33,7 +33,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.PluginChanged; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -56,6 +56,9 @@ public class PluginSorterPlugin extends Plugin @Inject private PluginSorterConfig config; + @Inject + private EventBus eventBus; + private boolean hidePlugins; private Color externalColor; private Color pvmColor; @@ -73,17 +76,24 @@ public class PluginSorterPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + updateColors(); } @Override protected void shutDown() throws Exception { - + eventBus.unregister(this); } - @Subscribe - public void onPluginChanged(PluginChanged pluginChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(PluginChanged.class, this, this::onPluginChanged); + } + + private void onPluginChanged(PluginChanged pluginChanged) { validatePlugins(); } @@ -102,8 +112,7 @@ public class PluginSorterPlugin extends Plugin updateColors(); } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (!configChanged.getGroup().equals("pluginsorter")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java index c71bfad61e..4592608dc9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java @@ -57,7 +57,7 @@ import net.runelite.api.events.GameObjectDespawned; import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.HiscoreManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -105,6 +105,9 @@ public class PohPlugin extends Plugin @Inject private BurnerOverlay burnerOverlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean showPortals; @Getter(AccessLevel.PACKAGE) @@ -142,6 +145,7 @@ public class PohPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(burnerOverlay); @@ -151,14 +155,26 @@ public class PohPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(burnerOverlay); pohObjects.clear(); incenseBurners.clear(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned); + eventBus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("poh")) { @@ -170,8 +186,7 @@ public class PohPlugin extends Plugin overlay.updateConfig(); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { final GameObject gameObject = event.getGameObject(); @@ -190,15 +205,13 @@ public class PohPlugin extends Plugin incenseBurners.put(event.getTile(), new IncenseBurner(gameObject.getId(), countdownTimer, randomTimer, null)); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { GameObject gameObject = event.getGameObject(); pohObjects.remove(gameObject); } - @Subscribe - public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + private void onDecorativeObjectSpawned(DecorativeObjectSpawned event) { DecorativeObject decorativeObject = event.getDecorativeObject(); if (PohIcons.getIcon(decorativeObject.getId()) != null) @@ -207,15 +220,13 @@ public class PohPlugin extends Plugin } } - @Subscribe - public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + private void onDecorativeObjectDespawned(DecorativeObjectDespawned event) { DecorativeObject decorativeObject = event.getDecorativeObject(); pohObjects.remove(decorativeObject); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { @@ -224,8 +235,7 @@ public class PohPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { final Actor actor = event.getActor(); final String actorName = actor.getName(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java index ef0a03b5e8..a492797b2d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poison/PoisonPlugin.java @@ -55,7 +55,7 @@ import net.runelite.api.events.PlayerDespawned; import net.runelite.api.events.VarbitChanged; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -114,6 +114,9 @@ public class PoisonPlugin extends Plugin @Inject private PoisonActorOverlay actorOverlay; + @Inject + private EventBus eventBus; + @Getter private int lastDamage; @@ -144,6 +147,7 @@ public class PoisonPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); actorOverlay.setFontSize(this.fontSize); overlayManager.add(poisonOverlay); @@ -162,6 +166,8 @@ public class PoisonPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(poisonOverlay); if (infobox != null) @@ -180,8 +186,17 @@ public class PoisonPlugin extends Plugin clientThread.invoke(this::resetHealthIcon); } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + } + + private void onVarbitChanged(VarbitChanged event) { final int poisonValue = client.getVar(VarPlayer.POISON); if (poisonValue != lastValue) @@ -229,7 +244,6 @@ public class PoisonPlugin extends Plugin } } - @Subscribe private void onHitsplatApplied(HitsplatApplied event) { Hitsplat.HitsplatType type = event.getHitsplat().getHitsplatType(); @@ -294,7 +308,6 @@ public class PoisonPlugin extends Plugin info.setLastDamageTick(tickCount); } - @Subscribe private void onGameTick(GameTick event) { int tickCount = client.getTickCount(); @@ -303,20 +316,17 @@ public class PoisonPlugin extends Plugin poisonedActors.values().removeIf(info -> info.getLastDamageTick() + POISON_TICK_TICKS + 5 < tickCount); } - @Subscribe private void onNpcDespawned(NpcDespawned event) { poisonedActors.remove(event.getNpc()); } - @Subscribe private void onPlayerDespawned(PlayerDespawned event) { poisonedActors.remove(event.getPlayer()); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals(PoisonConfig.GROUP)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java index 6e40c5ebe9..4e3ce27162 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayagainstplayer/PrayAgainstPlayerPlugin.java @@ -49,7 +49,7 @@ import net.runelite.api.events.InteractingChanged; import net.runelite.api.events.PlayerDespawned; import net.runelite.api.events.PlayerSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -103,6 +103,9 @@ public class PrayAgainstPlayerPlugin extends Plugin @Inject private PrayAgainstPlayerConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Color attackerPlayerColor; @Getter(AccessLevel.PACKAGE) @@ -140,8 +143,7 @@ public class PrayAgainstPlayerPlugin extends Plugin return configManager.getConfig(PrayAgainstPlayerConfig.class); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGGED_IN) { @@ -153,6 +155,7 @@ public class PrayAgainstPlayerPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); potentialPlayersAttackingMe = new ArrayList<>(); playersAttackingMe = new ArrayList<>(); @@ -163,12 +166,23 @@ public class PrayAgainstPlayerPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(overlayPrayerTab); } - @Subscribe - protected void onAnimationChanged(AnimationChanged animationChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + } + + private void onAnimationChanged(AnimationChanged animationChanged) { if ((animationChanged.getActor() instanceof Player) && (animationChanged.getActor().getInteracting() instanceof Player) && (animationChanged.getActor().getInteracting() == client.getLocalPlayer())) { @@ -206,8 +220,7 @@ public class PrayAgainstPlayerPlugin extends Plugin } } - @Subscribe - protected void onInteractingChanged(InteractingChanged interactingChanged) + private void onInteractingChanged(InteractingChanged interactingChanged) { // if someone interacts with you, add them to the potential attackers list if ((interactingChanged.getSource() instanceof Player) && (interactingChanged.getTarget() instanceof Player)) @@ -233,8 +246,7 @@ public class PrayAgainstPlayerPlugin extends Plugin } } - @Subscribe - protected void onPlayerDespawned(PlayerDespawned playerDespawned) + private void onPlayerDespawned(PlayerDespawned playerDespawned) { PlayerContainer container = findPlayerInAttackerList(playerDespawned.getPlayer()); PlayerContainer container2 = findPlayerInPotentialList(playerDespawned.getPlayer()); @@ -248,8 +260,7 @@ public class PrayAgainstPlayerPlugin extends Plugin } } - @Subscribe - protected void onPlayerSpawned(PlayerSpawned playerSpawned) + private void onPlayerSpawned(PlayerSpawned playerSpawned) { if (this.markNewPlayer) { @@ -414,8 +425,7 @@ public class PrayAgainstPlayerPlugin extends Plugin return null; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("prayagainstplayer")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java index 1dae89f203..e51e988f52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java @@ -42,7 +42,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -88,6 +88,9 @@ public class PrayerPlugin extends Plugin @Inject private PrayerConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private PrayerFlickLocation prayerFlickLocation; @Getter(AccessLevel.PACKAGE) @@ -115,6 +118,8 @@ public class PrayerPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); + overlayManager.add(flickOverlay); overlayManager.add(doseOverlay); overlayManager.add(barOverlay); @@ -123,13 +128,21 @@ public class PrayerPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(flickOverlay); overlayManager.remove(doseOverlay); overlayManager.remove(barOverlay); removeIndicators(); } - @Subscribe + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("prayer")) @@ -146,8 +159,7 @@ public class PrayerPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(final ItemContainerChanged event) + private void onItemContainerChanged(final ItemContainerChanged event) { final ItemContainer container = event.getItemContainer(); final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); @@ -172,8 +184,7 @@ public class PrayerPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { prayersActive = isAnyPrayerActive(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayeralert/PrayerAlertPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayeralert/PrayerAlertPlugin.java index edba3b0550..1293327e03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayeralert/PrayerAlertPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayeralert/PrayerAlertPlugin.java @@ -23,7 +23,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -48,6 +48,9 @@ public class PrayerAlertPlugin extends Plugin @Inject private PrayerAlertConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean alwaysShowAlert; @Getter(AccessLevel.PACKAGE) @@ -65,16 +68,19 @@ public class PrayerAlertPlugin extends Plugin this.alwaysShowAlert = config.alwaysShowAlert(); this.oldRenderMode = config.oldRenderMode(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } - @Subscribe private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("prayeralert")) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java index b79187fa6a..ea5e87587a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java @@ -30,7 +30,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -51,6 +51,9 @@ public class ProfilesPlugin extends Plugin @Inject private ClientToolbar clientToolbar; + @Inject + private EventBus eventBus; + private ProfilesPanel panel; private NavigationButton navButton; @@ -64,6 +67,8 @@ public class ProfilesPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + panel = injector.getInstance(ProfilesPanel.class); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "profiles_icon.png"); @@ -81,10 +86,11 @@ public class ProfilesPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + clientToolbar.removeNavigation(navButton); } - @Subscribe private void onConfigChanged(ConfigChanged event) throws Exception { if (event.getGroup().equals("profiles") && event.getKey().equals("rememberPassword")) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java index 55eaede2bb..7dc1db8748 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java @@ -301,6 +301,11 @@ public class PuzzleSolverOverlay extends Overlay arrow = getUpArrow(); } + if (arrow == null) + { + continue; + } + int x = puzzleBoxLocation.getX() + blankX * PUZZLE_TILE_SIZE + PUZZLE_TILE_SIZE / 2 - arrow.getWidth() / 2; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverPlugin.java index 331a7a6205..d9c574f744 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverPlugin.java @@ -51,7 +51,7 @@ import static net.runelite.api.widgets.WidgetInfo.LIGHT_BOX_BUTTON_G; import static net.runelite.api.widgets.WidgetInfo.LIGHT_BOX_BUTTON_H; import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.puzzlesolver.lightbox.Combination; @@ -86,6 +86,9 @@ public class PuzzleSolverPlugin extends Plugin @Inject private PuzzleSolverConfig config; + @Inject + private EventBus eventBus; + private LightboxState lightbox; private final LightboxState[] changes = new LightboxState[LightBox.COMBINATIONS_POWER]; private Combination lastClick; @@ -102,23 +105,34 @@ public class PuzzleSolverPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + @Provides PuzzleSolverConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(PuzzleSolverConfig.class); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded widget) + private void onWidgetLoaded(WidgetLoaded widget) { if (widget.getGroupId() != WidgetID.VARROCK_MUSEUM_QUIZ_GROUP_ID) { @@ -151,8 +165,7 @@ public class PuzzleSolverPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked menuOptionClicked) + private void onMenuOptionClicked(MenuOptionClicked menuOptionClicked) { int widgetId = menuOptionClicked.getActionParam1(); if (TO_GROUP(widgetId) != WidgetID.LIGHT_BOX_GROUP_ID) @@ -208,7 +221,6 @@ public class PuzzleSolverPlugin extends Plugin } } - @Subscribe public void onGameTick(GameTick event) { Widget lightboxWidget = client.getWidget(WidgetInfo.LIGHT_BOX_CONTENTS); @@ -297,7 +309,6 @@ public class PuzzleSolverPlugin extends Plugin } } - @Subscribe private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("puzzlesolver")) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java index bd0b9e17e3..bd1fbe4319 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsConfig.java @@ -76,31 +76,68 @@ public interface PvpToolsConfig extends Config keyName = "hideAttack", name = "Hide attack", description = "Hides the attack option for clanmates, friends, or both", - position = 5, - group = "Right-Click Attack Options" + position = 5 ) default boolean hideAttack() { return false; } + @ConfigItem( + keyName = "hideAttackMode", + name = "Mode", + description = "", + position = 6, + hidden = true, + unhide = "hideAttack" + ) + default AttackMode hideAttackMode() + { + return AttackMode.FRIENDS; + } + @ConfigItem( keyName = "hideCast", name = "Hide cast", description = "Hides the cast option for clanmates, friends, or both", - position = 7, - group = "Right-Click Attack Options" + position = 7 ) default boolean hideCast() { return false; } + @ConfigItem( + keyName = "hideCastMode", + name = "Mode", + description = "", + position = 8, + hidden = true, + unhide = "hideCast" + ) + default AttackMode hideCastMode() + { + return AttackMode.FRIENDS; + } + + @ConfigItem( + keyName = "hideCastIgnored", + name = "Ignored spells", + description = "Spells that should not be hidden from being cast, separated by a comma", + position = 9, + hidden = true, + unhide = "hideCast" + ) + default String hideCastIgnored() + { + return "cure other, energy transfer, heal other, vengeance other"; + } + @ConfigItem( keyName = "riskCalculator", name = "Risk Calculator", description = "Enables a panel in the PvP Tools Panel that shows the players current risk", - position = 13 + position = 10 ) default boolean riskCalculatorEnabled() { @@ -111,7 +148,7 @@ public interface PvpToolsConfig extends Config keyName = "missingPlayers", name = "Missing CC Players", description = "Adds a button to the PvP Tools panel that opens a window showing which CC members are not at the current players location", - position = 14 + position = 11 ) default boolean missingPlayersEnabled() { @@ -122,7 +159,7 @@ public interface PvpToolsConfig extends Config keyName = "currentPlayers", name = "Current CC Players", description = "Adds a button to the PvP Tools panel that opens a window showing which CC members currently at the players location", - position = 15 + position = 12 ) default boolean currentPlayersEnabled() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java index b0b7d100f4..b601dde072 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pvptools/PvpToolsPlugin.java @@ -11,6 +11,7 @@ package net.runelite.client.plugins.pvptools; +import com.google.common.collect.Sets; import com.google.inject.Provides; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -20,6 +21,7 @@ import java.util.Comparator; import java.util.List; import java.util.NavigableMap; import java.util.Objects; +import java.util.Set; import java.util.TreeMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; @@ -36,14 +38,17 @@ import net.runelite.api.Item; import net.runelite.api.ItemDefinition; import net.runelite.api.Player; import net.runelite.api.SkullIcon; +import net.runelite.api.Varbits; +import net.runelite.api.WorldType; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.PlayerDespawned; import net.runelite.api.events.PlayerSpawned; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.Keybind; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.game.ItemManager; import net.runelite.client.input.KeyManager; @@ -87,6 +92,7 @@ public class PvpToolsPlugin extends Plugin @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) private boolean hideAll; + private boolean loaded; @Inject private OverlayManager overlayManager; @@ -94,9 +100,15 @@ public class PvpToolsPlugin extends Plugin @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + private final PvpToolsPlugin uhPvpToolsPlugin = this; /** @@ -149,7 +161,10 @@ public class PvpToolsPlugin extends Plugin private boolean missingPlayersEnabled; private boolean currentPlayersEnabled; private boolean hideAttack; + private AttackMode hideAttackMode; private boolean hideCast; + private AttackMode hideCastMode; + private Set unhiddenCasts; @Inject private ClientToolbar clientToolbar; @@ -235,11 +250,10 @@ public class PvpToolsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(pvpToolsOverlay); overlayManager.add(playerCountOverlay); - client.setHideFriendAttackOptions(this.hideAttack); - client.setHideFriendCastOptions(this.hideCast); keyManager.registerKeyListener(fallinHotkeyListener); keyManager.registerKeyListener(renderselfHotkeyListener); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "skull.png"); @@ -258,7 +272,6 @@ public class PvpToolsPlugin extends Plugin panel.currentPlayers.addActionListener(currentPlayersActionListener); clientToolbar.addNavigation(navButton); - if (this.missingPlayersEnabled) { panel.missingPlayers.setVisible(true); @@ -269,86 +282,116 @@ public class PvpToolsPlugin extends Plugin panel.currentPlayers.setVisible(true); } + if (client.getGameState() == GameState.LOGGED_IN) + { + setCastOptions(); + } } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(pvpToolsOverlay); overlayManager.remove(playerCountOverlay); keyManager.unregisterKeyListener(fallinHotkeyListener); keyManager.unregisterKeyListener(renderselfHotkeyListener); clientToolbar.removeNavigation(navButton); - client.setHideFriendAttackOptions(false); - client.setHideFriendCastOptions(false); + + if (client.getGameState() == GameState.LOGGED_IN) + { + resetCastOptions(); + } + + loaded = false; } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(PlayerSpawned.class, this, this::onPlayerSpawned); + eventBus.subscribe(PlayerDespawned.class, this, this::onPlayerDespawned); + } + + private void onConfigChanged(ConfigChanged configChanged) { if (!"pvptools".equals(configChanged.getGroup())) { return; } - client.setHideFriendAttackOptions(this.hideAttack); - client.setHideFriendCastOptions(this.hideCast); - if (configChanged.getGroup().equals("pvptools")) + updateConfig(); + + switch (configChanged.getKey()) { - updateConfig(); - - switch (configChanged.getKey()) - { - case "countPlayers": - if (this.countPlayers) - { - updatePlayers(); - } - if (!this.countPlayers) - { - panel.disablePlayerCount(); - } - break; - case "countOverHeads": - if (this.countOverHeads) - { - countOverHeads(); - } - if (!this.countOverHeads) - { - panel.disablePrayerCount(); - } - break; - case "riskCalculator": - if (this.riskCalculatorEnabled) - { - getCarriedWealth(); - } - if (!this.riskCalculatorEnabled) - { - panel.disableRiskCalculator(); - } - break; - case "missingPlayers": - if (this.missingPlayersEnabled) - { - panel.missingPlayers.setVisible(true); - } - break; - case "currentPlayers": - if (this.currentPlayersEnabled) - { - panel.currentPlayers.setVisible(true); - } - break; - default: - break; - } + case "countPlayers": + if (this.countPlayers) + { + updatePlayers(); + } + if (!this.countPlayers) + { + panel.disablePlayerCount(); + } + break; + case "countOverHeads": + if (this.countOverHeads) + { + countOverHeads(); + } + if (!this.countOverHeads) + { + panel.disablePrayerCount(); + } + break; + case "riskCalculator": + if (this.riskCalculatorEnabled) + { + getCarriedWealth(); + } + if (!this.riskCalculatorEnabled) + { + panel.disableRiskCalculator(); + } + break; + case "missingPlayers": + if (this.missingPlayersEnabled) + { + panel.missingPlayers.setVisible(true); + } + break; + case "currentPlayers": + if (this.currentPlayersEnabled) + { + panel.currentPlayers.setVisible(true); + } + break; + case "hideAttack": + case "hideAttackMode": + if (this.hideAttack) + { + hideAttackOptions(this.hideAttackMode); + } + else + { + client.setHideFriendAttackOptions(false); + client.setHideClanmateAttackOptions(false); + } + break; + case "hideCast": + case "hideCastMode": + case "hideCastIgnored": + setCastOptions(); + break; + default: + break; } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer().equals(client.getItemContainer(InventoryID.INVENTORY)) && this.riskCalculatorEnabled) @@ -357,21 +400,26 @@ public class PvpToolsPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { - if (event.getGameState().equals(GameState.LOGGED_IN) && this.riskCalculatorEnabled) + if (event.getGameState().equals(GameState.LOGGED_IN)) { - getCarriedWealth(); - } - if (event.getGameState().equals(GameState.LOGGED_IN) && this.countPlayers) - { - updatePlayers(); + if (this.riskCalculatorEnabled) + { + getCarriedWealth(); + } + if (this.countPlayers) + { + updatePlayers(); + } + if (!loaded) + { + setCastOptions(); + } } } - @Subscribe - public void onPlayerSpawned(PlayerSpawned event) + private void onPlayerSpawned(PlayerSpawned event) { if (this.countPlayers && PvPUtil.isAttackable(client, event.getPlayer())) { @@ -383,8 +431,7 @@ public class PvpToolsPlugin extends Plugin } } - @Subscribe - public void onPlayerDespawned(PlayerDespawned event) + private void onPlayerDespawned(PlayerDespawned event) { if (this.countPlayers && PvPUtil.isAttackable(client, event.getPlayer())) { @@ -577,6 +624,101 @@ public class PvpToolsPlugin extends Plugin panel.biggestItemLabel.repaint(); } + /** + * Given an AttackMode, hides the appropriate attack options. + * @param mode The {@link AttackMode} specifying clanmates, friends, or both. + */ + public void hideAttackOptions(AttackMode mode) + { + switch (mode) + { + case CLAN: + client.setHideClanmateAttackOptions(true); + client.setHideFriendAttackOptions(false); + break; + case FRIENDS: + client.setHideFriendAttackOptions(true); + client.setHideClanmateAttackOptions(false); + break; + case BOTH: + client.setHideClanmateAttackOptions(true); + client.setHideFriendAttackOptions(true); + break; + } + } + + /** + * Given an AttackMode, hides the appropriate cast options. + * @param mode The {@link AttackMode} specifying clanmates, friends, or both. + */ + public void hideCastOptions(AttackMode mode) + { + switch (mode) + { + case CLAN: + client.setHideClanmateCastOptions(true); + client.setHideFriendCastOptions(false); + break; + case FRIENDS: + client.setHideFriendCastOptions(true); + client.setHideClanmateCastOptions(false); + break; + case BOTH: + client.setHideClanmateCastOptions(true); + client.setHideFriendCastOptions(true); + break; + } + } + + public void setCastOptions() + { + clientThread.invoke(() -> + { + if ((client.getVar(Varbits.IN_RAID) == 1 || client.getVar(Varbits.THEATRE_OF_BLOOD) == 2) + || (client.getVar(Varbits.IN_WILDERNESS) != 1 && !WorldType.isAllPvpWorld(client.getWorldType()))) + { + return; + } + + if (this.hideAttack) + { + hideAttackOptions(this.hideAttackMode); + } + else + { + client.setHideFriendAttackOptions(false); + client.setHideClanmateAttackOptions(false); + } + + if (this.hideCast) + { + hideCastOptions(this.hideCastMode); + } + else + { + client.setHideFriendCastOptions(false); + client.setHideClanmateCastOptions(false); + } + + client.setUnhiddenCasts(this.unhiddenCasts); + + loaded = true; + }); + } + + private void resetCastOptions() + { + clientThread.invoke(() -> + { + if (client.getVar(Varbits.IN_RAID) == 1 || client.getVar(Varbits.THEATRE_OF_BLOOD) == 2) + { + return; + } + + client.setHideFriendAttackOptions(false); + client.setHideFriendCastOptions(false); + }); + } private void updateConfig() { @@ -589,6 +731,9 @@ public class PvpToolsPlugin extends Plugin this.missingPlayersEnabled = config.missingPlayersEnabled(); this.currentPlayersEnabled = config.currentPlayersEnabled(); this.hideAttack = config.hideAttack(); + this.hideAttackMode = config.hideAttackMode(); this.hideCast = config.hideCast(); + this.hideCastMode = config.hideCastMode(); + this.unhiddenCasts = Sets.newHashSet(Text.fromCSV(config.hideCastIgnored().toLowerCase())); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java index f12911344c..0b9e4a09d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/pyramidplunder/PyramidPlunderPlugin.java @@ -56,7 +56,7 @@ import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -120,6 +120,9 @@ public class PyramidPlunderPlugin extends Plugin @Inject private PyramidPlunderOverlay pyramidPlunderOverlay; + @Inject + private EventBus eventBus; + @Getter private boolean isInGame; @@ -147,18 +150,33 @@ public class PyramidPlunderPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(pyramidPlunderOverlay); highlighted.clear(); reset(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(WallObjectSpawned.class, this, this::onWallObjectSpawned); + eventBus.subscribe(WallObjectChanged.class, this, this::onWallObjectChanged); + eventBus.subscribe(WallObjectDespawned.class, this, this::onWallObjectDespawned); + } + + private void onConfigChanged(ConfigChanged event) { if (!"pyramidplunder".equals(event.getGroup())) { @@ -207,8 +225,7 @@ public class PyramidPlunderPlugin extends Plugin ); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -241,8 +258,7 @@ public class PyramidPlunderPlugin extends Plugin } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { int lastValue = pyramidTimer; pyramidTimer = client.getVar(Varbits.PYRAMID_PLUNDER_TIMER); @@ -276,38 +292,32 @@ public class PyramidPlunderPlugin extends Plugin removeTimer(); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { onTileObject(event.getTile(), null, event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { onTileObject(event.getTile(), event.getGameObject(), null); } - @Subscribe - public void onWallObjectSpawned(WallObjectSpawned event) + private void onWallObjectSpawned(WallObjectSpawned event) { onTileObject(event.getTile(), null, event.getWallObject()); } - @Subscribe - public void onWallObjectChanged(WallObjectChanged event) + private void onWallObjectChanged(WallObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getWallObject()); } - @Subscribe - public void onWallObjectDespawned(WallObjectDespawned event) + private void onWallObjectDespawned(WallObjectDespawned event) { onTileObject(event.getTile(), event.getWallObject(), null); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java index 2f0fb9b415..775d28179b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java @@ -53,7 +53,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxTextInput; import net.runelite.client.plugins.Plugin; @@ -87,6 +87,9 @@ public class QuestListPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + private ChatboxTextInput searchInput; private Widget questSearchButton; private Widget questHideButton; @@ -98,12 +101,15 @@ public class QuestListPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); clientThread.invoke(this::addQuestButtons); } @Override protected void shutDown() { + eventBus.unregister(this); + Widget header = client.getWidget(WidgetInfo.QUESTLIST_BOX); if (header != null) { @@ -111,8 +117,15 @@ public class QuestListPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged e) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(VarClientIntChanged.class, this, this::onVarClientIntChanged); + } + + private void onGameStateChanged(GameStateChanged e) { if (e.getGameState() == GameState.LOGGING_IN) { @@ -120,8 +133,7 @@ public class QuestListPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!event.getEventName().equals("questProgressUpdated")) { @@ -170,8 +182,7 @@ public class QuestListPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged varbitChanged) + private void onVarbitChanged(VarbitChanged varbitChanged) { if (isChatboxOpen() && isNotOnQuestTab()) { @@ -179,8 +190,7 @@ public class QuestListPlugin extends Plugin } } - @Subscribe - public void onVarClientIntChanged(VarClientIntChanged varClientIntChanged) + private void onVarClientIntChanged(VarClientIntChanged varClientIntChanged) { if (varClientIntChanged.getIndex() == VarClientInt.INVENTORY_TAB.getIndex() && isChatboxOpen() && isNotOnQuestTab()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 64ae7c8661..16494579e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -75,7 +75,7 @@ import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SpriteManager; @@ -107,6 +107,7 @@ import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; ) @Singleton @Slf4j +@Getter(AccessLevel.PACKAGE) public class RaidsPlugin extends Plugin { static final DecimalFormat POINTS_FORMAT = new DecimalFormat("#,###"); @@ -151,125 +152,106 @@ public class RaidsPlugin extends Plugin "SFCCP.CSCPF - #WNEESE#NWSWWN", //bad crabs first rare crabs second "SCFPC.CSPCF - #WSWWNE#WSEENE" //good crabs first rare crabs second ); - private static final String TRIPLE_PUZZLE = "SFCCPC.PCSCPF - #WSEENES#WWWNEEE"; //good crabs first rare crabs second rare crabs third private static final Pattern PUZZLES = Pattern.compile("Puzzle - (\\w+)"); - @Getter(AccessLevel.PACKAGE) - private final List roomWhitelist = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private final List roomBlacklist = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private final List rotationWhitelist = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private final List layoutWhitelist = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private final Map> recommendedItemsList = new HashMap<>(); + @Getter(AccessLevel.NONE) @Inject private ChatMessageManager chatMessageManager; + @Getter(AccessLevel.NONE) @Inject private InfoBoxManager infoBoxManager; + @Getter(AccessLevel.NONE) @Inject private Client client; + @Getter(AccessLevel.NONE) @Inject private RaidsConfig config; + @Getter(AccessLevel.NONE) @Inject private OverlayManager overlayManager; + @Getter(AccessLevel.NONE) @Inject private RaidsOverlay overlay; + @Getter(AccessLevel.NONE) @Inject private RaidsPointsOverlay pointsOverlay; + @Getter(AccessLevel.NONE) @Inject private RaidsPartyOverlay partyOverlay; + @Getter(AccessLevel.NONE) @Inject private LayoutSolver layoutSolver; + @Getter(AccessLevel.NONE) @Inject private SpriteManager spriteManager; + @Getter(AccessLevel.NONE) @Inject private ClientThread clientThread; + @Getter(AccessLevel.NONE) @Inject private TooltipManager tooltipManager; + @Getter(AccessLevel.NONE) @Inject private ClientToolbar clientToolbar; + @Getter(AccessLevel.NONE) @Inject private ItemManager itemManager; - @Getter(AccessLevel.PACKAGE) - private Raid raid; - @Getter(AccessLevel.PACKAGE) - private boolean inRaidChambers; - @Getter(AccessLevel.PACKAGE) - private String goodCrabs; - @Getter(AccessLevel.PACKAGE) - private int startPlayerCount; - @Getter(AccessLevel.PACKAGE) - private List partyMembers = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private List startingPartyMembers = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private Set missingPartyMembers = new HashSet<>(); - @Getter(AccessLevel.PACKAGE) - private String layoutFullCode; - @Getter(AccessLevel.PACKAGE) + @Getter(AccessLevel.NONE) + @Inject + private EventBus eventBus; private boolean raidStarted; - private int upperTime = -1; - private int middleTime = -1; - private int lowerTime = -1; - private int raidTime = -1; - private WidgetOverlay widgetOverlay; - private String tooltip; - private NavigationButton navButton; - private RaidsTimer timer; - - @Getter(AccessLevel.PACKAGE) + private boolean inRaidChambers; private boolean enhanceScouterTitle; - @Getter(AccessLevel.PACKAGE) private boolean hideBackground; private boolean raidsTimer; private boolean pointsMessage; private boolean ptsHr; - @Getter(AccessLevel.PACKAGE) private boolean scoutOverlay; private boolean scoutOverlayAtBank; private boolean scoutOverlayInRaid; - @Getter(AccessLevel.PACKAGE) private boolean displayFloorBreak; - @Getter(AccessLevel.PACKAGE) private boolean showRecommendedItems; - private String recommendedItems; - @Getter(AccessLevel.PACKAGE) private boolean alwaysShowWorldAndCC; private boolean layoutMessage; - @Getter(AccessLevel.PACKAGE) private boolean colorTightrope; - @Getter(AccessLevel.PACKAGE) - private Color tightropeColor; - @Getter(AccessLevel.PACKAGE) private boolean crabHandler; - @Getter(AccessLevel.PACKAGE) - private Color goodCrabColor; - @Getter(AccessLevel.PACKAGE) - private Color rareCrabColor; - @Getter(AccessLevel.PACKAGE) private boolean enableRotationWhitelist; - private String whitelistedRotations; - @Getter(AccessLevel.PACKAGE) private boolean enableLayoutWhitelist; - private String whitelistedLayouts; - @Getter(AccessLevel.PACKAGE) private boolean showScavsFarms; - @Getter(AccessLevel.PACKAGE) private boolean scavsBeforeIce; - @Getter(AccessLevel.PACKAGE) private boolean scavsBeforeOlm; - @Getter(AccessLevel.PACKAGE) - private Color scavPrepColor; - private String whitelistedRooms; - private String blacklistedRooms; - @Getter(AccessLevel.PACKAGE) private boolean hideRopeless; - @Getter(AccessLevel.PACKAGE) private boolean hideVanguards; - @Getter(AccessLevel.PACKAGE) private boolean hideUnknownCombat; private boolean partyDisplay; + private int startPlayerCount; + private int upperTime = -1; + private int middleTime = -1; + private int lowerTime = -1; + private int raidTime = -1; + private Color goodCrabColor; + private Color rareCrabColor; + private Color scavPrepColor; + private Color tightropeColor; + private Raid raid; + private RaidsTimer timer; + private WidgetOverlay widgetOverlay; + private NavigationButton navButton; + private String recommendedItems; + private String whitelistedRooms; + private String whitelistedRotations; + private String whitelistedLayouts; + private String blacklistedRooms; + private String tooltip; + private String goodCrabs; + private String layoutFullCode; + private List roomWhitelist = new ArrayList<>(); + private List roomBlacklist = new ArrayList<>(); + private List rotationWhitelist = new ArrayList<>(); + private List layoutWhitelist = new ArrayList<>(); + private List partyMembers = new ArrayList<>(); + private List startingPartyMembers = new ArrayList<>(); + private Map> recommendedItemsList = new HashMap<>(); + private Set missingPartyMembers = new HashSet<>(); @Provides RaidsConfig provideConfig(ConfigManager configManager) @@ -287,7 +269,8 @@ public class RaidsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); - + addSubscriptions(); + overlayManager.add(overlay); overlayManager.add(pointsOverlay); if (this.partyDisplay) @@ -312,6 +295,8 @@ public class RaidsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(pointsOverlay); clientToolbar.removeNavigation(navButton); @@ -328,15 +313,25 @@ public class RaidsPlugin extends Plugin reset(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ClientTick.class, this, this::onClientTick); + eventBus.subscribe(OverlayMenuClicked.class, this, this::onOverlayMenuClicked); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("raids")) { return; } - + updateConfig(); + updateLists(); if (event.getKey().equals("raidsTimer")) { @@ -356,12 +351,10 @@ public class RaidsPlugin extends Plugin } } - updateLists(); clientThread.invokeLater(() -> checkRaidPresence(true)); } - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged event) + private void onWidgetHiddenChanged(WidgetHiddenChanged event) { if (!inRaidChambers || event.isHidden()) { @@ -376,8 +369,7 @@ public class RaidsPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { checkRaidPresence(false); if (this.partyDisplay) @@ -386,8 +378,7 @@ public class RaidsPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (inRaidChambers && event.getType() == ChatMessageType.FRIENDSCHATNOTIFICATION) { @@ -398,9 +389,9 @@ public class RaidsPlugin extends Plugin { if (this.raidsTimer) { - timer = new RaidsTimer(spriteManager.getSprite(TAB_QUESTS_BROWN_RAIDING_PARTY, 0), this, Instant.now()); + timer = new RaidsTimer(this, Instant.now()); + spriteManager.getSpriteAsync(TAB_QUESTS_BROWN_RAIDING_PARTY, 0, timer); infoBoxManager.addInfoBox(timer); - raidStarted = true; } if (this.partyDisplay) { @@ -519,8 +510,7 @@ public class RaidsPlugin extends Plugin } } - @Subscribe - public void onClientTick(ClientTick event) + private void onClientTick(ClientTick event) { if (!this.raidsTimer || !client.getGameState().equals(GameState.LOGGED_IN) @@ -536,8 +526,7 @@ public class RaidsPlugin extends Plugin } } - @Subscribe - public void onOverlayMenuClicked(OverlayMenuClicked event) + private void onOverlayMenuClicked(OverlayMenuClicked event) { OverlayMenuEntry entry = event.getEntry(); if (entry.getMenuAction() == MenuAction.RUNELITE_OVERLAY && @@ -824,7 +813,7 @@ public class RaidsPlugin extends Plugin { list.clear(); - if (list.equals(rotationWhitelist)) + if (list == this.rotationWhitelist) { Matcher m = ROTATION_REGEX.matcher(input); while (m.find()) @@ -1236,7 +1225,7 @@ public class RaidsPlugin extends Plugin { overlay.setScoutOverlayShown(bool); } - + private void updateConfig() { this.enhanceScouterTitle = config.enhanceScouterTitle(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java index b1cf6600ef..e33fd7c3c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsTimer.java @@ -25,7 +25,6 @@ package net.runelite.client.plugins.raids; import java.awt.Color; -import java.awt.image.BufferedImage; import java.time.Duration; import java.time.Instant; import java.time.LocalTime; @@ -48,9 +47,9 @@ public class RaidsTimer extends InfoBox @Setter(AccessLevel.PACKAGE) private boolean stopped; - RaidsTimer(final BufferedImage image, final Plugin plugin, final Instant startTime) + public RaidsTimer(Plugin plugin, Instant startTime) { - super(image, plugin); + super(null, plugin); this.startTime = startTime; floorTime = startTime; stopped = false; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/shortcuts/ShortcutPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/shortcuts/ShortcutPlugin.java index b8bb023e98..8cba543dc3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/shortcuts/ShortcutPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/shortcuts/ShortcutPlugin.java @@ -16,7 +16,7 @@ import net.runelite.api.events.GameObjectDespawned; import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -39,6 +39,8 @@ public class ShortcutPlugin extends Plugin private ShortcutOverlay overlay; @Inject private ShortcutConfig config; + @Inject + private EventBus eventBus; @Getter(AccessLevel.PACKAGE) private boolean highlightShortcuts; @@ -57,6 +59,8 @@ public class ShortcutPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + this.highlightShortcuts = config.highlightShortcuts(); overlayManager.add(overlay); } @@ -64,11 +68,19 @@ public class ShortcutPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); overlayManager.remove(overlay); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameObjectSpawned(GameObjectSpawned event) { WorldPoint worldPoint = WorldPoint.fromLocalInstance(client, event.getGameObject().getLocalLocation()); if (worldPoint == null) @@ -81,20 +93,17 @@ public class ShortcutPlugin extends Plugin } } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { shortcut.remove(event.getGameObject()); } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { shortcut.removeIf(object -> object.getCanvasLocation() == null); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("shortcut")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java index 5df929535f..5a4f16fdb7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java @@ -46,7 +46,7 @@ import net.runelite.api.events.GraphicsObjectCreated; import net.runelite.api.events.VarbitChanged; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -81,6 +81,9 @@ public class RaidsThievingPlugin extends Plugin @Inject private RaidsThievingConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final Map chests = new HashMap<>(); @@ -115,6 +118,7 @@ public class RaidsThievingPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlay.updateConfig(); @@ -124,14 +128,22 @@ public class RaidsThievingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); lastActionTime = Instant.ofEpochMilli(0); chests.clear(); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GraphicsObjectCreated.class, this, this::onGraphicsObjectCreated); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { GameObject obj = event.getGameObject(); WorldPoint loc = obj.getWorldLocation(); @@ -203,9 +215,7 @@ public class RaidsThievingPlugin extends Plugin } } - - @Subscribe - public void onGraphicsObjectCreated(GraphicsObjectCreated event) + private void onGraphicsObjectCreated(GraphicsObjectCreated event) { GraphicsObject obj = event.getGraphicsObject(); if (obj.getId() == 184) @@ -222,8 +232,7 @@ public class RaidsThievingPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { boolean setting = client.getVar(Varbits.IN_RAID) == 1; @@ -235,8 +244,7 @@ public class RaidsThievingPlugin extends Plugin } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("raidsthievingplugin")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/reorderprayers/ReorderPrayersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/reorderprayers/ReorderPrayersPlugin.java index deec5d3ec6..09baf49c33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/reorderprayers/ReorderPrayersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/reorderprayers/ReorderPrayersPlugin.java @@ -48,7 +48,7 @@ import static net.runelite.api.widgets.WidgetConfig.DRAG_ON; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.plugins.Plugin; @@ -181,6 +181,9 @@ public class ReorderPrayersPlugin extends Plugin @Inject private MenuManager menuManager; + @Inject + private EventBus eventBus; + private Prayer[] prayerOrder; static String prayerOrderToString(Prayer[] prayerOrder) @@ -221,6 +224,8 @@ public class ReorderPrayersPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + refreshPrayerTabOption(); prayerOrder = stringToPrayerOrder(config.prayerOrder()); reorderPrayers(); @@ -229,13 +234,23 @@ public class ReorderPrayersPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + clearPrayerTabMenus(); prayerOrder = Prayer.values(); reorderPrayers(false); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(DraggingWidgetChanged.class, this, this::onDraggingWidgetChanged); + eventBus.subscribe(WidgetMenuOptionClicked.class, this, this::onWidgetMenuOptionClicked); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -243,8 +258,7 @@ public class ReorderPrayersPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals(CONFIG_GROUP_KEY)) { @@ -260,8 +274,7 @@ public class ReorderPrayersPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) { @@ -269,8 +282,7 @@ public class ReorderPrayersPlugin extends Plugin } } - @Subscribe - public void onDraggingWidgetChanged(DraggingWidgetChanged event) + private void onDraggingWidgetChanged(DraggingWidgetChanged event) { // is dragging widget and mouse button released if (event.isDraggingWidget() && client.getMouseCurrentButton() == 0) @@ -301,8 +313,7 @@ public class ReorderPrayersPlugin extends Plugin } } - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + private void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) { if (event.getWidget() == WidgetInfo.FIXED_VIEWPORT_PRAYER_TAB || event.getWidget() == WidgetInfo.RESIZABLE_VIEWPORT_PRAYER_TAB diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java index 8a0f91e692..f8d0888375 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.task.Schedule; @@ -76,6 +76,9 @@ public class ReportButtonPlugin extends Plugin @Inject private ReportButtonConfig config; + @Inject + private EventBus eventBus; + private TimeStyle timeStyle; @Provides @@ -87,6 +90,8 @@ public class ReportButtonPlugin extends Plugin @Override public void startUp() { + addSubscriptions(); + this.timeStyle = config.time(); clientThread.invoke(this::updateReportButtonTime); } @@ -94,6 +99,8 @@ public class ReportButtonPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + clientThread.invoke(() -> { Widget reportButton = client.getWidget(WidgetInfo.CHATBOX_REPORT_TEXT); @@ -104,8 +111,13 @@ public class ReportButtonPlugin extends Plugin }); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onGameStateChanged(GameStateChanged event) { GameState state = event.getGameState(); @@ -205,8 +217,7 @@ public class ReportButtonPlugin extends Plugin return DATE_FORMAT.format(new Date()); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("regenmeter")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java index 163682223b..469a1ff4cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/roguesden/RoguesDenPlugin.java @@ -45,7 +45,7 @@ import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.ItemContainerChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -76,23 +76,41 @@ public class RoguesDenPlugin extends Plugin @Inject private RoguesDenOverlay overlay; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { + addSubscriptions(); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); obstaclesHull.clear(); obstaclesTile.clear(); hasGem = false; } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(GroundObjectChanged.class, this, this::onGroundObjectChanged); + eventBus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY)) { @@ -111,44 +129,37 @@ public class RoguesDenPlugin extends Plugin hasGem = false; } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { onTileObject(event.getTile(), null, event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { onTileObject(event.getTile(), event.getGameObject(), null); } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { onTileObject(event.getTile(), null, event.getGroundObject()); } - @Subscribe - public void onGroundObjectChanged(GroundObjectChanged event) + private void onGroundObjectChanged(GroundObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject()); } - @Subscribe - public void onGroundObjectDespawned(GroundObjectDespawned event) + private void onGroundObjectDespawned(GroundObjectDespawned event) { onTileObject(event.getTile(), event.getGroundObject(), null); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java index 29f3ae2523..d80e22b592 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/RunecraftPlugin.java @@ -56,7 +56,7 @@ import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -115,6 +115,9 @@ public class RunecraftPlugin extends Plugin @Inject private MenuManager menuManager; + @Inject + private EventBus eventBus; + private boolean Lavas; @Getter(AccessLevel.PACKAGE) private boolean essPouch; @@ -162,6 +165,7 @@ public class RunecraftPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(abyssOverlay); abyssOverlay.updateConfig(); @@ -172,6 +176,8 @@ public class RunecraftPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(abyssOverlay); abyssObjects.clear(); darkMage = null; @@ -180,8 +186,20 @@ public class RunecraftPlugin extends Plugin removeSwaps(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned); + eventBus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("runecraft")) { @@ -198,8 +216,7 @@ public class RunecraftPlugin extends Plugin abyssOverlay.updateConfig(); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE) { @@ -212,8 +229,7 @@ public class RunecraftPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded entry) + private void onMenuEntryAdded(MenuEntryAdded entry) { if (wearingCape || wearingTiara) { @@ -287,9 +303,7 @@ public class RunecraftPlugin extends Plugin return -1; } - - @Subscribe - public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + private void onDecorativeObjectSpawned(DecorativeObjectSpawned event) { DecorativeObject decorativeObject = event.getDecorativeObject(); if (AbyssRifts.getRift(decorativeObject.getId()) != null) @@ -298,15 +312,13 @@ public class RunecraftPlugin extends Plugin } } - @Subscribe - public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + private void onDecorativeObjectDespawned(DecorativeObjectDespawned event) { DecorativeObject decorativeObject = event.getDecorativeObject(); abyssObjects.remove(decorativeObject); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { GameState gameState = event.getGameState(); switch (gameState) @@ -322,8 +334,7 @@ public class RunecraftPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (event.getItemContainer() == client.getItemContainer(InventoryID.INVENTORY)) { @@ -339,8 +350,7 @@ public class RunecraftPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { final NPC npc = event.getNpc(); if (npc.getId() == NpcID.DARK_MAGE) @@ -349,8 +359,7 @@ public class RunecraftPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { final NPC npc = event.getNpc(); if (npc != null && npc.equals(darkMage)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runedoku/RunedokuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/runedoku/RunedokuPlugin.java index 3fa8214b50..e06e11d5e8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runedoku/RunedokuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runedoku/RunedokuPlugin.java @@ -33,7 +33,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -60,6 +60,9 @@ public class RunedokuPlugin extends Plugin @Inject private RunedokuConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Color mindRuneColor; @Getter(AccessLevel.PACKAGE) @@ -91,17 +94,21 @@ public class RunedokuPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(runedokuOverlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(runedokuOverlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("runedoku")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runeliteplus/RuneLitePlusPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/runeliteplus/RuneLitePlusPlugin.java index 0b7ffb8271..db86fc540a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runeliteplus/RuneLitePlusPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runeliteplus/RuneLitePlusPlugin.java @@ -39,7 +39,7 @@ import static net.runelite.api.widgets.WidgetInfo.*; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.RuneLitePlusConfig; import net.runelite.client.discord.DiscordService; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; @@ -105,6 +105,9 @@ public class RuneLitePlusPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventbus; + private final RuneLitePlusKeyListener keyListener = new RuneLitePlusKeyListener(); private int entered = -1; private int enterIdx; @@ -113,6 +116,8 @@ public class RuneLitePlusPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + if (config.customPresence()) { ClientUI.currentPresenceName = ("RuneLitePlus"); @@ -127,8 +132,7 @@ public class RuneLitePlusPlugin extends Plugin expectInput = false; } - @Subscribe - protected void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("runeliteplus")) { @@ -165,13 +169,20 @@ public class RuneLitePlusPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventbus.unregister(this); + entered = 0; enterIdx = 0; expectInput = false; keyManager.unregisterKeyListener(keyListener); } - @Subscribe + private void addSubscriptions() + { + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + private void onScriptCallbackEvent(ScriptCallbackEvent e) { if (!config.keyboardPin()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchPlugin.java index 88a897d9ef..b3dbdc6b18 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchPlugin.java @@ -32,7 +32,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.runepouch.config.RunePouchOverlayMode; @@ -55,6 +55,9 @@ public class RunepouchPlugin extends Plugin @Inject private RunepouchConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Color fontColor; @Getter(AccessLevel.PACKAGE) @@ -72,17 +75,21 @@ public class RunepouchPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("runepouch")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java index bc2ea6d984..168fbcde35 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java @@ -30,7 +30,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.InteractingChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -55,6 +55,9 @@ public class SafeSpotPlugin extends Plugin @Inject private SafeSpotConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private List safeSpotList; @@ -79,6 +82,7 @@ public class SafeSpotPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); safeSpotOverlay = new SafeSpotOverlay(client, this); overlayManager.add(safeSpotOverlay); @@ -87,10 +91,18 @@ public class SafeSpotPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(safeSpotOverlay); } - @Subscribe + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + private void onInteractingChanged(InteractingChanged event) { if (event.getSource() != client.getLocalPlayer()) @@ -103,8 +115,7 @@ public class SafeSpotPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (client.getLocalPlayer().getInteracting() != null) { @@ -185,8 +196,7 @@ public class SafeSpotPlugin extends Plugin return safeSpotList; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("safespot")) { 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 ce6a8d67fa..e94418945d 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 @@ -44,13 +44,14 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.screenmarkers.ui.ScreenMarkerPluginPanel; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ImageUtil; @@ -87,6 +88,13 @@ public class ScreenMarkerPlugin extends Plugin @Inject private ScreenMarkerCreationOverlay overlay; + @Getter + @Inject + private ColorPickerManager colorPickerManager; + + @Inject + private EventBus eventBus; + private ScreenMarkerMouseListener mouseListener; private ScreenMarkerPluginPanel pluginPanel; private NavigationButton navigationButton; @@ -101,6 +109,8 @@ public class ScreenMarkerPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); loadConfig(configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY)).forEach(screenMarkers::add); screenMarkers.forEach(overlayManager::add); @@ -125,6 +135,8 @@ public class ScreenMarkerPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.removeIf(ScreenMarkerOverlay.class::isInstance); screenMarkers.clear(); @@ -138,8 +150,7 @@ public class ScreenMarkerPlugin extends Plugin navigationButton = null; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (screenMarkers.isEmpty() && event.getGroup().equals(CONFIG_GROUP) && event.getKey().equals(CONFIG_KEY)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index 217922790e..3aced96c5a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -31,8 +31,6 @@ import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import javax.inject.Singleton; import javax.swing.BorderFactory; @@ -491,45 +489,35 @@ class ScreenMarkerPanel extends JPanel private void openFillColorPicker() { - RuneliteColorPicker colorPicker = new RuneliteColorPicker(SwingUtilities.windowForComponent(this), - marker.getMarker().getFill(), marker.getMarker().getName() + " Fill", false); + RuneliteColorPicker colorPicker = plugin.getColorPickerManager().create( + SwingUtilities.windowForComponent(this), + marker.getMarker().getFill(), + marker.getMarker().getName() + " Fill", + false); colorPicker.setLocation(getLocationOnScreen()); colorPicker.setOnColorChange(c -> { marker.getMarker().setFill(c); updateFill(); }); - - colorPicker.addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent e) - { - plugin.updateConfig(); - } - }); + colorPicker.setOnClose(c -> plugin.updateConfig()); colorPicker.setVisible(true); } private void openBorderColorPicker() { - RuneliteColorPicker colorPicker = new RuneliteColorPicker(SwingUtilities.windowForComponent(this), - marker.getMarker().getColor(), marker.getMarker().getName() + " Border", false); + RuneliteColorPicker colorPicker = plugin.getColorPickerManager().create( + SwingUtilities.windowForComponent(this), + marker.getMarker().getColor(), + marker.getMarker().getName() + " Border", + false); colorPicker.setLocation(getLocationOnScreen()); colorPicker.setOnColorChange(c -> { marker.getMarker().setColor(c); updateBorder(); }); - - colorPicker.addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent e) - { - plugin.updateConfig(); - } - }); + colorPicker.setOnClose(c -> plugin.updateConfig()); colorPicker.setVisible(true); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 453c7f4597..73991b48fa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -58,7 +58,6 @@ import javax.imageio.ImageIO; import javax.inject.Inject; import javax.inject.Singleton; import javax.swing.SwingUtilities; - import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -91,7 +90,7 @@ import net.runelite.client.Notifier; import static net.runelite.client.RuneLite.SCREENSHOT_DIR; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.Keybind; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.PlayerLootReceived; import net.runelite.client.game.SpriteManager; import net.runelite.client.input.KeyManager; @@ -196,6 +195,9 @@ public class ScreenshotPlugin extends Plugin @Inject private SpriteManager spriteManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private BufferedImage reportButton; @@ -244,6 +246,7 @@ public class ScreenshotPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(screenshotOverlay); SCREENSHOT_DIR.mkdirs(); @@ -273,18 +276,32 @@ public class ScreenshotPlugin extends Plugin .build(); clientToolbar.addNavigation(titleBarButton); + + spriteManager.getSpriteAsync(SpriteID.CHATBOX_REPORT_BUTTON, 0, s -> reportButton = s); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(screenshotOverlay); clientToolbar.removeNavigation(titleBarButton); keyManager.unregisterKeyListener(hotkeyListener); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(PlayerLootReceived.class, this, this::onPlayerLootReceived); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN && reportButton == null) @@ -293,8 +310,7 @@ public class ScreenshotPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + void onGameTick(GameTick event) { if (this.screenshotFriendDeath) { @@ -342,8 +358,7 @@ public class ScreenshotPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged e) + private void onAnimationChanged(AnimationChanged e) { //this got refactored somewhere, but some things were missing if (!this.screenshotFriendDeath || !this.screenshotPlayerDeath) @@ -383,8 +398,7 @@ public class ScreenshotPlugin extends Plugin } } - @Subscribe - public void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) + private void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) { if (this.screenshotKills) { @@ -395,8 +409,7 @@ public class ScreenshotPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM && event.getType() != ChatMessageType.TRADE) { @@ -509,8 +522,7 @@ public class ScreenshotPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + void onWidgetLoaded(WidgetLoaded event) { String fileName; int groupId = event.getGroupId(); @@ -775,6 +787,14 @@ public class ScreenshotPlugin extends Plugin { File screenshotFile = new File(playerFolder, fileName + ".png"); + // To make sure that screenshots don't get overwritten, check if file exists, + // and if it does create file with same name and suffix. + int i = 1; + while (screenshotFile.exists()) + { + screenshotFile = new File(playerFolder, fileName + String.format("(%d)", i++) + ".png"); + } + ImageIO.write(screenshot, "PNG", screenshotFile); if (this.uploadScreenshot) @@ -886,8 +906,7 @@ public class ScreenshotPlugin extends Plugin return theatreOfBloodNumber; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("screenshot")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java index e74b268575..7280e59e8c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shayzieninfirmary/ShayzienInfirmaryPlugin.java @@ -34,7 +34,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.NPC; import net.runelite.api.events.GameTick; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -60,18 +60,25 @@ public class ShayzienInfirmaryPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + @Inject private ShayzienInfirmaryOverlay overlay; @Override protected void startUp() throws Exception { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + loadPlugin(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + unloadPlugin(); } @@ -85,8 +92,7 @@ public class ShayzienInfirmaryPlugin extends Plugin overlayManager.remove(overlay); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (isNotAtInfirmary()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java index d9464b1dd6..d0e2eb02e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/shiftwalker/ShiftWalkerPlugin.java @@ -30,7 +30,7 @@ import javax.inject.Singleton; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.FocusChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.plugins.Plugin; @@ -65,6 +65,9 @@ public class ShiftWalkerPlugin extends Plugin @Inject private KeyManager keyManager; + @Inject + private EventBus eventBus; + private boolean shiftWalk; private boolean shiftLoot; @@ -80,17 +83,26 @@ public class ShiftWalkerPlugin extends Plugin this.shiftWalk = config.shiftWalk(); this.shiftLoot = config.shiftLoot(); + addSubscriptions(); + keyManager.registerKeyListener(inputListener); } @Override public void shutDown() { + eventBus.unregister(this); + keyManager.unregisterKeyListener(inputListener); } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + + private void onFocusChanged(FocusChanged event) { if (!event.isFocused()) { @@ -117,8 +129,7 @@ public class ShiftWalkerPlugin extends Plugin menuManager.removePriorityEntry(WALK_HERE); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("shiftwalkhere")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java index 147420e7b1..44797f4968 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java @@ -40,7 +40,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SkillIconManager; import net.runelite.client.game.SpriteManager; @@ -81,6 +81,9 @@ public class SkillCalculatorPlugin extends Plugin @Inject private SkillCalculatorConfig skillCalculatorConfig; + @Inject + private EventBus eventBus; + private NavigationButton uiNavigationButton; private NavigationButton bankedUiNavigationButton; @@ -96,6 +99,8 @@ public class SkillCalculatorPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "calc.png"); final SkillCalculatorPanel uiPanel = new SkillCalculatorPanel(skillIconManager, client, spriteManager, itemManager); @@ -114,6 +119,7 @@ public class SkillCalculatorPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); clientToolbar.removeNavigation(uiNavigationButton); if (bankedUiNavigationButton != null) { @@ -121,8 +127,13 @@ public class SkillCalculatorPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("skillCalculator") && event.getKey().equals("enabledBankedXp")) { @@ -130,7 +141,6 @@ public class SkillCalculatorPlugin extends Plugin } } - @Subscribe public void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!event.getEventName().equals("setBankTitle") || !skillCalculatorConfig.showBankedXp()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skybox/SkyboxPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/skybox/SkyboxPlugin.java index d91597749b..7a0c11bf33 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skybox/SkyboxPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skybox/SkyboxPlugin.java @@ -33,7 +33,7 @@ import net.runelite.api.Player; import net.runelite.api.coords.LocalPoint; import net.runelite.api.events.BeforeRender; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -49,21 +49,34 @@ public class SkyboxPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + private Skybox skybox; @Override public void startUp() throws IOException { + addSubscriptions(); + skybox = new Skybox(SkyboxPlugin.class.getResourceAsStream("skybox.txt"), "skybox.txt"); } @Override public void shutDown() { + eventBus.unregister(this); + client.setSkyboxColor(0); skybox = null; } + private void addSubscriptions() + { + eventBus.subscribe(BeforeRender.class, this, this::onBeforeRender); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + private int mapChunk(int cx, int cy, int plane) { cx -= client.getBaseX() / 8; @@ -79,8 +92,7 @@ public class SkyboxPlugin extends Plugin return instanceTemplateChunks[cx][cy]; } - @Subscribe - public void onBeforeRender(BeforeRender r) + private void onBeforeRender(BeforeRender r) { if (skybox == null || client.getGameState() != GameState.LOGGED_IN) { @@ -124,8 +136,7 @@ public class SkyboxPlugin extends Plugin )); } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN) { 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 eee2b5beeb..c06ed1ce49 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 @@ -82,7 +82,7 @@ import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.ChatInput; import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.game.ItemManager; @@ -219,6 +219,9 @@ public class SlayerPlugin extends Plugin @Inject private ChatClient chatClient; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final Set highlightedTargets = new HashSet<>(); @@ -291,6 +294,7 @@ public class SlayerPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(targetClickboxOverlay); @@ -326,6 +330,8 @@ public class SlayerPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(targetClickboxOverlay); overlayManager.remove(targetWeaknessOverlay); @@ -338,14 +344,27 @@ public class SlayerPlugin extends Plugin clientToolbar.removeNavigation(navButton); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); + } + @Provides SlayerConfig getConfig(ConfigManager configManager) { return configManager.getConfig(SlayerConfig.class); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -387,8 +406,7 @@ public class SlayerPlugin extends Plugin config.streak(streak); } - @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) + private void onNpcSpawned(NpcSpawned npcSpawned) { NPC npc = npcSpawned.getNpc(); if (isTarget(npc, targetNames)) @@ -397,8 +415,7 @@ public class SlayerPlugin extends Plugin } } - @Subscribe - public void onNpcDefinitionChanged(NpcDefinitionChanged event) + private void onNpcDefinitionChanged(NpcDefinitionChanged event) { NPC npc = event.getNpc(); @@ -408,8 +425,7 @@ public class SlayerPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { NPC npc = npcDespawned.getNpc(); boolean contained = highlightedTargets.remove(npc); @@ -420,8 +436,7 @@ public class SlayerPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + void onVarbitChanged(VarbitChanged event) { if (client.getVar(Varbits.SLAYER_REWARD_POINTS) == cachedPoints) { @@ -528,8 +543,7 @@ public class SlayerPlugin extends Plugin private static final int FORCED_WAIT = 2; private int forcedWait = -1; - @Subscribe - public void onGameTick(GameTick tick) + void onGameTick(GameTick tick) { loginTick = false; @@ -610,8 +624,7 @@ public class SlayerPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM) { @@ -696,8 +709,7 @@ public class SlayerPlugin extends Plugin } } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void onExperienceChanged(ExperienceChanged event) { if (event.getSkill() != SLAYER) { @@ -735,8 +747,7 @@ public class SlayerPlugin extends Plugin cachedXp = slayerExp; } - @Subscribe - public void onInteractingChanged(InteractingChanged event) + private void onInteractingChanged(InteractingChanged event) { if (client.getLocalPlayer() == null) { @@ -767,7 +778,6 @@ public class SlayerPlugin extends Plugin return SUPERIOR_SLAYER_MONSTERS.contains(name.toLowerCase()); } - @Subscribe private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("slayer")) @@ -1144,7 +1154,7 @@ public class SlayerPlugin extends Plugin else { player = Text.removeTags(chatMessage.getName()) - .replace('\u00A0', ' '); + .replace('\u00A0', ' '); } if (Integer.toString(getPoints()) == null) @@ -1153,11 +1163,11 @@ public class SlayerPlugin extends Plugin } String response = new ChatMessageBuilder() - .append(ChatColorType.NORMAL) - .append("Slayer Points: ") - .append(ChatColorType.HIGHLIGHT) - .append(Integer.toString(getPoints())) - .build(); + .append(ChatColorType.NORMAL) + .append("Slayer Points: ") + .append(ChatColorType.HIGHLIGHT) + .append(Integer.toString(getPoints())) + .build(); final MessageNode messageNode = chatMessage.getMessageNode(); messageNode.setRuneLiteFormatMessage(response); @@ -1259,4 +1269,4 @@ public class SlayerPlugin extends Plugin this.lastCertainAmount = config.lastCertainAmount(); this.taskLocation = config.taskLocation(); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java index 538c5326bc..de867b0284 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java @@ -339,4 +339,4 @@ enum Task { return tasks.get(taskName.toLowerCase()); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java index 682f39ba2f..5753e46f39 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayermusiq/SlayermusiqPlugin.java @@ -63,7 +63,7 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -96,20 +96,23 @@ public class SlayermusiqPlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { - // + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); } @Override protected void shutDown() throws Exception { - // + eventBus.unregister(this); } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { int widgetID = event.getActionParam1(); if (Ints.contains(QUESTLIST_WIDGET_IDS, widgetID) && "Read Journal:".equals(event.getOption())) @@ -124,7 +127,6 @@ public class SlayermusiqPlugin extends Plugin } } - @Subscribe private void onMenuOptionClicked(MenuOptionClicked ev) { if (ev.getMenuAction() == MenuAction.RUNELITE && ev.getOption().equals(MENUOP_SLAYERMUSIQ)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java index 9d821ad6ab..a549677479 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java @@ -36,7 +36,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; @@ -61,6 +61,9 @@ public class SmeltingPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private SmeltingSession session; @@ -75,6 +78,8 @@ public class SmeltingPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + this.statTimeout = config.statTimeout(); session = null; overlayManager.add(overlay); @@ -83,12 +88,20 @@ public class SmeltingPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); session = null; } - @Subscribe - public void onChatMessage(ChatMessage event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.SPAM) { @@ -113,8 +126,7 @@ public class SmeltingPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (session != null) { @@ -128,7 +140,6 @@ public class SmeltingPlugin extends Plugin } } - @Subscribe private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("smelting")) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java index aa1e66efd0..6fd663ad58 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spawntimer/SpawnTimerPlugin.java @@ -19,7 +19,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -39,6 +39,8 @@ public class SpawnTimerPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; @Getter(AccessLevel.PACKAGE) private final Set highlightedNpcs = new HashSet<>(); @@ -68,6 +70,8 @@ public class SpawnTimerPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.getNpcToHighlight = config.getNpcToHighlight(); this.getHighlightColor = config.getHighlightColor(); @@ -79,19 +83,28 @@ public class SpawnTimerPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + ticks.clear(); highlightedNpcs.clear(); overlayManager.remove(SpawnTimerOverlay); } - @Subscribe - public void onGameTick(GameTick g) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + } + + private void onGameTick(GameTick g) { currentTick++; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGIN_SCREEN || event.getGameState() == GameState.HOPPING) @@ -101,8 +114,7 @@ public class SpawnTimerPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned n) + private void onNpcSpawned(NpcSpawned n) { if (n.getNpc() != null) { @@ -115,8 +127,7 @@ public class SpawnTimerPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned n) + private void onNpcDespawned(NpcDespawned n) { final NPC npc = n.getNpc(); if (highlightedNpcs.contains(npc)) @@ -140,7 +151,6 @@ public class SpawnTimerPlugin extends Plugin return Text.fromCSV(configNpcs); } - @Subscribe private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("spawntimer")) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java index d58467d9f1..ecb7d2832d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specbar/SpecBarPlugin.java @@ -28,7 +28,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.events.ScriptCallbackEvent; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -47,18 +47,22 @@ public class SpecBarPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!"drawSpecbarAnyway".equals(event.getEventName())) { 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 3f164f87b0..c28057a6b7 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 @@ -46,7 +46,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.VarbitChanged; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -92,21 +92,36 @@ public class SpecialCounterPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private EventBus eventBus; + @Override protected void startUp() { + addSubscriptions(); + wsClient.registerMessage(SpecialCounterUpdate.class); } @Override protected void shutDown() { + eventBus.unregister(this); + removeCounters(); wsClient.unregisterMessage(SpecialCounterUpdate.class); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(SpecialCounterUpdate.class, this, this::onSpecialCounterUpdate); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -122,8 +137,7 @@ public class SpecialCounterPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { int specialPercentage = client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT); @@ -142,7 +156,6 @@ public class SpecialCounterPlugin extends Plugin specialHitpointsExperience = client.getSkillExperience(Skill.HITPOINTS); } - @Subscribe private void onGameTick(GameTick tick) { if (client.getGameState() != GameState.LOGGED_IN) @@ -219,8 +232,7 @@ public class SpecialCounterPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { NPC actor = npcDespawned.getNpc(); @@ -230,8 +242,7 @@ public class SpecialCounterPlugin extends Plugin } } - @Subscribe - public void onSpecialCounterUpdate(SpecialCounterUpdate event) + private void onSpecialCounterUpdate(SpecialCounterUpdate event) { if (party.getLocalMember().getMemberId().equals(event.getMemberId())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java index 0502330b79..3694512f1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java @@ -53,7 +53,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.MouseManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; @@ -120,6 +120,9 @@ public class SpellbookPlugin extends Plugin @Inject private SpellbookDragOverlay overlay; + @Inject + private EventBus eventBus; + @Getter private boolean dragging; @@ -151,6 +154,7 @@ public class SpellbookPlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); refreshMagicTabOption(); loadFilter(); @@ -160,6 +164,7 @@ public class SpellbookPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); clearMagicTabMenus(); saveSpells(); config.canDrag(false); @@ -168,8 +173,16 @@ public class SpellbookPlugin extends Plugin mouseListener = null; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(WidgetMenuOptionClicked.class, this, this::onWidgetMenuOptionClicked); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -177,8 +190,7 @@ public class SpellbookPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"spellbook".equals(event.getGroup())) { @@ -198,7 +210,6 @@ public class SpellbookPlugin extends Plugin refreshMagicTabOption(); } - @Subscribe public void onVarbitChanged(VarbitChanged event) { if (client.getGameState() != GameState.LOGGED_IN) @@ -252,9 +263,7 @@ public class SpellbookPlugin extends Plugin return false; } - - @Subscribe - public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + private void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) { if (event.getWidget() != WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB && event.getWidget() != WidgetInfo.RESIZABLE_VIEWPORT_MAGIC_TAB @@ -318,8 +327,7 @@ public class SpellbookPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (client.getVar(Varbits.FILTER_SPELLBOOK) != 0 || !this.enableMobile diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java index 1936f87664..3b7e8eecdb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java @@ -42,7 +42,7 @@ import net.runelite.api.NPCDefinition; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; @@ -94,6 +94,9 @@ public class StatusBarsPlugin extends Plugin @Inject private StatusBarsConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Instant lastCombatAction; @@ -114,6 +117,7 @@ public class StatusBarsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); barRenderers.put(BarMode.DISABLED, null); @@ -128,8 +132,7 @@ public class StatusBarsPlugin extends Plugin this.lastCombatAction = Instant.now(); } - @Subscribe - public void onGameTick(GameTick gameTick) + private void onGameTick(GameTick gameTick) { if (!this.toggleRestorationBars) { @@ -167,18 +170,25 @@ public class StatusBarsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); barRenderers.clear(); } + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + @Provides StatusBarsConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(StatusBarsConfig.class); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"statusbars".equals(event.getGroup())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusorbs/StatusOrbsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusorbs/StatusOrbsPlugin.java index 3e3e671f4a..ade1af9e64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusorbs/StatusOrbsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusorbs/StatusOrbsPlugin.java @@ -52,7 +52,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -102,6 +102,9 @@ public class StatusOrbsPlugin extends Plugin @Inject private Notifier notifier; + @Inject + private EventBus eventBus; + @Getter private double hitpointsPercentage; @@ -152,8 +155,9 @@ public class StatusOrbsPlugin extends Plugin @Override protected void startUp() throws Exception { - migrateConfigs(); updateConfig(); + addSubscriptions(); + overlayManager.add(overlay); if (this.dynamicHpHeart && client.getGameState().equals(GameState.LOGGED_IN)) { @@ -164,6 +168,8 @@ public class StatusOrbsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); localPlayerRunningToDestination = false; prevLocalPlayerLocation = null; @@ -174,8 +180,15 @@ public class StatusOrbsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("statusorbs")) { @@ -202,7 +215,6 @@ public class StatusOrbsPlugin extends Plugin } } - @Subscribe private void onVarbitChanged(VarbitChanged e) { if (this.dynamicHpHeart) @@ -218,7 +230,6 @@ public class StatusOrbsPlugin extends Plugin wasRapidHeal = isRapidHeal; } - @Subscribe private void onGameStateChanged(GameStateChanged ev) { if (ev.getGameState() == GameState.HOPPING || ev.getGameState() == GameState.LOGIN_SCREEN) @@ -229,8 +240,7 @@ public class StatusOrbsPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT) == 1000) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/StonedLootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/StonedLootTrackerPlugin.java index 6ba61372c2..edae7b42d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/StonedLootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/StonedLootTrackerPlugin.java @@ -70,7 +70,7 @@ import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.NpcLootReceived; import net.runelite.client.events.PlayerLootReceived; import net.runelite.client.game.ItemManager; @@ -141,6 +141,9 @@ public class StonedLootTrackerPlugin extends Plugin @Inject private LootRecordWriter writer; + @Inject + private EventBus eventBus; + private Multiset inventorySnapshot; @Provides @@ -149,8 +152,7 @@ public class StonedLootTrackerPlugin extends Plugin return configManager.getConfig(StonedLootTrackerConfig.class); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("stonedloottracker")) { @@ -173,6 +175,8 @@ public class StonedLootTrackerPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + panel = new LootTrackerPanel(itemManager, this); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); @@ -224,25 +228,37 @@ public class StonedLootTrackerPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + clientToolbar.removeNavigation(navButton); } - @Subscribe - public void onLootTrackerRecordStored(LootTrackerRecordStored s) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(LootTrackerRecordStored.class, this, this::onLootTrackerRecordStored); + eventBus.subscribe(LootTrackerNameChange.class, this, this::onLootTrackerNameChange); + eventBus.subscribe(NpcLootReceived.class, this, this::onNpcLootReceived); + eventBus.subscribe(PlayerLootReceived.class, this, this::onPlayerLootReceived); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onLootTrackerRecordStored(LootTrackerRecordStored s) { SwingUtilities.invokeLater(() -> panel.addLog(s.getRecord())); } - @Subscribe - public void onLootTrackerNameChange(LootTrackerNameChange c) + private void onLootTrackerNameChange(LootTrackerNameChange c) { refreshData(); SwingUtilities.invokeLater(() -> panel.updateNames()); } - @Subscribe - public void onNpcLootReceived(final NpcLootReceived npcLootReceived) + private void onNpcLootReceived(final NpcLootReceived npcLootReceived) { final NPC npc = npcLootReceived.getNpc(); final Collection items = npcLootReceived.getItems(); @@ -268,8 +284,7 @@ public class StonedLootTrackerPlugin extends Plugin addLog(name, rec); } - @Subscribe - public void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) + private void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) { final Player player = playerLootReceived.getPlayer(); final Collection items = playerLootReceived.getItems(); @@ -281,8 +296,7 @@ public class StonedLootTrackerPlugin extends Plugin addLog(name, rec); } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { final ItemContainer container; switch (event.getGroupId()) @@ -350,8 +364,7 @@ public class StonedLootTrackerPlugin extends Plugin writer.addLootTrackerRecord(record); } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE && event.getType() != ChatMessageType.SPAM) { @@ -471,8 +484,7 @@ public class StonedLootTrackerPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (eventType != null && (CHEST_EVENT_TYPES.containsValue(eventType) || HERBIBOR_EVENT.equals(eventType))) { @@ -671,8 +683,7 @@ public class StonedLootTrackerPlugin extends Plugin }); } - @Subscribe - public void onGameStateChanged(GameStateChanged c) + private void onGameStateChanged(GameStateChanged c) { if (c.getGameState().equals(GameState.LOGGED_IN)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/data/LootRecordWriter.java b/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/data/LootRecordWriter.java index 13b001151c..7b9f74b2f7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/data/LootRecordWriter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stonedloottracker/data/LootRecordWriter.java @@ -73,7 +73,7 @@ public class LootRecordWriter { playerFolder = new File(LOOT_RECORD_DIR, username); playerFolder.mkdir(); - bus.post(new LootTrackerNameChange()); + bus.post(LootTrackerNameChange.class, new LootTrackerNameChange()); } public Set getKnownFileNames() @@ -140,7 +140,7 @@ public class LootRecordWriter file.append(dataAsString); file.newLine(); file.close(); - bus.post(new LootTrackerRecordStored(rec)); + bus.post(LootTrackerRecordStored.class, new LootTrackerRecordStored(rec)); } catch (IOException ioe) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stretchedmode/StretchedModePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedmode/StretchedModePlugin.java index 1d57cdb4ee..2287f7cf2a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/stretchedmode/StretchedModePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stretchedmode/StretchedModePlugin.java @@ -32,7 +32,7 @@ import net.runelite.api.Client; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ResizeableChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -61,6 +61,9 @@ public class StretchedModePlugin extends Plugin @Inject private TranslateMouseWheelListener mouseWheelListener; + @Inject + private EventBus eventBus; + @Provides StretchedModeConfig provideConfig(ConfigManager configManager) { @@ -70,6 +73,9 @@ public class StretchedModePlugin extends Plugin @Override protected void startUp() { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ResizeableChanged.class, this, this::onResizeableChanged); + mouseManager.registerMouseListener(0, mouseListener); mouseManager.registerMouseWheelListener(0, mouseWheelListener); @@ -80,6 +86,8 @@ public class StretchedModePlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + client.setStretchedEnabled(false); client.invalidateStretching(true); @@ -87,14 +95,12 @@ public class StretchedModePlugin extends Plugin mouseManager.unregisterMouseWheelListener(mouseWheelListener); } - @Subscribe - public void onResizeableChanged(ResizeableChanged event) + private void onResizeableChanged(ResizeableChanged event) { client.invalidateStretching(true); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("stretchedmode")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java index 6b0d864198..27e1afe746 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/suppliestracker/SuppliesTrackerPlugin.java @@ -62,7 +62,7 @@ import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -150,10 +150,14 @@ public class SuppliesTrackerPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; @Override protected void startUp() throws Exception { + addSubscriptions(); + panel = new SuppliesTrackerPanel(itemManager, this); final BufferedImage header = ImageUtil.getResourceStreamFromClass(getClass(), "panel_icon.png"); panel.loadHeaderIcon(header); @@ -172,17 +176,27 @@ public class SuppliesTrackerPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); clientToolbar.removeNavigation(navButton); } + private void addSubscriptions() + { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(CannonballFired.class, this, this::onCannonballFired); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + } + @Provides SuppliesTrackerConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(SuppliesTrackerConfig.class); } - @Subscribe - public void onGameTick(GameTick tick) + private void onGameTick(GameTick tick) { Player player = client.getLocalPlayer(); if (player.getAnimation() == BLOWPIPE_ATTACK) @@ -239,8 +253,7 @@ public class SuppliesTrackerPlugin extends Plugin return percent; } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE)) { @@ -314,14 +327,12 @@ public class SuppliesTrackerPlugin extends Plugin } } - @Subscribe - public void onCannonballFired(CannonballFired cannonballFired) + private void onCannonballFired(CannonballFired cannonballFired) { buildEntries(CANNONBALL); } - @Subscribe - public void onAnimationChanged(AnimationChanged animationChanged) + private void onAnimationChanged(AnimationChanged animationChanged) { if (animationChanged.getActor() == client.getLocalPlayer()) { @@ -374,8 +385,7 @@ public class SuppliesTrackerPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged itemContainerChanged) + private void onItemContainerChanged(ItemContainerChanged itemContainerChanged) { ItemContainer itemContainer = itemContainerChanged.getItemContainer(); @@ -501,8 +511,7 @@ public class SuppliesTrackerPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(final MenuOptionClicked event) + private void onMenuOptionClicked(final MenuOptionClicked event) { // Uses stacks to push/pop for tick eating // Create pattern to find eat/drink at beginning diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tarnslair/TarnsLairPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tarnslair/TarnsLairPlugin.java index fc2bbff2f7..9bb03bf433 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tarnslair/TarnsLairPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tarnslair/TarnsLairPlugin.java @@ -43,7 +43,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.GroundObjectChanged; import net.runelite.api.events.GroundObjectDespawned; import net.runelite.api.events.GroundObjectSpawned; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -84,6 +84,9 @@ public class TarnsLairPlugin extends Plugin @Inject private TarnsLairOverlay overlay; + @Inject + private EventBus eventBus; + @Override protected void startUp() throws Exception { @@ -93,6 +96,8 @@ public class TarnsLairPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); staircases.clear(); wallTraps.clear(); @@ -100,51 +105,55 @@ public class TarnsLairPlugin extends Plugin inLair = false; } - @Subscribe - public void onGameTick(GameTick event) + private void addSubscriptions() + { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(GroundObjectChanged.class, this, this::onGroundObjectChanged); + eventBus.subscribe(GroundObjectDespawned.class, this, this::onGroundObjectDespawned); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onGameTick(GameTick event) { int regionID = client.getLocalPlayer().getWorldLocation().getRegionID(); inLair = (regionID == TARNS_LAIR_NORTH_REGION || regionID == TARNS_LAIR_SOUTH_REGION); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { onTileObject(event.getTile(), null, event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(GameObjectChanged event) + private void onGameObjectChanged(GameObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGameObject()); } - @Subscribe - public void onGameObjectDespawned(GameObjectDespawned event) + private void onGameObjectDespawned(GameObjectDespawned event) { onTileObject(event.getTile(), event.getGameObject(), null); } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { onTileObject(event.getTile(), null, event.getGroundObject()); } - @Subscribe - public void onGroundObjectChanged(GroundObjectChanged event) + private void onGroundObjectChanged(GroundObjectChanged event) { onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject()); } - @Subscribe - public void onGroundObjectDespawned(GroundObjectDespawned event) + private void onGroundObjectDespawned(GroundObjectDespawned event) { onTileObject(event.getTile(), event.getGroundObject(), null); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOADING) { 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 56740fdd0a..3897309b2a 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 @@ -39,7 +39,7 @@ import net.runelite.api.Skill; import net.runelite.api.events.DecorativeObjectDespawned; import net.runelite.api.events.DecorativeObjectSpawned; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -66,6 +66,9 @@ public class TearsOfGuthixPlugin extends Plugin @Inject private TearsOfGuthixExperienceOverlay experienceOverlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final Map streams = new HashMap<>(); @@ -75,6 +78,8 @@ public class TearsOfGuthixPlugin extends Plugin @Override protected void startUp() { + addSubscriptions(); + overlayManager.add(overlay); overlayManager.add(experienceOverlay); } @@ -82,14 +87,22 @@ public class TearsOfGuthixPlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(experienceOverlay); streams.clear(); playerLowestSkill = null; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(DecorativeObjectSpawned.class, this, this::onDecorativeObjectSpawned); + eventBus.subscribe(DecorativeObjectDespawned.class, this, this::onDecorativeObjectDespawned); + } + + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -120,8 +133,7 @@ public class TearsOfGuthixPlugin extends Plugin } } - @Subscribe - public void onDecorativeObjectSpawned(DecorativeObjectSpawned event) + private void onDecorativeObjectSpawned(DecorativeObjectSpawned event) { DecorativeObject object = event.getDecorativeObject(); @@ -133,8 +145,7 @@ public class TearsOfGuthixPlugin extends Plugin } } - @Subscribe - public void onDecorativeObjectDespawned(DecorativeObjectDespawned event) + private void onDecorativeObjectDespawned(DecorativeObjectDespawned event) { if (streams.isEmpty()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java index 26238c416b..142d40e982 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/TheatrePlugin.java @@ -35,7 +35,7 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.graphics.ModelOutlineRenderer; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -84,6 +84,9 @@ public class TheatrePlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + private Widget widget = null; @Getter(AccessLevel.PUBLIC) @@ -162,6 +165,7 @@ public class TheatrePlugin extends Plugin protected void startUp() { updateConfig(); + addSubscriptions(); room = TheatreRoom.UNKNOWN; @@ -178,6 +182,8 @@ public class TheatrePlugin extends Plugin @Override protected void shutDown() { + eventBus.unregister(this); + maidenHandler.onStop(); maidenHandler = null; @@ -202,8 +208,23 @@ public class TheatrePlugin extends Plugin overlayManager.remove(overlay); } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(NpcDefinitionChanged.class, this, this::onNpcDefinitionChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GroundObjectSpawned.class, this, this::onGroundObjectSpawned); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + } + + private void onSpotAnimationChanged(SpotAnimationChanged event) { if (maidenHandler != null) { @@ -211,8 +232,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onNpcDefinitionChanged(NpcDefinitionChanged event) + private void onNpcDefinitionChanged(NpcDefinitionChanged event) { if (maidenHandler != null) { @@ -220,8 +240,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { if (maidenHandler != null) { @@ -255,8 +274,7 @@ public class TheatrePlugin extends Plugin } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (maidenHandler != null) { @@ -285,8 +303,7 @@ public class TheatrePlugin extends Plugin } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { if (verzikHandler != null) { @@ -294,8 +311,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (maidenHandler != null) { @@ -303,8 +319,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded event) + private void onWidgetLoaded(WidgetLoaded event) { if (event.getGroupId() != WidgetID.PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID && event.getGroupId() != WidgetID.PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID) { @@ -322,8 +337,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (maidenHandler != null) { @@ -445,8 +459,7 @@ public class TheatrePlugin extends Plugin widget = null; } - @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) + private void onGroundObjectSpawned(GroundObjectSpawned event) { if (sotetsegHandler != null) { @@ -459,8 +472,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("Theatre")) { @@ -473,8 +485,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { if (bloatHandler != null) { @@ -487,8 +498,7 @@ public class TheatrePlugin extends Plugin } } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void onProjectileMoved(ProjectileMoved event) { if (sotetsegHandler != null) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java index f7c262c853..dddc77f9ad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/theatre/rooms/BloatHandler.java @@ -16,7 +16,6 @@ import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.VarbitChanged; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.theatre.RoomHandler; import net.runelite.client.plugins.theatre.TheatrePlugin; import net.runelite.client.plugins.theatre.TheatreRoom; @@ -129,7 +128,6 @@ public class BloatHandler extends RoomHandler } } - @Subscribe public void onVarbitChanged(VarbitChanged event) { if (client.getVar(Varbits.BLOAT_DOOR) == 1 && !bloatFlag) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java index fa73e5b00f..c7718bfaa7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java @@ -38,7 +38,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; @@ -67,6 +67,9 @@ public class ThievingPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private ThievingSession session; @@ -81,6 +84,8 @@ public class ThievingPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.statTimeout = config.statTimeout(); session = null; @@ -90,12 +95,20 @@ public class ThievingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); session = null; } - @Subscribe - public void onGameTick(GameTick gameTick) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onGameTick(GameTick gameTick) { if (session == null || this.statTimeout == 0) { @@ -111,10 +124,8 @@ public class ThievingPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { - if (event.getType() != ChatMessageType.SPAM) { return; @@ -145,8 +156,7 @@ public class ThievingPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"thieving".equals(event.getGroup())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ticktimers/TickTimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/ticktimers/TickTimersPlugin.java index b801e83a40..066b0163ad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ticktimers/TickTimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ticktimers/TickTimersPlugin.java @@ -42,7 +42,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.NPCManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -76,6 +76,8 @@ public class TickTimersPlugin extends Plugin private TickTimersConfig config; @Inject private NPCManager npcManager; + @Inject + private EventBus eventBus; @Getter(AccessLevel.PACKAGE) private Set npcContainer = new HashSet<>(); private boolean validRegion; @@ -105,19 +107,29 @@ public class TickTimersPlugin extends Plugin public void startUp() { updateConfig(); + addSubscriptions(); npcContainer.clear(); } @Override public void shutDown() { + eventBus.unregister(this); npcContainer.clear(); overlayManager.remove(timersOverlay); validRegion = false; } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() != GameState.LOGGED_IN) { @@ -137,8 +149,7 @@ public class TickTimersPlugin extends Plugin npcContainer.clear(); } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { if (!validRegion) { @@ -181,8 +192,7 @@ public class TickTimersPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { if (!validRegion) { @@ -217,7 +227,6 @@ public class TickTimersPlugin extends Plugin } } - @Subscribe public void onGameTick(GameTick Event) { if (!validRegion) @@ -254,8 +263,7 @@ public class TickTimersPlugin extends Plugin ); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"TickTimers".equals(event.getGroup())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsPlugin.java index 9a41a6a35b..c10ae5f23d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tileindicators/TileIndicatorsPlugin.java @@ -32,7 +32,7 @@ import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -55,6 +55,9 @@ public class TileIndicatorsPlugin extends Plugin @Inject private TileIndicatorsConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Color highlightDestinationColor; @Getter(AccessLevel.PACKAGE) @@ -78,17 +81,20 @@ public class TileIndicatorsPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!"tileindicators".equals(event.getGroup())) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameIndicator.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameIndicator.java index 6434ad8203..0cdf993aed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameIndicator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameIndicator.java @@ -25,22 +25,17 @@ package net.runelite.client.plugins.timers; import java.awt.Color; -import java.awt.image.BufferedImage; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.SpriteID; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.SpriteManager; +@Getter(AccessLevel.PACKAGE) enum GameIndicator { VENGEANCE_ACTIVE(SpriteID.SPELL_VENGEANCE_OTHER, GameTimerImageType.SPRITE, "Vengeance active"); - @Getter(AccessLevel.PACKAGE) private final String description; - @Getter(AccessLevel.PACKAGE) private String text; - @Getter(AccessLevel.PACKAGE) private Color textColor; private final int imageId; private final GameTimerImageType imageType; @@ -58,17 +53,4 @@ enum GameIndicator { this(imageId, idType, description, "", null); } - - BufferedImage getImage(ItemManager itemManager, SpriteManager spriteManager) - { - switch (imageType) - { - case ITEM: - return itemManager.getImage(imageId); - case SPRITE: - return spriteManager.getSprite(imageId, 0); - default: - return null; - } - } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 97b51e82fb..1f3406a040 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -27,7 +27,6 @@ */ package net.runelite.client.plugins.timers; -import java.awt.image.BufferedImage; import java.time.Duration; import java.time.temporal.ChronoUnit; import lombok.AccessLevel; @@ -35,9 +34,8 @@ import lombok.Getter; import net.runelite.api.GraphicID; import net.runelite.api.ItemID; import net.runelite.api.SpriteID; -import net.runelite.client.game.ItemManager; -import net.runelite.client.game.SpriteManager; +@Getter(AccessLevel.PACKAGE) enum GameTimer { STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", 2, ChronoUnit.MINUTES, true), @@ -77,13 +75,9 @@ enum GameTimer ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom"), DRAGON_FIRE_SHIELD(ItemID.DRAGONFIRE_SHIELD_11284, GameTimerImageType.ITEM, "Dragonfire Shield Special", 2, ChronoUnit.MINUTES); - @Getter(AccessLevel.PACKAGE) private final Duration duration; - @Getter(AccessLevel.PACKAGE) private final Integer graphicId; - @Getter(AccessLevel.PACKAGE) private final String description; - @Getter(AccessLevel.PACKAGE) private final boolean removedOnDeath; private final int imageId; @@ -118,17 +112,4 @@ enum GameTimer { this(imageId, idType, description, null, 1, ChronoUnit.MILLIS, false); } - - BufferedImage getImage(ItemManager itemManager, SpriteManager spriteManager) - { - switch (imageType) - { - case ITEM: - return itemManager.getImage(imageId); - case SPRITE: - return spriteManager.getSprite(imageId, 0); - default: - return null; - } - } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimerImageType.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimerImageType.java index 1d51d05e34..008e323fe1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimerImageType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimerImageType.java @@ -28,4 +28,4 @@ enum GameTimerImageType { ITEM, SPRITE -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/IndicatorIndicator.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/IndicatorIndicator.java index 395fd7ba74..85263b0f00 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/IndicatorIndicator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/IndicatorIndicator.java @@ -25,7 +25,6 @@ package net.runelite.client.plugins.timers; import java.awt.Color; -import java.awt.Image; import lombok.AccessLevel; import lombok.Getter; import net.runelite.client.plugins.Plugin; @@ -37,9 +36,9 @@ public class IndicatorIndicator extends InfoBox @Getter(AccessLevel.PACKAGE) private final GameIndicator indicator; - IndicatorIndicator(final GameIndicator indicator, final Image image, final Plugin plugin) + IndicatorIndicator(final GameIndicator indicator, final Plugin plugin) { - super(image, plugin); + super(null, plugin); this.indicator = indicator; setPriority(InfoBoxPriority.MED); } @@ -55,4 +54,4 @@ public class IndicatorIndicator extends InfoBox { return indicator.getTextColor(); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java index a5e3c44a2e..3cb6a7ef3e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TeleportWidget.java @@ -57,4 +57,4 @@ enum TeleportWidget } return null; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java index 5d7ffa5762..88776d3bb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimerTimer.java @@ -25,7 +25,6 @@ */ package net.runelite.client.plugins.timers; -import java.awt.image.BufferedImage; import java.time.temporal.ChronoUnit; import net.runelite.client.plugins.Plugin; import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; @@ -35,16 +34,16 @@ class TimerTimer extends Timer { private final GameTimer timer; - TimerTimer(final GameTimer timer, final Plugin plugin, final BufferedImage image) + TimerTimer(final GameTimer timer, final Plugin plugin) { - super(timer.getDuration().toMillis(), ChronoUnit.MILLIS, image, plugin); + super(timer.getDuration().toMillis(), ChronoUnit.MILLIS, null, plugin); this.timer = timer; setPriority(InfoBoxPriority.MED); } - TimerTimer(final GameTimer timer, final int amount, final Plugin plugin, final BufferedImage image) + TimerTimer(final GameTimer timer, final int amount, final Plugin plugin) { - super(timer.getDuration().toMillis() * amount, ChronoUnit.MILLIS, image, plugin); + super(timer.getDuration().toMillis() * amount, ChronoUnit.MILLIS, null, plugin); this.timer = timer; setPriority(InfoBoxPriority.MED); } @@ -53,4 +52,4 @@ class TimerTimer extends Timer { return timer; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java index 320509b301..4926b9893c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java @@ -220,4 +220,4 @@ public interface TimersConfig extends Config { return true; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 36ac85610f..b66d821b93 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.timers; import com.google.inject.Provides; -import java.awt.image.BufferedImage; import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; @@ -72,7 +71,7 @@ import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; import static net.runelite.api.widgets.WidgetInfo.PVP_WORLD_SAFE_ZONE; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; @@ -150,7 +149,10 @@ public class TimersPlugin extends Plugin @Inject private InfoBoxManager infoBoxManager; - + + @Inject + private EventBus eventBus; + private boolean showHomeMinigameTeleports; private boolean showAntiPoison; private boolean showAntiFire; @@ -181,11 +183,14 @@ public class TimersPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); } - + @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + infoBoxManager.removeIf(t -> t instanceof TimerTimer); lastRaidVarb = -1; lastPoint = null; @@ -198,8 +203,24 @@ public class TimersPlugin extends Plugin imbuedHeartClicked = false; } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(WidgetHiddenChanged.class, this, this::onWidgetHiddenChanged); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(LocalPlayerDeath.class, this, this::onLocalPlayerDeath); + eventBus.subscribe(BoostedLevelChanged.class, this, this::onBoostedLevelChanged); + } + + private void onVarbitChanged(VarbitChanged event) { int raidVarb = client.getVar(Varbits.IN_RAID); int vengCooldownVarb = client.getVar(Varbits.VENGEANCE_COOLDOWN); @@ -286,8 +307,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onWidgetHiddenChanged(WidgetHiddenChanged event) + private void onWidgetHiddenChanged(WidgetHiddenChanged event) { Widget widget = event.getWidget(); if (WorldType.isPvpWorld(client.getWorldType()) @@ -297,16 +317,15 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("timers")) { return; } - + updateConfig(); - + if (!this.showHomeMinigameTeleports) { removeGameTimer(HOME_TELEPORT); @@ -397,8 +416,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (this.showStamina && event.getOption().contains("Drink") @@ -464,8 +482,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.SPAM && event.getType() != ChatMessageType.GAMEMESSAGE) { @@ -620,8 +637,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { loggedInRace = false; @@ -670,8 +686,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { switch (gameStateChanged.getGameState()) { @@ -685,8 +700,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { Actor actor = event.getActor(); @@ -744,8 +758,7 @@ public class TimersPlugin extends Plugin lastAnimation = client.getLocalPlayer().getAnimation(); } - @Subscribe - public void onSpotAnimationChanged(SpotAnimationChanged event) + private void onSpotAnimationChanged(SpotAnimationChanged event) { Actor actor = event.getActor(); @@ -832,8 +845,7 @@ public class TimersPlugin extends Plugin * * @param itemContainerChanged */ - @Subscribe - public void onItemContainerChanged(ItemContainerChanged itemContainerChanged) + private void onItemContainerChanged(ItemContainerChanged itemContainerChanged) { ItemContainer container = itemContainerChanged.getItemContainer(); if (container == client.getItemContainer(InventoryID.EQUIPMENT)) @@ -868,8 +880,7 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned npcDespawned) + private void onNpcDespawned(NpcDespawned npcDespawned) { NPC npc = npcDespawned.getNpc(); @@ -886,14 +897,12 @@ public class TimersPlugin extends Plugin } } - @Subscribe - public void onLocalPlayerDeath(LocalPlayerDeath event) + private void onLocalPlayerDeath(LocalPlayerDeath event) { infoBoxManager.removeIf(t -> t instanceof TimerTimer && ((TimerTimer) t).getTimer().isRemovedOnDeath()); } - @Subscribe - public void onBoostedLevelChanged(BoostedLevelChanged event) + private void onBoostedLevelChanged(BoostedLevelChanged event) { Skill skill = event.getSkill(); @@ -919,8 +928,16 @@ public class TimersPlugin extends Plugin { removeGameTimer(timer); - BufferedImage image = timer.getImage(itemManager, spriteManager); - TimerTimer t = new TimerTimer(timer, this, image); + TimerTimer t = new TimerTimer(timer, this); + switch (timer.getImageType()) + { + case SPRITE: + spriteManager.getSpriteAsync(timer.getImageId(), 0, t); + break; + case ITEM: + t.setImage(itemManager.getImage(timer.getImageId())); + break; + } t.setTooltip(timer.getDescription()); infoBoxManager.addInfoBox(t); return t; @@ -930,8 +947,16 @@ public class TimersPlugin extends Plugin { removeGameTimer(timer); - BufferedImage image = timer.getImage(itemManager, spriteManager); - TimerTimer t = new TimerTimer(timer, duration, this, image); + TimerTimer t = new TimerTimer(timer, duration, this); + switch (timer.getImageType()) + { + case SPRITE: + spriteManager.getSpriteAsync(timer.getImageId(), 0, t); + break; + case ITEM: + t.setImage(itemManager.getImage(timer.getImageId())); + break; + } t.setTooltip(timer.getDescription()); infoBoxManager.addInfoBox(t); return t; @@ -946,8 +971,16 @@ public class TimersPlugin extends Plugin { removeGameIndicator(gameIndicator); - BufferedImage image = gameIndicator.getImage(itemManager, spriteManager); - IndicatorIndicator indicator = new IndicatorIndicator(gameIndicator, image, this); + IndicatorIndicator indicator = new IndicatorIndicator(gameIndicator, this); + switch (gameIndicator.getImageType()) + { + case SPRITE: + spriteManager.getSpriteAsync(gameIndicator.getImageId(), 0, indicator); + break; + case ITEM: + indicator.setImage(itemManager.getImage(gameIndicator.getImageId())); + break; + } indicator.setTooltip(gameIndicator.getDescription()); infoBoxManager.addInfoBox(indicator); @@ -966,7 +999,7 @@ public class TimersPlugin extends Plugin removeGameTimer(DMM_FULLTB); removeGameTimer(DMM_HALFTB); } - + private void updateConfig() { this.showHomeMinigameTeleports = config.showHomeMinigameTeleports(); @@ -988,4 +1021,4 @@ public class TimersPlugin extends Plugin this.showStaffOfTheDead = config.showStaffOfTheDead(); this.showAbyssalSireStun = config.showAbyssalSireStun(); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java index 516fb5eb94..4cd5d88456 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java @@ -41,7 +41,7 @@ import net.runelite.api.Varbits; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.ColorUtil; @@ -61,6 +61,9 @@ public class TimestampPlugin extends Plugin @Inject private TimestampConfig config; + @Inject + private EventBus eventBus; + @Getter private SimpleDateFormat formatter; @@ -73,17 +76,21 @@ public class TimestampPlugin extends Plugin @Override protected void startUp() throws Exception { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + updateFormatter(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + formatter = null; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("timestamp") && event.getKey().equals("format")) { @@ -91,8 +98,7 @@ public class TimestampPlugin extends Plugin } } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (!event.getEventName().equals("addTimestamp")) { 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 9279883311..dbd23caabf 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 @@ -42,7 +42,7 @@ import net.runelite.api.events.UsernameChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -88,6 +88,9 @@ public class TimeTrackingPlugin extends Plugin @Inject private ScheduledExecutorService executorService; + @Inject + private EventBus eventBus; + private ScheduledFuture panelUpdateFuture; private TimeTrackingPanel panel; @@ -106,6 +109,8 @@ public class TimeTrackingPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + clockManager.loadTimers(); clockManager.loadStopwatches(); birdHouseTracker.loadFromConfig(); @@ -130,6 +135,8 @@ public class TimeTrackingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + lastTickLocation = null; lastTickPostLogin = false; @@ -142,8 +149,14 @@ public class TimeTrackingPlugin extends Plugin clientToolbar.removeNavigation(navButton); } - @Subscribe - public void onConfigChanged(ConfigChanged e) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(UsernameChanged.class, this, this::onUsernameChanged); + } + + private void onConfigChanged(ConfigChanged e) { if (!e.getGroup().equals(CONFIG_GROUP)) { @@ -160,8 +173,7 @@ public class TimeTrackingPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick t) + private void onGameTick(GameTick t) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -200,8 +212,7 @@ public class TimeTrackingPlugin extends Plugin } } - @Subscribe - public void onUsernameChanged(UsernameChanged e) + private void onUsernameChanged(UsernameChanged e) { farmingTracker.loadCompletionTimes(); birdHouseTracker.loadFromConfig(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java index e4dcf97508..b99212963b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Set; import javax.swing.JLabel; import javax.swing.border.EmptyBorder; -import lombok.extern.slf4j.Slf4j; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.timetracking.TabContentPanel; import net.runelite.client.plugins.timetracking.TimeTrackingConfig; @@ -42,7 +41,6 @@ import net.runelite.client.plugins.timetracking.TimeablePanel; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; -@Slf4j public class FarmingTabPanel extends TabContentPanel { private final FarmingTracker farmingTracker; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java index bc69f169fe..c3295578f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java @@ -39,7 +39,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameTick; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; @@ -62,6 +62,9 @@ public class TitheFarmPlugin extends Plugin @Inject private TitheFarmPluginConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private final Set plants = new HashSet<>(); @@ -82,6 +85,8 @@ public class TitheFarmPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + overlayManager.add(titheFarmOverlay); titheFarmOverlay.updateConfig(); } @@ -89,11 +94,19 @@ public class TitheFarmPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(titheFarmOverlay); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("tithefarmplugin")) { @@ -103,14 +116,12 @@ public class TitheFarmPlugin extends Plugin } } - @Subscribe - public void onGameTick(final GameTick event) + private void onGameTick(final GameTick event) { plants.removeIf(plant -> plant.getPlantTimeRelative() == 1); } - @Subscribe - public void onGameObjectSpawned(GameObjectSpawned event) + private void onGameObjectSpawned(GameObjectSpawned event) { GameObject gameObject = event.getGameObject(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tmorph/TMorph.java b/runelite-client/src/main/java/net/runelite/client/plugins/tmorph/TMorph.java index 133636aa77..1a432301ae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tmorph/TMorph.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tmorph/TMorph.java @@ -35,7 +35,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.kit.KitType; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -57,6 +57,9 @@ public class TMorph extends Plugin @Inject private TMorphConfig config; + @Inject + private EventBus eventBus; + private boolean mageSwap; private boolean rangeSwap; private boolean meleeSwap; @@ -128,10 +131,23 @@ public class TMorph extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("TMorph")) { @@ -139,8 +155,7 @@ public class TMorph extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { if (this.animationTarget <= 0 && this.animationSwap <= 0 && this.globalAnimSwap > 0) { @@ -158,8 +173,7 @@ public class TMorph extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (client.getGameState() != GameState.LOGGED_IN) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java index 842e1cc887..e2c60ac3ca 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tobdamagecount/DamageCounterPlugin.java @@ -46,12 +46,11 @@ import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; - @PluginDescriptor( name = "ToB Damage Counter", description = "Gives you an estimation damage on a boss and taken after the fight is done" + @@ -105,9 +104,27 @@ public class DamageCounterPlugin extends Plugin private Client client; @Inject private ChatMessageManager chatMessangerManager; + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(LocalPlayerDeath.class, this, this::onLocalPlayerDeath); + } + + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } //every game tick it will go through methods - @Subscribe private void onGameTick(GameTick tick) { if (client.getGameState() != GameState.LOGGED_IN) @@ -140,9 +157,8 @@ public class DamageCounterPlugin extends Plugin } } - @Subscribe //if you hop it will reset the counter - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { if (event.getGameState() == GameState.LOGGED_IN) { @@ -192,7 +208,6 @@ public class DamageCounterPlugin extends Plugin } - @Subscribe //will add the damage that you have taken from the current boss fight private void onHitsplatApplied(HitsplatApplied Hit) { @@ -208,8 +223,7 @@ public class DamageCounterPlugin extends Plugin because every time she phases she "dies" so making sure the counter doesn't print out the damage for phase 1, 2, and 3. */ - @Subscribe - public void onNpcDespawned(NpcDespawned npc) + private void onNpcDespawned(NpcDespawned npc) { NPC actor = npc.getNpc(); double Percent = calculatePercent(WorldPoint.fromLocalInstance(client, @@ -310,7 +324,6 @@ public class DamageCounterPlugin extends Plugin sendChatMessage(MessageTaken); } - @Subscribe //whenever you have died in tob you will get a death message with damage // made sure the message works at ToB area or else it will message every where private void onLocalPlayerDeath(LocalPlayerDeath death) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java index 62923981a9..b409c84217 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/twitch/TwitchPlugin.java @@ -42,7 +42,7 @@ import net.runelite.client.chat.ChatboxInputListener; import net.runelite.client.chat.CommandManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.ChatboxInput; import net.runelite.client.events.PrivateMessageInput; import net.runelite.client.plugins.Plugin; @@ -72,11 +72,16 @@ public class TwitchPlugin extends Plugin implements TwitchListener, ChatboxInput @Inject private CommandManager commandManager; + @Inject + private EventBus eventBus; + private TwitchIRCClient twitchIRCClient; @Override protected void startUp() { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + connect(); commandManager.register(this); } @@ -84,6 +89,8 @@ public class TwitchPlugin extends Plugin implements TwitchListener, ChatboxInput @Override protected void shutDown() { + eventBus.unregister(this); + if (twitchIRCClient != null) { twitchIRCClient.close(); @@ -149,8 +156,7 @@ public class TwitchPlugin extends Plugin implements TwitchListener, ChatboxInput } } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (!configChanged.getGroup().equals("twitch")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java index 9d3179c68c..3207e576bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vetion/VetionPlugin.java @@ -33,7 +33,7 @@ import lombok.Getter; import net.runelite.api.Actor; import net.runelite.api.AnimationID; import net.runelite.api.events.AnimationChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -56,12 +56,17 @@ public class VetionPlugin extends Plugin @Inject private VetionOverlay overlay; + @Inject + private EventBus eventBus; + @Getter private Map vetions; @Override protected void startUp() { + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + vetions = new HashMap<>(); overlayManager.add(overlay); } @@ -73,9 +78,7 @@ public class VetionPlugin extends Plugin vetions = null; } - - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { if (event.getActor().getAnimation() == AnimationID.VETION_EARTHQUAKE) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/virtuallevels/VirtualLevelsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/virtuallevels/VirtualLevelsPlugin.java index c9f3bb462f..719b55a6b4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/virtuallevels/VirtualLevelsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/virtuallevels/VirtualLevelsPlugin.java @@ -35,7 +35,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.PluginChanged; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -60,20 +60,33 @@ public class VirtualLevelsPlugin extends Plugin @Inject private ClientThread clientThread; + @Inject + private EventBus eventBus; + @Provides VirtualLevelsConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(VirtualLevelsConfig.class); } + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(PluginChanged.class, this, this::onPluginChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + } + @Override protected void shutDown() { + eventBus.unregister(this); + clientThread.invoke(this::simulateSkillChange); } - @Subscribe - public void onPluginChanged(PluginChanged pluginChanged) + private void onPluginChanged(PluginChanged pluginChanged) { // this is guaranteed to be called after the plugin has been registered by the eventbus. startUp is not. if (pluginChanged.getPlugin() == this) @@ -82,8 +95,7 @@ public class VirtualLevelsPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged configChanged) + private void onConfigChanged(ConfigChanged configChanged) { if (!configChanged.getGroup().equals("virtuallevels")) { @@ -93,8 +105,7 @@ public class VirtualLevelsPlugin extends Plugin clientThread.invoke(this::simulateSkillChange); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent e) + private void onScriptCallbackEvent(ScriptCallbackEvent e) { final String eventName = e.getEventName(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/AcidPathOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/AcidPathOverlay.java new file mode 100644 index 0000000000..b0ebab25a9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/AcidPathOverlay.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2018, https://runelitepl.us + * Copyright (c) 2019, Infinitay + * + * 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.vorkath; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; + +public class AcidPathOverlay extends Overlay +{ + private static final Color ACID_SPOTS_COLOR = Color.GREEN; + private static final Color ACID_FREE_PATH_COLOR = Color.PINK; + private static final Color WOOXWALK_ATTACK_SPOT_COLOR = Color.YELLOW; + private static final Color WOOXWALK_OUT_OF_REACH_SPOT_COLOR = Color.RED; + private static final int BAR_INDICATOR_SPACER = 5; + + private final Client client; + private final VorkathPlugin plugin; + + @Inject + public AcidPathOverlay(final Client client, final VorkathPlugin plugin) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + + this.client = client; + this.plugin = plugin; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (plugin.getVorkath() == null || plugin.getVorkath().getVorkath().getLocalLocation() == null) + { + return null; + } + + if (plugin.isIndicateAcidPools() && plugin.getAcidSpots() != null + && !plugin.getAcidSpots().isEmpty()) + { + for (WorldPoint acidWorldPoint : plugin.getAcidSpots()) + { + LocalPoint acidLocalPoint = LocalPoint.fromWorld(client, acidWorldPoint); + if (acidLocalPoint == null) + { + continue; + } + OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client, + acidLocalPoint), ACID_SPOTS_COLOR); + } + } + + if (plugin.isIndicateAcidFreePath() && plugin.getAcidFreePath() != null + && !plugin.getAcidFreePath().isEmpty()) + { + for (WorldPoint acidFreeWorldPoint : plugin.getAcidFreePath()) + { + LocalPoint acidFreeLocalPoint = LocalPoint.fromWorld(client, acidFreeWorldPoint); + if (acidFreeLocalPoint == null) + { + continue; + } + + OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client, + acidFreeLocalPoint), ACID_FREE_PATH_COLOR); + } + } + + if (plugin.isIndicateWooxWalkPath() && plugin.getWooxWalkPath()[0] != null + && plugin.getWooxWalkPath()[1] != null) + { + LocalPoint attackLocalPoint = LocalPoint.fromWorld(client, plugin.getWooxWalkPath()[0]); + LocalPoint outOfReachLocalPoint = LocalPoint.fromWorld(client, plugin.getWooxWalkPath()[1]); + + if (attackLocalPoint != null && outOfReachLocalPoint != null) + { + OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client, + attackLocalPoint), Color.YELLOW); + OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client, + outOfReachLocalPoint), Color.RED); + + if (plugin.isIndicateWooxWalkTick() && plugin.getWooxWalkBar() != null + && plugin.getWooxWalkTimer() != -1) + { + int[] xpointsAttack = { + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2.0 + 1), + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth()), + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth()), + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2 + 1) + }; + int[] xpointsOutOfReach = { + (int) plugin.getWooxWalkBar().getX(), + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2.0), + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2.0), + (int) plugin.getWooxWalkBar().getX() + }; + int[] ypointsBoth = { + (int) plugin.getWooxWalkBar().getY(), + (int) plugin.getWooxWalkBar().getY(), + (int) (plugin.getWooxWalkBar().getY() + plugin.getWooxWalkBar().getHeight()), + (int) (plugin.getWooxWalkBar().getY() + plugin.getWooxWalkBar().getHeight()) + }; + Polygon wooxWalkAttack = new Polygon(xpointsAttack, ypointsBoth, 4); + Polygon wooxWalkOutOfReach = new Polygon(xpointsOutOfReach, ypointsBoth, 4); + OverlayUtil.renderPolygon(graphics, wooxWalkAttack, WOOXWALK_ATTACK_SPOT_COLOR); + OverlayUtil.renderPolygon(graphics, wooxWalkOutOfReach, WOOXWALK_OUT_OF_REACH_SPOT_COLOR); + + long timeLeft = (System.currentTimeMillis() - plugin.getWooxWalkTimer()) % 1200; + double timeScale; + if (timeLeft <= 600) + { + timeScale = 1 - timeLeft / 600.0; + } + else + { + timeLeft -= 600; + timeScale = timeLeft / 600.0; + } + int progress = (int) Math.round(plugin.getWooxWalkBar().getWidth() * timeScale); + + int[] xpointsIndicator = { + (int) (plugin.getWooxWalkBar().getX() - plugin.getWooxWalkBar().getHeight() / 2 + progress), + (int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getHeight() / 2 + progress), + (int) plugin.getWooxWalkBar().getX() + progress + }; + int[] ypointsIndicator = { + (int) (plugin.getWooxWalkBar().getY() - plugin.getWooxWalkBar().getHeight() - BAR_INDICATOR_SPACER), + (int) (plugin.getWooxWalkBar().getY() - plugin.getWooxWalkBar().getHeight() - BAR_INDICATOR_SPACER), + (int) (plugin.getWooxWalkBar().getY() - BAR_INDICATOR_SPACER) + }; + Polygon indicator = new Polygon(xpointsIndicator, ypointsIndicator, 3); + OverlayUtil.renderPolygon(graphics, indicator, Color.WHITE); + } + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/Vorkath.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/Vorkath.java index 02ae424527..b2fd6551ed 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/Vorkath.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/Vorkath.java @@ -38,23 +38,12 @@ public class Vorkath static final int FIRE_BALL_ATTACKS = 25; private NPC vorkath; - private VorkathAttack lastAttack; - private Phase currentPhase; private Phase nextPhase; private Phase lastPhase; - private int attacksLeft; - enum Phase - { - UNKNOWN, - ACID, - FIRE_BALL, - SPAWN - } - public Vorkath(NPC vorkath) { this.vorkath = vorkath; @@ -107,4 +96,12 @@ public class Vorkath log.debug("[Vorkath] Update! Last Phase: {}->{}, Current Phase: {}->{}, Next Phase: {}->{}, Attacks: {}->{}", oldLastPhase, this.lastPhase, oldCurrentPhase, this.currentPhase, oldNextPhase, this.nextPhase, oldAttacksLeft, this.attacksLeft); } + + enum Phase + { + UNKNOWN, + ACID, + FIRE_BALL, + SPAWN + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathAttack.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathAttack.java index 6a2479c57b..d1a2ec95ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathAttack.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathAttack.java @@ -82,9 +82,6 @@ public enum VorkathAttack */ ZOMBIFIED_SPAWN(AnimationID.VORKATH_FIRE_BOMB_OR_SPAWN_ATTACK, ProjectileID.VORKATH_SPAWN_AOE); - private final int vorkathAnimationID; - private final int projectileID; - private static final Map VORKATH_ATTACKS; private static final Map VORKATH_BASIC_ATTACKS; @@ -113,6 +110,9 @@ public enum VorkathAttack VORKATH_BASIC_ATTACKS = builder.build(); } + private final int vorkathAnimationID; + private final int projectileID; + /** * @param projectileID id of projectile * @return {@link VorkathAttack} associated with the specified projectile @@ -123,7 +123,7 @@ public enum VorkathAttack } /** - * @param projectileID + * @param projectileID id of projectile * @return true if the projectile id matches a {@link VorkathAttack#getProjectileID()} within {@link VorkathAttack#VORKATH_BASIC_ATTACKS}, * false otherwise */ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java new file mode 100644 index 0000000000..46a51ca8f0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathConfig.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018, Jordan Atwood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.vorkath; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("vorkath") +public interface VorkathConfig extends Config +{ + @ConfigItem( + keyName = "indicateAcidPools", + name = "Acid Pools", + description = "Indicate the acid pools", + position = 0 + ) + default boolean indicateAcidPools() + { + return false; + } + + @ConfigItem( + keyName = "indicateAcidFreePath", + name = "Acid Free Path", + description = "Indicate the most efficient acid free path", + position = 1 + ) + default boolean indicateAcidFreePath() + { + return true; + } + + @ConfigItem( + keyName = "acidFreePathMinLength", + name = "Minimum Length Acid Free Path", + description = "The minimum length of an acid free path", + position = 2, + hidden = true, + unhide = "indicateAcidFreePath" + ) + default int acidFreePathLength() + { + return 5; + } + + @ConfigItem( + keyName = "indicateWooxWalkPath", + name = "WooxWalk Path", + description = "Indicate the closest WooxWalk path", + position = 3 + ) + default boolean indicateWooxWalkPath() + { + return true; + } + + @ConfigItem( + keyName = "indicateWooxWalkTick", + name = "WooxWalk Tick", + description = "Indicate on which tile to click during each game tick", + position = 4 + ) + default boolean indicateWooxWalkTick() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java index d55484adb6..11b363fa72 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathOverlay.java @@ -26,7 +26,6 @@ */ package net.runelite.client.plugins.vorkath; -import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -41,6 +40,8 @@ import net.runelite.api.coords.LocalPoint; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.ImageUtil; @Singleton public class VorkathOverlay extends Overlay @@ -50,6 +51,18 @@ public class VorkathOverlay extends Overlay private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255); private static final int OVERLAY_ICON_DISTANCE = 30; private static final int OVERLAY_ICON_MARGIN = 1; + private static final BufferedImage UNKNOWN; + private static final BufferedImage ACID; + private static final BufferedImage FIRE_BALL; + private static final BufferedImage SPAWN; + + static + { + UNKNOWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png"); + ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png"); + FIRE_BALL = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "fire_strike.png"); + SPAWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png"); + } private final Client client; private final VorkathPlugin plugin; @@ -68,9 +81,9 @@ public class VorkathOverlay extends Overlay { if (plugin.getVorkath() != null) { - Vorkath vorkath = plugin.getVorkath(); + final Vorkath vorkath = plugin.getVorkath(); - LocalPoint localLocation = vorkath.getVorkath().getLocalLocation(); + final LocalPoint localLocation = vorkath.getVorkath().getLocalLocation(); if (localLocation != null) { Point point = Perspective.localToCanvas(client, localLocation, client.getPlane(), vorkath.getVorkath().getLogicalHeight() + 16); @@ -78,7 +91,7 @@ public class VorkathOverlay extends Overlay { point = new Point(point.getX(), point.getY()); - BufferedImage currentPhaseIcon = getIcon(vorkath); + final BufferedImage currentPhaseIcon = getIcon(vorkath); int totalWidth = 0; if (currentPhaseIcon != null) @@ -88,41 +101,33 @@ public class VorkathOverlay extends Overlay int bgPadding = 8; int currentPosX = 0; - graphics.setStroke(new BasicStroke(2)); - graphics.setColor(COLOR_ICON_BACKGROUND); - graphics.fillOval( - point.getX() - totalWidth / 2 + currentPosX - bgPadding, - point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, - currentPhaseIcon.getWidth() + bgPadding * 2, - currentPhaseIcon.getHeight() + bgPadding * 2); + if (currentPhaseIcon == null) + { + return null; + } - graphics.setColor(COLOR_ICON_BORDER); - graphics.drawOval( - point.getX() - totalWidth / 2 + currentPosX - bgPadding, - point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, - currentPhaseIcon.getWidth() + bgPadding * 2, - currentPhaseIcon.getHeight() + bgPadding * 2); + OverlayUtil.setProgressIcon(graphics, point, currentPhaseIcon, totalWidth, bgPadding, currentPosX, + COLOR_ICON_BACKGROUND, OVERLAY_ICON_DISTANCE, COLOR_ICON_BORDER, COLOR_ICON_BORDER_FILL); - graphics.drawImage( - currentPhaseIcon, - point.getX() - totalWidth / 2 + currentPosX, - point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE, - null); - - graphics.setColor(COLOR_ICON_BORDER_FILL); - Arc2D.Double arc = new Arc2D.Double( + final Arc2D.Double arc = new Arc2D.Double( point.getX() - totalWidth / 2 + currentPosX - bgPadding, - point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, + point.getY() - (float) (currentPhaseIcon.getHeight() / 2) - OVERLAY_ICON_DISTANCE - bgPadding, currentPhaseIcon.getWidth() + bgPadding * 2, currentPhaseIcon.getHeight() + bgPadding * 2, 90.0, -360.0 * getAttacksLeftProgress(), - Arc2D.OPEN); + Arc2D.OPEN + ); graphics.draw(arc); } } } + if (plugin.getZombifiedSpawn() != null) + { + OverlayUtil.renderActorOverlayImage(graphics, plugin.getZombifiedSpawn(), SPAWN, Color.green, 10); + } + return null; } @@ -135,13 +140,13 @@ public class VorkathOverlay extends Overlay switch (vorkath.getCurrentPhase()) { case UNKNOWN: - return VorkathPlugin.UNKNOWN; + return UNKNOWN; case ACID: - return VorkathPlugin.ACID; + return ACID; case FIRE_BALL: - return VorkathPlugin.FIRE_BALL; + return FIRE_BALL; case SPAWN: - return VorkathPlugin.SPAWN; + return SPAWN; } return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java index 58cefc7efe..60063c25e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java @@ -27,28 +27,47 @@ package net.runelite.client.plugins.vorkath; import com.google.inject.Inject; +import com.google.inject.Provides; import com.google.inject.Singleton; -import java.awt.image.BufferedImage; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Actor; import net.runelite.api.Client; +import net.runelite.api.GameObject; import net.runelite.api.NPC; -import net.runelite.api.NpcID; +import net.runelite.api.ObjectID; +import net.runelite.api.Projectile; +import net.runelite.api.ProjectileID; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.AnimationChanged; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.ProjectileMoved; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.api.events.ProjectileSpawned; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.util.ImageUtil; import org.apache.commons.lang3.ArrayUtils; @PluginDescriptor( name = "Vorkath Helper", - description = "Count vorkath attacks, and which phase is coming next", + description = "Count vorkath attacks, indicate next phase, wooxwalk timer, indicate path through acid", tags = {"combat", "overlay", "pve", "pvm"}, type = PluginType.PVM, enabledByDefault = false @@ -61,93 +80,146 @@ public class VorkathPlugin extends Plugin @Inject private Client client; - @Inject private OverlayManager overlayManager; - @Inject private VorkathOverlay overlay; - @Inject - private ZombifiedSpawnOverlay SpawnOverlay; - - @Getter + private AcidPathOverlay acidPathOverlay; + @Inject + private VorkathConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private Vorkath vorkath; - - @Getter + @Getter(AccessLevel.PACKAGE) private NPC zombifiedSpawn; + @Getter(AccessLevel.PACKAGE) + private List acidSpots = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private List acidFreePath = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) + private WorldPoint[] wooxWalkPath = new WorldPoint[2]; + @Getter(AccessLevel.PACKAGE) + private long wooxWalkTimer = -1; + @Getter(AccessLevel.PACKAGE) + private Rectangle wooxWalkBar; + private int lastAcidSpotsSize = 0; + // Config values + @Getter(AccessLevel.PACKAGE) + private boolean indicateAcidPools; + @Getter(AccessLevel.PACKAGE) + private boolean indicateAcidFreePath; + @Getter(AccessLevel.PACKAGE) + private boolean indicateWooxWalkPath; + @Getter(AccessLevel.PACKAGE) + private boolean indicateWooxWalkTick; + private int acidFreePathLength; - /** - * The last projectile's starting movement cycle - */ - private int lastProjectileCycle; - - static final BufferedImage UNKNOWN; - static final BufferedImage ACID; - static final BufferedImage FIRE_BALL; - static final BufferedImage SPAWN; - - static + @Provides + VorkathConfig provideConfig(ConfigManager configManager) { - UNKNOWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png"); - ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png"); - FIRE_BALL = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "fire_strike.png"); - SPAWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png"); + return configManager.getConfig(VorkathConfig.class); } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + @Override + protected void startUp() { - if (isAtVorkath()) - { - if (isVorkath(event.getNpc().getId())) - { - vorkath = new Vorkath(event.getNpc()); - lastProjectileCycle = -1; - overlayManager.add(overlay); - } - else if (isZombifiedSpawn(event.getNpc().getId())) - { - zombifiedSpawn = event.getNpc(); - overlayManager.add(SpawnOverlay); - } - } + addSubscriptions(); + updateConfig(); } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + @Override + protected void shutDown() { - if (isAtVorkath()) - { - if (isVorkath(event.getNpc().getId())) - { - vorkath = null; - lastProjectileCycle = -1; - overlayManager.remove(overlay); - } - else if (isZombifiedSpawn(event.getNpc().getId())) - { - zombifiedSpawn = null; - overlayManager.remove(SpawnOverlay); - } - } + reset(); } - @Subscribe - public void onProjectileMoved(ProjectileMoved event) + private void addSubscriptions() { - // Only capture initial projectile - if (!isAtVorkath() || event.getProjectile().getStartMovementCycle() == lastProjectileCycle) + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); + eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(ClientTick.class, this, this::onClientTick); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) + { + if (!event.getGroup().equals("vorkath")) { return; } - VorkathAttack vorkathAttack = VorkathAttack.getVorkathAttack(event.getProjectile().getId()); + updateConfig(); + } + + private void onNpcSpawned(NpcSpawned event) + { + if (!isAtVorkath()) + { + return; + } + + final NPC npc = event.getNpc(); + + if (npc.getName() == null) + { + return; + } + + if (npc.getName().equals("Vorkath")) + { + vorkath = new Vorkath(npc); + overlayManager.add(overlay); + } + else if (npc.getName().equals("Zombified Spawn")) + { + zombifiedSpawn = npc; + } + } + + private void onNpcDespawned(NpcDespawned event) + { + if (!isAtVorkath()) + { + return; + } + + final NPC npc = event.getNpc(); + + if (npc.getName() == null) + { + return; + } + + if (npc.getName().equals("Vorkath")) + { + reset(); + } + else if (npc.getName().equals("Zombified Spawn")) + { + zombifiedSpawn = null; + } + } + + private void onProjectileSpawned(ProjectileSpawned event) + { + if (!isAtVorkath()) + { + return; + } + + final Projectile proj = event.getProjectile(); + final VorkathAttack vorkathAttack = VorkathAttack.getVorkathAttack(proj.getId()); + if (vorkathAttack != null) { - /*log.debug("[Projectile ({})] Game Tick: {}, Game Cycle: {}, Starting Cyle: {} Last Cycle: {}, Initial Projectile?: {}", - vorkathAttack, client.getTickCount(), client.getGameCycle(), event.getProjectile().getStartMovementCycle(), - lastProjectileCycle, event.getProjectile().getStartMovementCycle() == client.getGameCycle());*/ if (VorkathAttack.isBasicAttack(vorkathAttack.getProjectileID()) && vorkath.getAttacksLeft() > 0) { vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); @@ -155,47 +227,86 @@ public class VorkathPlugin extends Plugin else if (vorkathAttack == VorkathAttack.ACID) { vorkath.updatePhase(Vorkath.Phase.ACID); - // Sets the phase's progress indicator to done vorkath.setAttacksLeft(0); } else if (vorkathAttack == VorkathAttack.FIRE_BALL) { vorkath.updatePhase(Vorkath.Phase.FIRE_BALL); - // Decrement to account for this fire ball vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); } - else if (vorkathAttack == VorkathAttack.FREEZE_BREATH && vorkath.getLastAttack() != VorkathAttack.ZOMBIFIED_SPAWN) + else if (vorkathAttack == VorkathAttack.FREEZE_BREATH || vorkathAttack == VorkathAttack.ZOMBIFIED_SPAWN) { - // Filters out second invisible freeze attack that is immediately after the Zombified Spawn vorkath.updatePhase(Vorkath.Phase.SPAWN); - // Sets progress of the phase to half - vorkath.setAttacksLeft(vorkath.getAttacksLeft() - (vorkath.getAttacksLeft() / 2)); - } - else if (vorkathAttack == VorkathAttack.ZOMBIFIED_SPAWN || (vorkath.getLastAttack() == VorkathAttack.ZOMBIFIED_SPAWN)) - { - // Also consumes the second invisible freeze attack that is immediately after the Zombified Spawn - // Sets progress of the phase to done as there are no more attacks within this phase vorkath.setAttacksLeft(0); } else { - // Vorkath fired a basic attack AND there are no more attacks left, typically after phases are over vorkath.updatePhase(vorkath.getNextPhase()); - // Decrement to account for this basic attack vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); } log.debug("[Vorkath ({})] {}", vorkathAttack, vorkath); vorkath.setLastAttack(vorkathAttack); - lastProjectileCycle = event.getProjectile().getStartMovementCycle(); } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onProjectileMoved(ProjectileMoved event) { - if (isAtVorkath() && vorkath != null && event.getActor().equals(vorkath.getVorkath()) - && event.getActor().getAnimation() == VorkathAttack.SLASH_ATTACK.getVorkathAnimationID()) + if (!isAtVorkath()) + { + return; + } + + final Projectile proj = event.getProjectile(); + final LocalPoint loc = event.getPosition(); + + if (proj.getId() == ProjectileID.VORKATH_POISON_POOL_AOE) + { + addAcidSpot(WorldPoint.fromLocal(client, loc)); + } + } + + private void onGameObjectSpawned(GameObjectSpawned event) + { + if (!isAtVorkath()) + { + return; + } + + final GameObject obj = event.getGameObject(); + + if (obj.getId() == ObjectID.ACID_POOL || obj.getId() == ObjectID.ACID_POOL_32000) + { + addAcidSpot(obj.getWorldLocation()); + } + } + + private void onGameObjectDespawned(GameObjectDespawned event) + { + if (!isAtVorkath()) + { + return; + } + + final GameObject obj = event.getGameObject(); + + if (obj.getId() == ObjectID.ACID_POOL || obj.getId() == ObjectID.ACID_POOL_32000) + { + acidSpots.remove(obj.getWorldLocation()); + } + } + + private void onAnimationChanged(AnimationChanged event) + { + if (!isAtVorkath()) + { + return; + } + + final Actor actor = event.getActor(); + + if (isAtVorkath() && vorkath != null && actor.equals(vorkath.getVorkath()) + && actor.getAnimation() == VorkathAttack.SLASH_ATTACK.getVorkathAnimationID()) { if (vorkath.getAttacksLeft() > 0) { @@ -203,15 +314,83 @@ public class VorkathPlugin extends Plugin } else { - // No more attacks left, typically after phases are over vorkath.updatePhase(vorkath.getNextPhase()); - // Decrement to account for this basic attack vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); } log.debug("[Vorkath (SLASH_ATTACK)] {}", vorkath); } } + private void onGameTick(GameTick event) + { + if (!isAtVorkath()) + { + return; + } + + // Update the acid free path every tick to account for player movement + if (this.indicateAcidFreePath && !acidSpots.isEmpty()) + { + calculateAcidFreePath(); + } + + // Start the timer when the player walks into the WooxWalk zone + if (this.indicateWooxWalkPath && this.indicateWooxWalkTick && wooxWalkPath[0] != null && wooxWalkPath[1] != null) + { + final WorldPoint playerLoc = client.getLocalPlayer().getWorldLocation(); + + if (playerLoc.getX() == wooxWalkPath[0].getX() && playerLoc.getY() == wooxWalkPath[0].getY() + && playerLoc.getPlane() == wooxWalkPath[0].getPlane()) + { + if (wooxWalkTimer == -1) + { + wooxWalkTimer = System.currentTimeMillis() - 400; + } + } + else if (playerLoc.getX() == wooxWalkPath[1].getX() && playerLoc.getY() == wooxWalkPath[1].getY() + && playerLoc.getPlane() == wooxWalkPath[1].getPlane()) + { + if (wooxWalkTimer == -1) + { + wooxWalkTimer = System.currentTimeMillis() - 1000; + } + } + else if (wooxWalkTimer != -1) + { + wooxWalkTimer = -1; + } + } + } + + private void onClientTick(ClientTick event) + { + if (acidSpots.size() != lastAcidSpotsSize) + { + if (acidSpots.size() == 0) + { + overlayManager.remove(acidPathOverlay); + acidFreePath.clear(); + Arrays.fill(wooxWalkPath, null); + wooxWalkTimer = -1; + } + else + { + if (this.indicateAcidFreePath) + { + calculateAcidFreePath(); + } + if (this.indicateWooxWalkPath) + { + calculateWooxWalkPath(); + } + + overlayManager.add(acidPathOverlay); + } + + lastAcidSpotsSize = acidSpots.size(); + } + } + /** * @return true if the player is in the Vorkath region, false otherwise */ @@ -220,28 +399,209 @@ public class VorkathPlugin extends Plugin return ArrayUtils.contains(client.getMapRegions(), VORKATH_REGION); } - /** - * @param npcID - * @return true if the npc is Vorkath, false otherwise - */ - private boolean isVorkath(int npcID) + private void addAcidSpot(WorldPoint acidSpotLocation) { - // Could be done with a a simple name check instead... - return npcID == NpcID.VORKATH || - npcID == NpcID.VORKATH_8058 || - npcID == NpcID.VORKATH_8059 || - npcID == NpcID.VORKATH_8060 || - npcID == NpcID.VORKATH_8061; + if (!acidSpots.contains(acidSpotLocation)) + { + acidSpots.add(acidSpotLocation); + } } - /** - * @param npcID - * @return true if the npc is a Zombified Spawn, otherwise false - */ - private boolean isZombifiedSpawn(int npcID) + private void calculateAcidFreePath() { - // Could be done with a a simple name check instead... - return npcID == NpcID.ZOMBIFIED_SPAWN || - npcID == NpcID.ZOMBIFIED_SPAWN_8063; + acidFreePath.clear(); + + final int[][][] directions = { + { + {0, 1}, {0, -1} // Positive and negative Y + }, + { + {1, 0}, {-1, 0} // Positive and negative X + } + }; + + List bestPath = new ArrayList<>(); + double bestClicksRequired = 99; + + final WorldPoint playerLoc = client.getLocalPlayer().getWorldLocation(); + final WorldPoint vorkLoc = vorkath.getVorkath().getWorldLocation(); + final int maxX = vorkLoc.getX() + 14; + final int minX = vorkLoc.getX() - 8; + final int maxY = vorkLoc.getY() - 1; + final int minY = vorkLoc.getY() - 8; + + // Attempt to search an acid free path, beginning at a location + // adjacent to the player's location (including diagonals) + for (int x = -1; x < 2; x++) + { + for (int y = -1; y < 2; y++) + { + final WorldPoint baseLocation = new WorldPoint(playerLoc.getX() + x, + playerLoc.getY() + y, playerLoc.getPlane()); + + if (acidSpots.contains(baseLocation) || baseLocation.getY() < minY || baseLocation.getY() > maxY) + { + continue; + } + + // Search in X and Y direction + for (int d = 0; d < directions.length; d++) + { + // Calculate the clicks required to start walking on the path + double currentClicksRequired = Math.abs(x) + Math.abs(y); + if (currentClicksRequired < 2) + { + currentClicksRequired += Math.abs(y * directions[d][0][0]) + Math.abs(x * directions[d][0][1]); + } + if (d == 0) + { + // Prioritize a path in the X direction (sideways) + currentClicksRequired += 0.5; + } + + List currentPath = new ArrayList<>(); + currentPath.add(baseLocation); + + // Positive X (first iteration) or positive Y (second iteration) + for (int i = 1; i < 25; i++) + { + final WorldPoint testingLocation = new WorldPoint(baseLocation.getX() + i * directions[d][0][0], + baseLocation.getY() + i * directions[d][0][1], baseLocation.getPlane()); + + if (acidSpots.contains(testingLocation) || testingLocation.getY() < minY || testingLocation.getY() > maxY + || testingLocation.getX() < minX || testingLocation.getX() > maxX) + { + break; + } + + currentPath.add(testingLocation); + } + + // Negative X (first iteration) or positive Y (second iteration) + for (int i = 1; i < 25; i++) + { + final WorldPoint testingLocation = new WorldPoint(baseLocation.getX() + i * directions[d][1][0], + baseLocation.getY() + i * directions[d][1][1], baseLocation.getPlane()); + + if (acidSpots.contains(testingLocation) || testingLocation.getY() < minY || testingLocation.getY() > maxY + || testingLocation.getX() < minX || testingLocation.getX() > maxX) + { + break; + } + + currentPath.add(testingLocation); + } + + if (currentPath.size() >= this.acidFreePathLength && currentClicksRequired < bestClicksRequired + || (currentClicksRequired == bestClicksRequired && currentPath.size() > bestPath.size())) + { + bestPath = currentPath; + bestClicksRequired = currentClicksRequired; + } + } + } + } + + if (bestClicksRequired != 99) + { + acidFreePath = bestPath; + } } -} + + private void calculateWooxWalkPath() + { + wooxWalkTimer = -1; + + updateWooxWalkBar(); + + final WorldPoint playerLoc = client.getLocalPlayer().getWorldLocation(); + final WorldPoint vorkLoc = vorkath.getVorkath().getWorldLocation(); + final int maxX = vorkLoc.getX() + 14; + final int minX = vorkLoc.getX() - 8; + final int baseX = playerLoc.getX(); + final int baseY = vorkLoc.getY() - 5; + final int middleX = vorkLoc.getX() + 3; + + // Loop through the arena tiles in the x-direction and + // alternate between positive and negative x direction + for (int i = 0; i < 50; i++) + { + // Make sure we always choose the spot closest to + // the middle of the arena + int directionRemainder = 0; + if (playerLoc.getX() < middleX) + { + directionRemainder = 1; + } + + int deviation = (int) Math.floor(i / 2.0); + if (i % 2 == directionRemainder) + { + deviation = -deviation; + } + + final WorldPoint attackLocation = new WorldPoint(baseX + deviation, baseY, playerLoc.getPlane()); + final WorldPoint outOfRangeLocation = new WorldPoint(baseX + deviation, baseY - 1, playerLoc.getPlane()); + + if (acidSpots.contains(attackLocation) || acidSpots.contains(outOfRangeLocation) + || attackLocation.getX() < minX || attackLocation.getX() > maxX) + { + continue; + } + + wooxWalkPath[0] = attackLocation; + wooxWalkPath[1] = outOfRangeLocation; + + break; + } + } + + private void updateWooxWalkBar() + { + // Update the WooxWalk tick indicator's dimensions + // based on the canvas dimensions + final Widget exp = client.getWidget(WidgetInfo.EXPERIENCE_TRACKER); + + if (exp == null) + { + return; + } + + final Rectangle screen = exp.getBounds(); + + int width = (int) Math.floor(screen.getWidth() / 2.0); + if (width % 2 == 1) + { + width++; + } + int height = (int) Math.floor(width / 20.0); + if (height % 2 == 1) + { + height++; + } + final int x = (int) Math.floor(screen.getX() + width / 2.0); + final int y = (int) Math.floor(screen.getY() + screen.getHeight() - 2 * height); + wooxWalkBar = new Rectangle(x, y, width, height); + } + + private void updateConfig() + { + this.indicateAcidPools = config.indicateAcidPools(); + this.indicateAcidFreePath = config.indicateAcidFreePath(); + this.indicateWooxWalkPath = config.indicateWooxWalkPath(); + this.indicateWooxWalkTick = config.indicateWooxWalkTick(); + this.acidFreePathLength = config.acidFreePathLength(); + } + + private void reset() + { + overlayManager.remove(overlay); + overlayManager.remove(acidPathOverlay); + vorkath = null; + acidSpots.clear(); + acidFreePath.clear(); + Arrays.fill(wooxWalkPath, null); + wooxWalkTimer = -1; + zombifiedSpawn = null; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java index e3ca95d45a..ca037b8f1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java @@ -48,7 +48,7 @@ import net.runelite.api.Player; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; @@ -80,6 +80,9 @@ public class WarIndicatorPlugin extends Plugin @Inject private Client client; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean highLightCallers; @Getter(AccessLevel.PACKAGE) @@ -111,6 +114,7 @@ public class WarIndicatorPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(warIndicatorOverlay); overlayManager.add(warIndicatorMiniMapOverlay); @@ -119,12 +123,18 @@ public class WarIndicatorPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.remove(warIndicatorOverlay); overlayManager.remove(warIndicatorMiniMapOverlay); } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded onMenuEntryAdded) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + + private void onMenuEntryAdded(MenuEntryAdded onMenuEntryAdded) { int type = onMenuEntryAdded.getType(); @@ -195,8 +205,7 @@ public class WarIndicatorPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("warIndicators")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java index 31878c18ab..e892cd6799 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/whalewatchers/WhaleWatchersPlugin.java @@ -37,7 +37,7 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.kit.KitType; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -76,6 +76,8 @@ public class WhaleWatchersPlugin extends Plugin private WhaleWatchersGloryOverlay whaleWatchersGloryOverlay; @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; private int tickCountdown = 0; @Getter(AccessLevel.PACKAGE) private boolean displaySmiteOverlay; @@ -95,8 +97,7 @@ public class WhaleWatchersPlugin extends Plugin return configManager.getConfig(WhaleWatchersConfig.class); } - @Subscribe - public void onOverlayMenuClicked(OverlayMenuClicked event) + private void onOverlayMenuClicked(OverlayMenuClicked event) { if (event.getOverlay().equals(overlay) && event.getEntry().getOption().equals("Reset")) { @@ -108,6 +109,7 @@ public class WhaleWatchersPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(whaleWatchersProtOverlay); @@ -118,6 +120,7 @@ public class WhaleWatchersPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.remove(overlay); overlayManager.remove(whaleWatchersProtOverlay); overlayManager.remove(whaleWatchersSmiteableOverlay); @@ -125,8 +128,18 @@ public class WhaleWatchersPlugin extends Plugin resetDamageCounter(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(OverlayMenuClicked.class, this, this::onOverlayMenuClicked); + eventBus.subscribe(HitsplatApplied.class, this, this::onHitsplatApplied); + eventBus.subscribe(ItemContainerChanged.class, this, this::onItemContainerChanged); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals(CONFIG_GROUP_NAME)) { @@ -149,9 +162,7 @@ public class WhaleWatchersPlugin extends Plugin } } - - @Subscribe - public void onHitsplatApplied(HitsplatApplied event) + private void onHitsplatApplied(HitsplatApplied event) { if (this.showDamageCounter) { @@ -175,9 +186,7 @@ public class WhaleWatchersPlugin extends Plugin } } - - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { if (this.gloryWarning && event.getItemContainer() == client.getItemContainer(InventoryID.EQUIPMENT)) { @@ -191,9 +200,7 @@ public class WhaleWatchersPlugin extends Plugin } } - - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (this.showDamageCounter && event.getMenuAction().equals(MenuAction.SPELL_CAST_ON_PLAYER)) { @@ -201,8 +208,7 @@ public class WhaleWatchersPlugin extends Plugin } } - @Subscribe - public void onVarbitChanged(VarbitChanged event) + private void onVarbitChanged(VarbitChanged event) { if (this.showDamageCounter && client.getVar(VarPlayer.ATTACKING_PLAYER) == -1 && inCombat) { @@ -242,8 +248,7 @@ public class WhaleWatchersPlugin extends Plugin } } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (this.showDamageCounter && tickCountdown > 0 && tickCountdown < 11) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java index b07ea0bad0..e0c704aa40 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiPlugin.java @@ -50,7 +50,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.ItemManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.game.chatbox.ChatboxPanelManager; @@ -105,6 +105,9 @@ public class WikiPlugin extends Plugin @Inject private Provider wikiSearchChatboxTextInputProvider; + @Inject + private EventBus eventBus; + private Widget icon; private boolean wikiSelected = false; @@ -112,6 +115,8 @@ public class WikiPlugin extends Plugin @Override public void startUp() { + addSubscriptions(); + spriteManager.addSpriteOverrides(WikiSprite.values()); clientThread.invokeLater(this::addWidgets); } @@ -119,6 +124,8 @@ public class WikiPlugin extends Plugin @Override public void shutDown() { + eventBus.unregister(this); + spriteManager.removeSpriteOverrides(WikiSprite.values()); clientThread.invokeLater(() -> { @@ -139,7 +146,13 @@ public class WikiPlugin extends Plugin }); } - @Subscribe + private void addSubscriptions() + { + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + } + private void onWidgetLoaded(WidgetLoaded l) { if (l.getGroupId() == WidgetID.MINIMAP_GROUP_ID) @@ -195,7 +208,6 @@ public class WikiPlugin extends Plugin } } - @Subscribe private void onMenuOptionClicked(MenuOptionClicked ev) { if (wikiSelected) @@ -322,8 +334,7 @@ public class WikiPlugin extends Plugin .build(); } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { int widgetIndex = event.getActionParam0(); int widgetID = event.getActionParam1(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java index 07e7442638..ac2cc07ca9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wildernesslocations/WildernessLocationsPlugin.java @@ -33,7 +33,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.Keybind; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -78,6 +78,9 @@ public class WildernessLocationsPlugin extends Plugin @Inject private KeyManager keyManager; + @Inject + private EventBus eventBus; + private String oldChat = ""; private int currentCooldown = 0; private WorldPoint worldPoint = null; @@ -105,6 +108,8 @@ public class WildernessLocationsPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + this.drawOverlay = wildyConfig.drawOverlay(); this.keybind = wildyConfig.keybind(); @@ -112,8 +117,14 @@ public class WildernessLocationsPlugin extends Plugin keyManager.registerKeyListener(hotkeyListener); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(VarClientStrChanged.class, this, this::onVarClientStrChanged); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("wildernesslocations")) { @@ -127,12 +138,13 @@ public class WildernessLocationsPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); keyManager.unregisterKeyListener(hotkeyListener); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (currentCooldown != 0) { @@ -210,8 +222,7 @@ public class WildernessLocationsPlugin extends Plugin return hashMap; } - @Subscribe - public void onVarClientStrChanged(VarClientStrChanged varClient) + private void onVarClientStrChanged(VarClientStrChanged varClient) { String newChat = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); if (varClient.getIndex() == VarClientStr.CHATBOX_TYPED_TEXT.getIndex() && !newChat.equals(oldChat)) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java index 910b9ae241..b98fe9fdc6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java @@ -37,6 +37,7 @@ import lombok.extern.slf4j.Slf4j; import static net.runelite.api.AnimationID.*; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; +import static net.runelite.api.GameState.LOADING; import net.runelite.api.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemContainer; @@ -49,12 +50,13 @@ import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.VarbitChanged; import net.runelite.client.Notifier; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.wintertodt.config.WintertodtNotifyMode; @@ -93,6 +95,9 @@ public class WintertodtPlugin extends Plugin @Inject private ChatMessageManager chatMessageManager; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private WintertodtActivity currentActivity = WintertodtActivity.IDLE; @@ -111,6 +116,8 @@ public class WintertodtPlugin extends Plugin private WintertodtNotifyMode notifyCondition; private Color damageNotificationColor; + private boolean subscribed; + @Provides WintertodtConfig getConfig(ConfigManager configManager) { @@ -123,19 +130,47 @@ public class WintertodtPlugin extends Plugin this.notifyCondition = config.notifyCondition(); this.damageNotificationColor = config.damageNotificationColor(); + addSubscriptions(); + reset(); overlayManager.add(overlay); + + handleWintertodtRegion(); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + eventBus.unregister("inside-wintertodt"); + overlayManager.remove(overlay); reset(); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + } + + private void wintertodtSubscriptions(boolean subscribe) + { + if (subscribe) + { + eventBus.subscribe(GameTick.class, "inside-wintertodt", this::onGameTick); + eventBus.subscribe(ChatMessage.class, "inside-wintertodt", this::onChatMessage); + eventBus.subscribe(AnimationChanged.class, "inside-wintertodt", this::onAnimationChanged); + eventBus.subscribe(ItemContainerChanged.class, "inside-wintertodt", this::onItemContainerChanged); + } + else + { + eventBus.unregister("inside-wintertodt"); + } + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("wintertodt")) { @@ -164,10 +199,24 @@ public class WintertodtPlugin extends Plugin return false; } - @Subscribe - public void onGameTick(GameTick gameTick) + private void handleWintertodtRegion() { - if (!isInWintertodtRegion()) + if (isInWintertodtRegion()) + { + if (!isInWintertodt) + { + reset(); + log.debug("Entered Wintertodt!"); + } + isInWintertodt = true; + + if (!subscribed) + { + wintertodtSubscriptions(true); + subscribed = true; + } + } + else { if (isInWintertodt) { @@ -176,21 +225,29 @@ public class WintertodtPlugin extends Plugin } isInWintertodt = false; - return; - } - if (!isInWintertodt) + if (subscribed) + { + wintertodtSubscriptions(false); + subscribed = false; + } + } + } + + private void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == LOADING) { - reset(); - log.debug("Entered Wintertodt!"); + handleWintertodtRegion(); } - isInWintertodt = true; + } + private void onGameTick(GameTick gameTick) + { checkActionTimeout(); } - @Subscribe - public void onVarbitChanged(VarbitChanged varbitChanged) + void onVarbitChanged(VarbitChanged varbitChanged) { int timerValue = client.getVar(Varbits.WINTERTODT_TIMER); if (timerValue != previousTimerValue) @@ -236,14 +293,8 @@ public class WintertodtPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage chatMessage) + private void onChatMessage(ChatMessage chatMessage) { - if (!isInWintertodt) - { - return; - } - ChatMessageType chatMessageType = chatMessage.getType(); if (chatMessageType != ChatMessageType.GAMEMESSAGE && chatMessageType != ChatMessageType.SPAM) @@ -380,14 +431,8 @@ public class WintertodtPlugin extends Plugin notifier.notify(notification); } - @Subscribe - public void onAnimationChanged(final AnimationChanged event) + private void onAnimationChanged(final AnimationChanged event) { - if (!isInWintertodt) - { - return; - } - final Player local = client.getLocalPlayer(); if (event.getActor() != local) @@ -429,12 +474,11 @@ public class WintertodtPlugin extends Plugin } } - @Subscribe - public void onItemContainerChanged(ItemContainerChanged event) + private void onItemContainerChanged(ItemContainerChanged event) { final ItemContainer container = event.getItemContainer(); - if (!isInWintertodt || container != client.getItemContainer(InventoryID.INVENTORY)) + if (container != client.getItemContainer(InventoryID.INVENTORY)) { return; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java index 996a13cb30..7bc066283c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java @@ -48,7 +48,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; @@ -82,6 +82,9 @@ public class WoodcuttingPlugin extends Plugin @Inject private WoodcuttingConfig config; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private WoodcuttingSession session; @@ -108,6 +111,7 @@ public class WoodcuttingPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); overlayManager.add(overlay); overlayManager.add(treesOverlay); @@ -116,6 +120,8 @@ public class WoodcuttingPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); overlayManager.remove(treesOverlay); treeObjects.clear(); @@ -123,8 +129,19 @@ public class WoodcuttingPlugin extends Plugin axe = null; } - @Subscribe - public void onGameTick(GameTick gameTick) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned); + eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned); + eventBus.subscribe(GameObjectChanged.class, this, this::onGameObjectChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + } + + private void onGameTick(GameTick gameTick) { if (session == null || session.getLastLogCut() == null) { @@ -141,8 +158,7 @@ public class WoodcuttingPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() == ChatMessageType.SPAM || event.getType() == ChatMessageType.GAMEMESSAGE) { @@ -163,8 +179,7 @@ public class WoodcuttingPlugin extends Plugin } } - @Subscribe - public void onGameObjectSpawned(final GameObjectSpawned event) + private void onGameObjectSpawned(final GameObjectSpawned event) { GameObject gameObject = event.getGameObject(); Tree tree = Tree.findTree(gameObject.getId()); @@ -175,20 +190,17 @@ public class WoodcuttingPlugin extends Plugin } } - @Subscribe - public void onGameObjectDespawned(final GameObjectDespawned event) + private void onGameObjectDespawned(final GameObjectDespawned event) { treeObjects.remove(event.getGameObject()); } - @Subscribe - public void onGameObjectChanged(final GameObjectChanged event) + private void onGameObjectChanged(final GameObjectChanged event) { treeObjects.remove(event.getGameObject()); } - @Subscribe - public void onGameStateChanged(final GameStateChanged event) + private void onGameStateChanged(final GameStateChanged event) { if (event.getGameState() != GameState.LOGGED_IN) { @@ -196,8 +208,7 @@ public class WoodcuttingPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(final AnimationChanged event) + private void onAnimationChanged(final AnimationChanged event) { Player local = client.getLocalPlayer(); @@ -214,8 +225,7 @@ public class WoodcuttingPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("woodcutting")) { 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 1136fffc31..7613e456ce 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 @@ -72,7 +72,7 @@ import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.Keybind; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -130,6 +130,9 @@ public class WorldHopperPlugin extends Plugin @Inject private WorldHopperConfig config; + @Inject + private EventBus eventBus; + private ScheduledExecutorService hopperExecutorService; private NavigationButton navButton; @@ -183,6 +186,7 @@ public class WorldHopperPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); firstRun = true; @@ -219,6 +223,8 @@ public class WorldHopperPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + pingFuture.cancel(true); pingFuture = null; @@ -236,8 +242,19 @@ public class WorldHopperPlugin extends Plugin hopperExecutorService = null; } - @Subscribe - public void onConfigChanged(final ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged); + eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); + eventBus.subscribe(PlayerMenuOptionClicked.class, this, this::onPlayerMenuOptionClicked); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(WorldListLoad.class, this, this::onWorldListLoad); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(ChatMessage.class, this, this::onChatMessage); + } + + private void onConfigChanged(final ConfigChanged event) { if (event.getGroup().equals(WorldHopperConfig.GROUP)) { @@ -320,8 +337,7 @@ public class WorldHopperPlugin extends Plugin panel.updateFavoriteMenu(world.getId(), false); } - @Subscribe - public void onVarbitChanged(VarbitChanged varbitChanged) + private void onVarbitChanged(VarbitChanged varbitChanged) { int old1 = favoriteWorld1; int old2 = favoriteWorld2; @@ -335,8 +351,7 @@ public class WorldHopperPlugin extends Plugin } } - @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) + private void onMenuEntryAdded(MenuEntryAdded event) { if (!config.menuOption()) { @@ -405,8 +420,7 @@ public class WorldHopperPlugin extends Plugin client.setMenuEntries(newMenu); } - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + private void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { if (!event.getMenuOption().equals(HOP_TO)) { @@ -421,8 +435,7 @@ public class WorldHopperPlugin extends Plugin } } - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + private void onGameStateChanged(GameStateChanged gameStateChanged) { // If the player has disabled the side bar plugin panel, do not update the UI if (this.showSidebar && gameStateChanged.getGameState() == GameState.LOGGED_IN) @@ -436,8 +449,7 @@ public class WorldHopperPlugin extends Plugin } } - @Subscribe - public void onWorldListLoad(WorldListLoad worldListLoad) + private void onWorldListLoad(WorldListLoad worldListLoad) { if (!this.showSidebar) { @@ -672,8 +684,7 @@ public class WorldHopperPlugin extends Plugin displaySwitcherAttempts = 0; } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { if (quickHopTargetWorld == null) { @@ -711,8 +722,7 @@ public class WorldHopperPlugin extends Plugin } } - @Subscribe - public void onChatMessage(ChatMessage event) + private void onChatMessage(ChatMessage event) { if (event.getType() != ChatMessageType.GAMEMESSAGE) { 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 67552394c9..f29ebabefb 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 @@ -39,14 +39,12 @@ import javax.swing.JPanel; import javax.swing.SwingUtilities; import lombok.AccessLevel; import lombok.Setter; -import lombok.extern.slf4j.Slf4j; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.PluginPanel; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldType; -@Slf4j class WorldSwitcherPanel extends PluginPanel { private static final Color ODD_ROW = new Color(44, 44, 44); @@ -413,4 +411,4 @@ class WorldSwitcherPanel extends PluginPanel ACTIVITY, PING } -} \ No newline at end of file +} 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 7f8a0ec744..9c4f30cc59 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 @@ -41,7 +41,7 @@ import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.WidgetID; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.AgilityShortcut; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -124,6 +124,9 @@ public class WorldMapPlugin extends Plugin @Inject private WorldMapPointManager worldMapPointManager; + @Inject + private EventBus eventBus; + private int agilityLevel = 0; private int woodcuttingLevel = 0; @@ -155,6 +158,8 @@ public class WorldMapPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + agilityLevel = client.getRealSkillLevel(Skill.AGILITY); woodcuttingLevel = client.getRealSkillLevel(Skill.WOODCUTTING); updateShownIcons(); @@ -163,6 +168,8 @@ public class WorldMapPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + worldMapPointManager.removeIf(FairyRingPoint.class::isInstance); worldMapPointManager.removeIf(AgilityShortcutPoint.class::isInstance); worldMapPointManager.removeIf(QuestStartPoint.class::isInstance); @@ -175,8 +182,14 @@ public class WorldMapPlugin extends Plugin woodcuttingLevel = 0; } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); + } + + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals(CONFIG_KEY)) { @@ -187,8 +200,7 @@ public class WorldMapPlugin extends Plugin updateShownIcons(); } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void onExperienceChanged(ExperienceChanged event) { if (event.getSkill() == Skill.AGILITY) { @@ -211,8 +223,7 @@ public class WorldMapPlugin extends Plugin } } - @Subscribe - public void onWidgetLoaded(WidgetLoaded widgetLoaded) + private void onWidgetLoaded(WidgetLoaded widgetLoaded) { if (widgetLoaded.getGroupId() == WidgetID.WORLD_MAP_GROUP_ID) { 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 591543e137..e9b8345dfd 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 @@ -42,7 +42,7 @@ import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; @@ -79,6 +79,9 @@ public class XpGlobesPlugin extends Plugin @Inject private XpGlobesOverlay overlay; + @Inject + private EventBus eventBus; + @Getter(AccessLevel.PACKAGE) private boolean enableTooltips; private boolean hideMaxed; @@ -108,17 +111,27 @@ public class XpGlobesPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); + overlayManager.add(overlay); } @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(overlay); } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + private void onExperienceChanged(ExperienceChanged event) { Skill skill = event.getSkill(); int currentXp = client.getSkillExperience(skill); @@ -197,8 +210,7 @@ public class XpGlobesPlugin extends Plugin globeCache = new XpGlobe[Skill.values().length - 1]; } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void onGameStateChanged(GameStateChanged event) { switch (event.getGameState()) { @@ -209,10 +221,7 @@ public class XpGlobesPlugin extends Plugin } } - - - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("xpglobes")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java index f456958292..8a05ccc932 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java @@ -37,7 +37,6 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.Actor; import net.runelite.api.Client; import net.runelite.api.Skill; @@ -49,7 +48,6 @@ import net.runelite.client.ui.components.PluginErrorPanel; import net.runelite.client.util.LinkBrowser; import okhttp3.HttpUrl; -@Slf4j class XpPanel extends PluginPanel { private final Map infoBoxes = new HashMap<>(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index f592cdc166..f926248040 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -53,7 +53,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.NPCManager; import net.runelite.client.game.SkillIconManager; import net.runelite.client.plugins.Plugin; @@ -105,6 +105,9 @@ public class XpTrackerPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private EventBus eventBus; + private NavigationButton navButton; private XpPanel xpPanel; private XpWorldType lastWorldType; @@ -143,6 +146,7 @@ public class XpTrackerPlugin extends Plugin protected void startUp() throws Exception { updateConfig(); + addSubscriptions(); xpPanel = new XpPanel(this, client, skillIconManager); @@ -161,13 +165,22 @@ public class XpTrackerPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); overlayManager.removeIf(e -> e instanceof XpInfoBoxOverlay); xpState.reset(); clientToolbar.removeNavigation(navButton); } - @Subscribe - public void onGameStateChanged(GameStateChanged event) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + eventBus.subscribe(GameTick.class, this, this::onGameTick); + } + + private void onGameStateChanged(GameStateChanged event) { GameState state = event.getGameState(); if (state == GameState.LOGGED_IN) @@ -318,8 +331,7 @@ public class XpTrackerPlugin extends Plugin } } - @Subscribe - public void onExperienceChanged(ExperienceChanged event) + private void onExperienceChanged(ExperienceChanged event) { final Skill skill = event.getSkill(); final int currentXp = client.getSkillExperience(skill); @@ -361,8 +373,7 @@ public class XpTrackerPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { final NPC npc = event.getNpc(); @@ -381,8 +392,7 @@ public class XpTrackerPlugin extends Plugin xpPanel.updateTotal(xpState.getTotalSnapshot()); } - @Subscribe - public void onGameTick(GameTick event) + private void onGameTick(GameTick event) { rebuildSkills(); if (fetchXp) @@ -579,8 +589,7 @@ public class XpTrackerPlugin extends Plugin } } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals("xpTracker")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xtea/XteaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xtea/XteaPlugin.java index e8e31dd0f2..a9a95ab724 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xtea/XteaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xtea/XteaPlugin.java @@ -31,7 +31,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.http.api.xtea.XteaClient; @@ -52,8 +52,22 @@ public class XteaPlugin extends Plugin @Inject private Client client; - @Subscribe - public void onGameStateChanged(GameStateChanged gameStateChanged) + @Inject + private EventBus eventBus; + + @Override + protected void startUp() throws Exception + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + } + + @Override + protected void shutDown() throws Exception + { + eventBus.unregister(this); + } + + private void onGameStateChanged(GameStateChanged gameStateChanged) { if (gameStateChanged.getGameState() != GameState.LOGGED_IN) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ControlFunction.java b/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ControlFunction.java index 9b526eb543..a5b2522b1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ControlFunction.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ControlFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Jacob M + * Copyright (c) 2019, Jacob M * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,7 +36,7 @@ public enum ControlFunction CONTROL_TO_ZOOM("Hold to zoom"), CONTROL_TO_RESET("Reset zoom"); - private String name; + private final String name; @Override public String toString() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomConfig.java index d3fb50007b..91821ba91b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomConfig.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2018 Abex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ package net.runelite.client.plugins.zoom; import net.runelite.client.config.Config; @@ -48,12 +72,11 @@ public interface ZoomConfig extends Config return false; } - @ConfigItem( keyName = "controlFunction", name = "Control Function", description = "Configures the zoom function when control is pressed", - position = 5 + position = 4 ) default ControlFunction controlFunction() { @@ -64,18 +87,22 @@ public interface ZoomConfig extends Config keyName = "ctrlZoomValue", name = "Reset zoom position", description = "Position of zoom when it is reset", - position = 6 + position = 5 + ) + @Range( + min = OUTER_LIMIT_MIN, + max = OUTER_LIMIT_MAX ) default int ctrlZoomValue() { - return 600; + return 512; } @ConfigItem( keyName = "zoomIncrement", name = "Zoom Speed", description = "Speed of zoom", - position = 7 + position = 6 ) default int zoomIncrement() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomPlugin.java index 634c9fe06a..21af699278 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomPlugin.java @@ -35,7 +35,7 @@ import net.runelite.api.events.FocusChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; @@ -52,10 +52,11 @@ public class ZoomPlugin extends Plugin implements KeyListener { /** * The largest (most zoomed in) value that can be used without the client crashing. - *

+ * * Larger values trigger an overflow in the engine's fov to scale code. */ private static final int INNER_ZOOM_LIMIT = 1004; + private static final int DEFAULT_ZOOM_INCREMENT = 25; private boolean controlDown; @@ -71,14 +72,16 @@ public class ZoomPlugin extends Plugin implements KeyListener @Inject private KeyManager keyManager; + @Inject + private EventBus eventBus; + @Provides ZoomConfig getConfig(ConfigManager configManager) { return configManager.getConfig(ZoomConfig.class); } - @Subscribe - public void onScriptCallbackEvent(ScriptCallbackEvent event) + private void onScriptCallbackEvent(ScriptCallbackEvent event) { if (client.getIndexScripts().isOverlayOutdated()) { @@ -90,7 +93,7 @@ public class ZoomPlugin extends Plugin implements KeyListener int[] intStack = client.getIntStack(); int intStackSize = client.getIntStackSize(); - if ("scrollWheelZoom".equals(event.getEventName()) && zoomConfig.controlFunction() == ControlFunction.CONTROL_TO_ZOOM && !controlDown) + if (!controlDown && "scrollWheelZoom".equals(event.getEventName()) && zoomConfig.controlFunction() == ControlFunction.CONTROL_TO_ZOOM) { intStack[intStackSize - 1] = 1; } @@ -109,9 +112,10 @@ public class ZoomPlugin extends Plugin implements KeyListener return; } - if ("scrollWheelZoomIncrement".equals(event.getEventName()) && zoomConfig.zoomIncrement() != 25) + if ("scrollWheelZoomIncrement".equals(event.getEventName()) && zoomConfig.zoomIncrement() != DEFAULT_ZOOM_INCREMENT) { intStack[intStackSize - 1] = zoomConfig.zoomIncrement(); + return; } if (zoomConfig.innerLimit()) @@ -140,8 +144,7 @@ public class ZoomPlugin extends Plugin implements KeyListener } } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void onFocusChanged(FocusChanged event) { if (!event.isFocused()) { @@ -152,6 +155,8 @@ public class ZoomPlugin extends Plugin implements KeyListener @Override protected void startUp() { + addSubscriptions(); + client.setCameraPitchRelaxerEnabled(zoomConfig.relaxCameraPitch()); keyManager.registerKeyListener(this); } @@ -159,13 +164,21 @@ public class ZoomPlugin extends Plugin implements KeyListener @Override protected void shutDown() { + eventBus.unregister(this); + client.setCameraPitchRelaxerEnabled(false); keyManager.unregisterKeyListener(this); controlDown = false; } - @Subscribe - public void onConfigChanged(ConfigChanged ev) + private void addSubscriptions() + { + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent); + eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); + } + + private void onConfigChanged(ConfigChanged ev) { client.setCameraPitchRelaxerEnabled(zoomConfig.relaxCameraPitch()); } @@ -190,6 +203,7 @@ public class ZoomPlugin extends Plugin implements KeyListener if (e.getKeyCode() == KeyEvent.VK_CONTROL) { controlDown = false; + if (zoomConfig.controlFunction() == ControlFunction.CONTROL_TO_RESET) { final int zoomValue = MiscUtils.clamp(zoomConfig.ctrlZoomValue(), zoomConfig.OUTER_LIMIT_MIN, INNER_ZOOM_LIMIT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java index 82deb0d766..18ee33b51f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/zulrah/ZulrahPlugin.java @@ -44,7 +44,7 @@ import net.runelite.api.events.GameTick; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.game.Sound; import net.runelite.client.game.SoundManager; import net.runelite.client.plugins.Plugin; @@ -98,6 +98,8 @@ public class ZulrahPlugin extends Plugin private ZulrahPrayerOverlay zulrahPrayerOverlay; @Inject private ZulrahOverlay zulrahOverlay; + @Inject + private EventBus eventBus; private ZulrahInstance instance; @Provides @@ -109,6 +111,8 @@ public class ZulrahPlugin extends Plugin @Override protected void startUp() throws Exception { + addSubscriptions(); + overlayManager.add(currentPhaseOverlay); overlayManager.add(nextPhaseOverlay); overlayManager.add(zulrahPrayerOverlay); @@ -118,6 +122,8 @@ public class ZulrahPlugin extends Plugin @Override protected void shutDown() throws Exception { + eventBus.unregister(this); + overlayManager.remove(currentPhaseOverlay); overlayManager.remove(nextPhaseOverlay); overlayManager.remove(zulrahPrayerOverlay); @@ -126,8 +132,15 @@ public class ZulrahPlugin extends Plugin instance = null; } - @Subscribe - public void onGameTick(GameTick event) + private void addSubscriptions() + { + eventBus.subscribe(GameTick.class, this, this::onGameTick); + eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); + eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); + eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); + } + + private void onGameTick(GameTick event) { if (client.getGameState() != GameState.LOGGED_IN) { @@ -196,8 +209,7 @@ public class ZulrahPlugin extends Plugin } } - @Subscribe - public void onAnimationChanged(AnimationChanged event) + private void onAnimationChanged(AnimationChanged event) { if (instance == null) { @@ -231,8 +243,7 @@ public class ZulrahPlugin extends Plugin } } - @Subscribe - public void onNpcSpawned(NpcSpawned event) + private void onNpcSpawned(NpcSpawned event) { NPC npc = event.getNpc(); if (npc != null && npc.getName() != null && @@ -242,8 +253,7 @@ public class ZulrahPlugin extends Plugin } } - @Subscribe - public void onNpcDespawned(NpcDespawned event) + private void onNpcDespawned(NpcDespawned event) { NPC npc = event.getNpc(); if (npc != null && npc.getName() != null && diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientToolbar.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientToolbar.java index 20bfe8897b..e49ef782ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientToolbar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientToolbar.java @@ -61,7 +61,7 @@ public class ClientToolbar if (buttons.add(button)) { - eventBus.post(new NavigationButtonAdded(button)); + eventBus.post(NavigationButtonAdded.class, new NavigationButtonAdded(button)); } } @@ -74,7 +74,7 @@ public class ClientToolbar { if (buttons.remove(button)) { - eventBus.post(new NavigationButtonRemoved(button)); + eventBus.post(NavigationButtonRemoved.class, new NavigationButtonRemoved(button)); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 8b3fc96130..7af0ad5675 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -84,7 +84,7 @@ import net.runelite.client.config.ExpandResizeType; import net.runelite.client.config.Keybind; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.WarningOnExit; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.events.NavigationButtonAdded; import net.runelite.client.events.NavigationButtonRemoved; import net.runelite.client.input.KeyManager; @@ -158,7 +158,8 @@ public class ClientUI MouseManager mouseManager, @Nullable Applet client, ConfigManager configManager, - Provider clientThreadProvider) + Provider clientThreadProvider, + EventBus eventbus) { this.properties = properties; this.config = config; @@ -167,10 +168,14 @@ public class ClientUI this.client = client; this.configManager = configManager; this.clientThreadProvider = clientThreadProvider; + + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(NavigationButtonAdded.class, this, this::onNavigationButtonAdded); + eventbus.subscribe(NavigationButtonRemoved.class, this, this::onNavigationButtonRemoved); + eventbus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (!event.getGroup().equals(CONFIG_GROUP) && !(event.getGroup().equals(PLUS_CONFIG_GROUP) @@ -185,8 +190,7 @@ public class ClientUI SwingUtilities.invokeLater(() -> updateFrameConfig(event.getKey().equals("lockWindowSize"))); } - @Subscribe - public void onNavigationButtonAdded(final NavigationButtonAdded event) + private void onNavigationButtonAdded(final NavigationButtonAdded event) { SwingUtilities.invokeLater(() -> { @@ -252,8 +256,7 @@ public class ClientUI }); } - @Subscribe - public void onNavigationButtonRemoved(final NavigationButtonRemoved event) + private void onNavigationButtonRemoved(final NavigationButtonRemoved event) { SwingUtilities.invokeLater(() -> { @@ -270,8 +273,7 @@ public class ClientUI }); } - @Subscribe - public void onGameStateChanged(final GameStateChanged event) + private void onGameStateChanged(final GameStateChanged event) { if (event.getGameState() != GameState.LOGGED_IN || !(client instanceof Client) || !config.usernameInTitle()) { @@ -871,7 +873,15 @@ public class ClientUI } frame.setExpandResizeType(config.automaticResizeType()); - frame.setContainedInScreen(config.containInScreen() && withTitleBar); + + ContainableFrame.Mode containMode = config.containInScreen(); + if (containMode == ContainableFrame.Mode.ALWAYS && !withTitleBar) + { + // When native window decorations are enabled we don't have a way to receive window move events + // so we can't contain to screen always. + containMode = ContainableFrame.Mode.RESIZING; + } + frame.setContainedInScreen(containMode); if (!config.rememberScreenBounds()) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java b/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java index 1a528f75aa..7d03d05ef3 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java @@ -32,11 +32,18 @@ import net.runelite.client.config.ExpandResizeType; public class ContainableFrame extends JFrame { + public enum Mode + { + ALWAYS, + RESIZING, + NEVER; + } + private static final int SCREEN_EDGE_CLOSE_DISTANCE = 40; @Setter private ExpandResizeType expandResizeType; - private boolean containedInScreen; + private Mode containedInScreen; private boolean expandedClientOppositeDirection; ContainableFrame() @@ -50,11 +57,11 @@ public class ContainableFrame extends JFrame }); } - public void setContainedInScreen(boolean value) + public void setContainedInScreen(Mode value) { this.containedInScreen = value; - if (value) + if (this.containedInScreen == Mode.ALWAYS) { // Reposition the frame if it is intersecting with the bounds this.setLocation(this.getX(), this.getY()); @@ -65,7 +72,7 @@ public class ContainableFrame extends JFrame @Override public void setLocation(int x, int y) { - if (containedInScreen) + if (this.containedInScreen == Mode.ALWAYS) { Rectangle bounds = this.getGraphicsConfiguration().getBounds(); x = Math.max(x, (int) bounds.getX()); @@ -80,8 +87,10 @@ public class ContainableFrame extends JFrame @Override public void setBounds(int x, int y, int width, int height) { - if (containedInScreen) + if (this.containedInScreen == Mode.ALWAYS) { + // XXX: this is wrong if setSize/resize is called because Component::resize sets private state that is read + // in Window::setBounds Rectangle bounds = this.getGraphicsConfiguration().getBounds(); width = Math.min(width, width - (int) bounds.getX() + x); x = Math.max(x, (int) bounds.getX()); @@ -127,7 +136,7 @@ public class ContainableFrame extends JFrame final int newWindowWidth = getWidth() + increment; int newWindowX = getX(); - if (containedInScreen) + if (this.containedInScreen != Mode.NEVER) { final Rectangle screenBounds = getGraphicsConfiguration().getBounds(); final boolean wouldExpandThroughEdge = getX() + newWindowWidth > screenBounds.getX() + screenBounds.getWidth(); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/ColorPickerManager.java b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/ColorPickerManager.java new file mode 100644 index 0000000000..f85c226784 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/ColorPickerManager.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, Ron Young + * 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.ui.components.colorpicker; + +import java.awt.Color; +import java.awt.Window; +import java.awt.event.WindowEvent; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import net.runelite.client.config.ConfigManager; + +@Singleton +public class ColorPickerManager +{ + private final ConfigManager configManager; + + @Setter(AccessLevel.PACKAGE) + @Getter(AccessLevel.PACKAGE) + private RuneliteColorPicker currentPicker; + + @Inject + private ColorPickerManager(final ConfigManager configManager) + { + this.configManager = configManager; + } + + public RuneliteColorPicker create(Window owner, Color previousColor, String title, boolean alphaHidden) + { + if (currentPicker != null) + { + currentPicker.dispatchEvent(new WindowEvent(currentPicker, WindowEvent.WINDOW_CLOSING)); + } + + currentPicker = new RuneliteColorPicker(owner, previousColor, title, alphaHidden, configManager, this); + return currentPicker; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java new file mode 100644 index 0000000000..fcb69a3198 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019, Ron Young + * 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.ui.components.colorpicker; + +import com.google.common.collect.EvictingQueue; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.function.Consumer; +import javax.swing.JPanel; +import net.runelite.client.config.ConfigManager; +import static net.runelite.client.ui.components.colorpicker.RuneliteColorPicker.CONFIG_GROUP; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.Text; + +final class RecentColors +{ + private static final String CONFIG_KEY = "recentColors"; + private static final int MAX = 16; + private static final int BOX_SIZE = 16; + + private final EvictingQueue recentColors = EvictingQueue.create(MAX); + private final ConfigManager configManager; + + RecentColors(final ConfigManager configManager) + { + this.configManager = configManager; + } + + private void load() + { + String str = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY); + if (str != null) + { + recentColors.addAll(Text.fromCSV(str)); + } + } + + void add(final String color) + { + if (ColorUtil.fromString(color) == null) + { + return; + } + + recentColors.remove(color); + recentColors.add(color); + + configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, Text.toCSV(recentColors)); + } + + JPanel build(final Consumer consumer, final boolean alphaHidden) + { + load(); + + JPanel container = new JPanel(new GridBagLayout()); + + GridBagConstraints cx = new GridBagConstraints(); + cx.insets = new Insets(0, 1, 4, 2); + cx.gridy = 0; + cx.gridx = 0; + cx.anchor = GridBagConstraints.WEST; + + for (String s : recentColors) + { + if (cx.gridx == MAX / 2) + { + cx.gridy++; + cx.gridx = 0; + } + + // Make sure the last element stays in line with all of the others + if (container.getComponentCount() == recentColors.size() - 1) + { + cx.weightx = 1; + cx.gridwidth = MAX / 2 - cx.gridx; + } + + container.add(createBox(ColorUtil.fromString(s), consumer, alphaHidden), cx); + cx.gridx++; + } + + return container; + } + + private static JPanel createBox(final Color color, final Consumer consumer, final boolean alphaHidden) + { + final JPanel box = new JPanel(); + String hex = alphaHidden ? ColorUtil.colorToHexCode(color) : ColorUtil.colorToAlphaHexCode(color); + + box.setBackground(color); + box.setOpaque(true); + box.setPreferredSize(new Dimension(BOX_SIZE, BOX_SIZE)); + box.setToolTipText("#" + hex.toUpperCase()); + box.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + consumer.accept(color); + } + }); + + return box; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java index 81d6780d70..653d31ecf8 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java @@ -39,6 +39,9 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Objects; import java.util.function.Consumer; import javax.swing.JDialog; import javax.swing.JFrame; @@ -53,12 +56,15 @@ import javax.swing.text.Document; import javax.swing.text.DocumentFilter; import lombok.Getter; import lombok.Setter; +import net.runelite.client.config.ConfigManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.util.ColorUtil; import org.pushingpixels.substance.internal.SubstanceSynapse; public class RuneliteColorPicker extends JDialog { + static final String CONFIG_GROUP = "colorpicker"; + private final static int FRAME_WIDTH = 400; private final static int FRAME_HEIGHT = 380; private final static int TONE_PANEL_SIZE = 160; @@ -84,16 +90,24 @@ public class RuneliteColorPicker extends JDialog @Setter private Consumer onColorChange; - public RuneliteColorPicker(Window parent, Color previousColor, String title, boolean alphaHidden) + @Setter + private Consumer onClose; + + RuneliteColorPicker(Window parent, Color previousColor, String title, boolean alphaHidden, + final ConfigManager configManager, final ColorPickerManager colorPickerManager) { super(parent, "RuneLite Color Picker - " + title, ModalityType.MODELESS); this.selectedColor = previousColor; + this.alphaHidden = alphaHidden; + + RecentColors recentColors = new RecentColors(configManager); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setResizable(false); setSize(FRAME_WIDTH, FRAME_HEIGHT); setBackground(ColorScheme.PROGRESS_COMPLETE_COLOR); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); JPanel content = new JPanel(new BorderLayout()); content.putClientProperty(SubstanceSynapse.COLORIZATION_FACTOR, 1.0); @@ -109,7 +123,6 @@ public class RuneliteColorPicker extends JDialog rightPanel.setLayout(new GridBagLayout()); GridBagConstraints cx = new GridBagConstraints(); - cx.insets = new Insets(0, 0, 0, 0); JLabel old = new JLabel("Previous"); old.setHorizontalAlignment(JLabel.CENTER); @@ -140,11 +153,26 @@ public class RuneliteColorPicker extends JDialog hexContainer.add(hexInput, cx); cx.fill = GridBagConstraints.BOTH; - cx.gridwidth = GridBagConstraints.RELATIVE; cx.weightx = 1; cx.weighty = 1; cx.gridy = 0; cx.gridx = 0; + + JPanel recentColorsContainer = recentColors.build(c -> + { + if (!alphaHidden) + { + alphaSlider.update(c.getAlpha()); + } + + colorChange(c); + updatePanels(); + }, alphaHidden); + + rightPanel.add(recentColorsContainer, cx); + + cx.gridwidth = GridBagConstraints.RELATIVE; + cx.gridy++; rightPanel.add(old, cx); cx.gridx++; @@ -176,7 +204,6 @@ public class RuneliteColorPicker extends JDialog slidersContainer.add(blueSlider); slidersContainer.add(alphaSlider); - this.alphaHidden = alphaHidden; if (alphaHidden) { alphaSlider.setVisible(false); @@ -265,6 +292,29 @@ public class RuneliteColorPicker extends JDialog updatePanels(); updateText(); + + addWindowListener(new WindowAdapter() + { + @Override + public void windowClosing(WindowEvent e) + { + if (onClose != null) + { + onClose.accept(selectedColor); + } + + if (!Objects.equals(previousColor, selectedColor)) + { + recentColors.add(selectedColor.getRGB() + ""); + } + + RuneliteColorPicker cp = colorPickerManager.getCurrentPicker(); + if (Objects.equals(cp, RuneliteColorPicker.this)) + { + colorPickerManager.setCurrentPicker(null); + } + } + }); } private void updatePanels() diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java index 40d82c357d..aafbf0a5d4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java @@ -47,7 +47,6 @@ import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PluginChanged; @@ -111,17 +110,18 @@ public class OverlayManager { this.configManager = configManager; this.eventBus = eventBus; + + eventBus.subscribe(PluginChanged.class, this, this::onPluginChanged); + eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked); } - @Subscribe - public void onPluginChanged(final PluginChanged event) + private void onPluginChanged(final PluginChanged event) { overlays.forEach(this::loadOverlay); rebuildOverlayLayers(); } - @Subscribe - public void onMenuOptionClicked(MenuOptionClicked event) + private void onMenuOptionClicked(MenuOptionClicked event) { if (event.getMenuAction() != MenuAction.RUNELITE_OVERLAY) { @@ -138,7 +138,7 @@ public class OverlayManager Optional optionalOverlayMenuEntry = menuEntries.stream() .filter(me -> me.getOption().equals(event.getOption())) .findAny(); - optionalOverlayMenuEntry.ifPresent(overlayMenuEntry -> eventBus.post(new OverlayMenuClicked(overlayMenuEntry, overlay))); + optionalOverlayMenuEntry.ifPresent(overlayMenuEntry -> eventBus.post(OverlayMenuClicked.class, new OverlayMenuClicked(overlayMenuEntry, overlay))); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index 76d5a21386..433f4d26ef 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -50,14 +50,14 @@ import net.runelite.api.events.FocusChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.RuneLiteConfig; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.input.KeyListener; import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseAdapter; import net.runelite.client.input.MouseManager; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; -import net.runelite.client.ui.FontManager; import net.runelite.client.util.MiscUtils; @Singleton @@ -101,7 +101,8 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener final OverlayManager overlayManager, final RuneLiteConfig runeLiteConfig, final MouseManager mouseManager, - final KeyManager keyManager) + final KeyManager keyManager, + final EventBus eventbus) { this.client = client; this.overlayManager = overlayManager; @@ -109,6 +110,11 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener this.updateConfig(); keyManager.registerKeyListener(this); mouseManager.registerMouseListener(this); + + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + eventbus.subscribe(FocusChanged.class, this, this::onFocusChanged); + eventbus.subscribe(ClientTick.class, this, this::onClientTick); + eventbus.subscribe(BeforeRender.class, this, this::onBeforeRender); } private void updateConfig() @@ -120,8 +126,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener this.interfaceFont = FontManager.getFontFromType(clientFont, runeLiteConfig.interfaceFontType()); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("runelite")) { @@ -129,8 +134,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener } } - @Subscribe - public void onFocusChanged(FocusChanged event) + private void onFocusChanged(FocusChanged event) { if (!event.isFocused()) { @@ -140,7 +144,6 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener } } - @Subscribe protected void onClientTick(ClientTick t) { if (menuEntries == null) @@ -167,8 +170,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener client.setMenuEntries(newEntries); } - @Subscribe - public void onBeforeRender(BeforeRender event) + private void onBeforeRender(BeforeRender event) { menuEntries = null; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java index 541196d646..49a18caba6 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayUtil.java @@ -393,4 +393,30 @@ public class OverlayUtil OverlayUtil.drawStrokeAndFillPoly(graphics, color, outlineWidth, outlineAlpha, fillAlpha, tilePoly); } } + + 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); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java index 3a433ffb15..b643bc0062 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java @@ -29,9 +29,9 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; -import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; +import java.awt.image.BufferedImage; import lombok.Getter; import lombok.Setter; import net.runelite.client.ui.FontManager; @@ -53,7 +53,7 @@ public class InfoBoxComponent implements LayoutableRenderableEntity private String text; private Color color = Color.WHITE; private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR; - private Image image; + private BufferedImage image; @Override public Dimension render(Graphics2D graphics) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java index 8c2889e8e6..fab945c11b 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBox.java @@ -25,7 +25,7 @@ package net.runelite.client.ui.overlay.infobox; import java.awt.Color; -import java.awt.Image; +import java.awt.image.BufferedImage; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -38,11 +38,11 @@ public abstract class InfoBox @Getter @Setter - private Image image; + private BufferedImage image; @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) - private Image scaledImage; + private BufferedImage scaledImage; @Getter(AccessLevel.PACKAGE) @Setter @@ -52,7 +52,7 @@ public abstract class InfoBox @Setter private String tooltip; - public InfoBox(Image image, Plugin plugin) + public InfoBox(BufferedImage image, Plugin plugin) { this.plugin = plugin; setImage(image); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java index 56ef1a66fd..f2e4b2f1ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java @@ -27,7 +27,6 @@ package net.runelite.client.ui.overlay.infobox; import com.google.common.base.Preconditions; import com.google.common.collect.ComparisonChain; import java.awt.Graphics; -import java.awt.Image; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Collections; @@ -39,7 +38,8 @@ import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.events.ConfigChanged; import net.runelite.client.config.RuneLiteConfig; -import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.plugins.PluginDescriptor; @Singleton @@ -50,13 +50,14 @@ public class InfoBoxManager private final RuneLiteConfig runeLiteConfig; @Inject - private InfoBoxManager(final RuneLiteConfig runeLiteConfig) + private InfoBoxManager(final RuneLiteConfig runeLiteConfig, final EventBus eventbus) { this.runeLiteConfig = runeLiteConfig; + + eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged); } - @Subscribe - public void onConfigChanged(ConfigChanged event) + private void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("runelite") && event.getKey().equals("infoBoxSize")) { @@ -72,6 +73,14 @@ public class InfoBoxManager updateInfoBoxImage(infoBox); infoBoxes.add(infoBox); refreshInfoBoxes(); + + BufferedImage image = infoBox.getImage(); + + if (image instanceof AsyncBufferedImage) + { + AsyncBufferedImage abi = (AsyncBufferedImage) image; + abi.onChanged(() -> updateInfoBoxImage(infoBox)); + } } public void removeInfoBox(InfoBox infoBox) @@ -118,7 +127,7 @@ public class InfoBoxManager } } - private void updateInfoBoxImage(final InfoBox infoBox) + public void updateInfoBoxImage(final InfoBox infoBox) { if (infoBox.getImage() == null) { @@ -126,8 +135,8 @@ public class InfoBoxManager } // Set scaled InfoBox image - final Image image = infoBox.getImage(); - Image resultImage = image; + final BufferedImage image = infoBox.getImage(); + BufferedImage resultImage = image; final double width = image.getWidth(null); final double height = image.getHeight(null); final double size = Math.max(2, runeLiteConfig.infoBoxSize()); // Limit size to 2 as that is minimum size not causing breakage diff --git a/runelite-client/src/main/java/net/runelite/client/util/DeferredEventBus.java b/runelite-client/src/main/java/net/runelite/client/util/DeferredEventBus.java index 4ac1941d7f..59b2111b84 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/DeferredEventBus.java +++ b/runelite-client/src/main/java/net/runelite/client/util/DeferredEventBus.java @@ -24,18 +24,20 @@ */ package net.runelite.client.util; +import io.reactivex.annotations.NonNull; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.client.eventbus.EventBus; -import org.jetbrains.annotations.NotNull; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; @Singleton public class DeferredEventBus extends EventBus { private final EventBus eventBus; - private final Queue pendingEvents = new ConcurrentLinkedQueue<>(); + private final Queue> pendingEvents = new ConcurrentLinkedQueue<>(); @Inject private DeferredEventBus(EventBus eventBus) @@ -44,21 +46,9 @@ public class DeferredEventBus extends EventBus } @Override - public void register(@NotNull Object object) + public void post(Class eventClass, @NonNull Object event) { - eventBus.register(object); - } - - @Override - public void unregister(@NotNull Object object) - { - eventBus.unregister(object); - } - - @Override - public void post(@NotNull Object object) - { - pendingEvents.add(object); + pendingEvents.add(new ImmutablePair<>(eventClass, event)); } public void replay() @@ -66,10 +56,10 @@ public class DeferredEventBus extends EventBus int size = pendingEvents.size(); while (size-- > 0) { - Object object = pendingEvents.poll(); - if (object != null) + Pair eventPair = pendingEvents.poll(); + if (eventPair != null) { - eventBus.post(object); + eventBus.post(eventPair.getKey(), eventPair.getValue()); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/util/ExecutorServiceExceptionLogger.java b/runelite-client/src/main/java/net/runelite/client/util/ExecutorServiceExceptionLogger.java index af5f13c89f..fe8902d663 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ExecutorServiceExceptionLogger.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ExecutorServiceExceptionLogger.java @@ -34,12 +34,10 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; /** * Wrapper for ${@link ScheduledExecutorService} that will log all uncaught exceptions as warning to console */ -@Slf4j @RequiredArgsConstructor public class ExecutorServiceExceptionLogger implements ScheduledExecutorService { diff --git a/runelite-client/src/main/java/net/runelite/client/util/GameEventManager.java b/runelite-client/src/main/java/net/runelite/client/util/GameEventManager.java index e837bb54d9..9e1a2d6659 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/GameEventManager.java +++ b/runelite-client/src/main/java/net/runelite/client/util/GameEventManager.java @@ -110,7 +110,7 @@ public class GameEventManager clientThread.invoke(() -> { - eventBus.register(subscriber); + // eventBus.register(subscriber); for (final InventoryID inventory : InventoryID.values()) { @@ -118,7 +118,7 @@ public class GameEventManager if (itemContainer != null) { - eventBus.post(new ItemContainerChanged(inventory.getId(), itemContainer)); + eventBus.post(ItemContainerChanged.class, new ItemContainerChanged(inventory.getId(), itemContainer)); } } @@ -127,7 +127,7 @@ public class GameEventManager if (npc != null) { final NpcSpawned npcSpawned = new NpcSpawned(npc); - eventBus.post(npcSpawned); + eventBus.post(NpcSpawned.class, npcSpawned); } } @@ -136,7 +136,7 @@ public class GameEventManager if (player != null) { final PlayerSpawned playerSpawned = new PlayerSpawned(player); - eventBus.post(playerSpawned); + eventBus.post(PlayerSpawned.class, playerSpawned); } } @@ -147,7 +147,7 @@ public class GameEventManager final WallObjectSpawned objectSpawned = new WallObjectSpawned(); objectSpawned.setTile(tile); objectSpawned.setWallObject(object); - eventBus.post(objectSpawned); + eventBus.post(WallObjectSpawned.class, objectSpawned); }); Optional.ofNullable(tile.getDecorativeObject()).ifPresent(object -> @@ -155,7 +155,7 @@ public class GameEventManager final DecorativeObjectSpawned objectSpawned = new DecorativeObjectSpawned(); objectSpawned.setTile(tile); objectSpawned.setDecorativeObject(object); - eventBus.post(objectSpawned); + eventBus.post(DecorativeObjectSpawned.class, objectSpawned); }); Optional.ofNullable(tile.getGroundObject()).ifPresent(object -> @@ -163,7 +163,7 @@ public class GameEventManager final GroundObjectSpawned objectSpawned = new GroundObjectSpawned(); objectSpawned.setTile(tile); objectSpawned.setGroundObject(object); - eventBus.post(objectSpawned); + eventBus.post(GroundObjectSpawned.class, objectSpawned); }); Arrays.stream(tile.getGameObjects()) @@ -173,7 +173,7 @@ public class GameEventManager final GameObjectSpawned objectSpawned = new GameObjectSpawned(); objectSpawned.setTile(tile); objectSpawned.setGameObject(object); - eventBus.post(objectSpawned); + eventBus.post(GameObjectSpawned.class, objectSpawned); }); Optional.ofNullable(tile.getItemLayer()).ifPresent(itemLayer -> @@ -187,12 +187,10 @@ public class GameEventManager current = current.getNext(); final ItemSpawned itemSpawned = new ItemSpawned(tile, item); - eventBus.post(itemSpawned); + eventBus.post(ItemSpawned.class, itemSpawned); } }); }); - - eventBus.unregister(subscriber); }); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java b/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java index caec527320..20663f1d38 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java +++ b/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java @@ -36,7 +36,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.client.account.AccountSession; import net.runelite.client.account.SessionManager; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PartyChanged; import net.runelite.http.api.ws.messages.party.Join; import net.runelite.http.api.ws.messages.party.Part; @@ -70,6 +69,9 @@ public class PartyService this.wsClient = wsClient; this.sessionManager = sessionManager; this.eventBus = eventBus; + + eventBus.subscribe(UserJoin.class, this, this::onUserJoin); + eventBus.subscribe(UserPart.class, this, this::onUserPart); } public void changeParty(UUID newParty) @@ -94,7 +96,7 @@ public class PartyService wsClient.changeSession(null); } - eventBus.post(new PartyChanged(partyId)); + eventBus.post(PartyChanged.class, new PartyChanged(partyId)); return; } @@ -107,12 +109,11 @@ public class PartyService wsClient.changeSession(uuid); } - eventBus.post(new PartyChanged(partyId)); + eventBus.post(PartyChanged.class, new PartyChanged(partyId)); wsClient.send(new Join(partyId, username)); } - @Subscribe - public void onUserJoin(final UserJoin message) + private void onUserJoin(final UserJoin message) { if (!partyId.equals(message.getPartyId())) { @@ -135,8 +136,7 @@ public class PartyService } } - @Subscribe - public void onUserPart(final UserPart message) + private void onUserPart(final UserPart message) { members.removeIf(member -> member.getMemberId().equals(message.getMemberId())); } diff --git a/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java b/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java index 5b92f5c533..8006b5ee1e 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java +++ b/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java @@ -174,7 +174,7 @@ public class WSClient extends WebSocketListener implements AutoCloseable } log.debug("Got: {}", text); - eventBus.post(message); + eventBus.post(PartyMessage.class, message); } @Override diff --git a/runelite-client/src/main/resources/item_stats.json b/runelite-client/src/main/resources/item_stats.json new file mode 100644 index 0000000000..a1378a5484 --- /dev/null +++ b/runelite-client/src/main/resources/item_stats.json @@ -0,0 +1,63437 @@ +{ + "0": { + "name": "Dwarf remains", + "quest": true + }, + "1": { + "name": "Toolkit", + "quest": true, + "weight": 0.453 + }, + "2": { + "name": "Cannonball" + }, + "3": { + "name": "Nulodion's notes", + "quest": true, + "weight": 0.028 + }, + "4": { + "name": "Ammo mould", + "quest": true, + "weight": 4.535 + }, + "5": { + "name": "Instruction manual", + "weight": 0.51 + }, + "6": { + "name": "Cannon base", + "quest": true, + "weight": 7.0 + }, + "8": { + "name": "Cannon stand", + "quest": true, + "weight": 7.0 + }, + "10": { + "name": "Cannon barrels", + "quest": true, + "weight": 7.0 + }, + "12": { + "name": "Cannon furnace", + "quest": true, + "weight": 7.0 + }, + "14": { + "name": "Railing", + "quest": true + }, + "15": { + "name": "Holy table napkin", + "quest": true, + "weight": 0.028 + }, + "16": { + "name": "Magic whistle", + "quest": true, + "weight": 0.2 + }, + "17": { + "name": "Grail bell", + "quest": true, + "weight": 0.028 + }, + "18": { + "name": "Magic gold feather", + "quest": true, + "weight": 0.005 + }, + "19": { + "name": "Holy grail", + "quest": true, + "weight": 0.085 + }, + "20": { + "name": "White cog", + "quest": true, + "weight": 1.0 + }, + "21": { + "name": "Black cog", + "quest": true, + "weight": 1.0 + }, + "22": { + "name": "Blue cog", + "quest": true, + "weight": 1.0 + }, + "23": { + "name": "Red cog", + "quest": true, + "weight": 1.0 + }, + "24": { + "name": "Rat poison", + "quest": true, + "weight": 0.141 + }, + "25": { + "name": "Red vine worm", + "quest": true + }, + "26": { + "name": "Fishing trophy", + "quest": true, + "weight": 0.085 + }, + "27": { + "name": "Fishing pass", + "quest": true, + "weight": 0.006 + }, + "28": { + "name": "Insect repellent", + "weight": 0.028 + }, + "30": { + "name": "Bucket of wax", + "quest": true, + "weight": 2.5 + }, + "32": { + "name": "Lit black candle", + "quest": true, + "weight": 0.028 + }, + "33": { + "name": "Lit candle" + }, + "35": { + "name": "Excalibur", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": 29, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "dmagic": 1, + "str": 25, + "aspeed": 5 + } + }, + "36": { + "name": "Candle", + "weight": 0.028 + }, + "38": { + "name": "Black candle", + "quest": true, + "weight": 0.028 + }, + "39": { + "name": "Bronze arrowtips" + }, + "40": { + "name": "Iron arrowtips" + }, + "41": { + "name": "Steel arrowtips" + }, + "42": { + "name": "Mithril arrowtips" + }, + "43": { + "name": "Adamant arrowtips" + }, + "44": { + "name": "Rune arrowtips" + }, + "45": { + "name": "Opal bolt tips" + }, + "46": { + "name": "Pearl bolt tips" + }, + "47": { + "name": "Barb bolttips" + }, + "48": { + "name": "Longbow (u)", + "weight": 1.332 + }, + "50": { + "name": "Shortbow (u)", + "weight": 1.0 + }, + "52": { + "name": "Arrow shaft" + }, + "53": { + "name": "Headless arrow" + }, + "54": { + "name": "Oak shortbow (u)", + "weight": 0.992 + }, + "56": { + "name": "Oak longbow (u)", + "weight": 1.332 + }, + "58": { + "name": "Willow longbow (u)", + "weight": 1.332 + }, + "60": { + "name": "Willow shortbow (u)", + "weight": 0.992 + }, + "62": { + "name": "Maple longbow (u)", + "weight": 1.332 + }, + "64": { + "name": "Maple shortbow (u)", + "weight": 0.992 + }, + "66": { + "name": "Yew longbow (u)", + "weight": 1.332 + }, + "68": { + "name": "Yew shortbow (u)", + "weight": 0.992 + }, + "70": { + "name": "Magic longbow (u)", + "weight": 1.332 + }, + "72": { + "name": "Magic shortbow (u)", + "weight": 0.992 + }, + "74": { + "name": "Khazard helmet", + "quest": true, + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "dstab": 4, + "dslash": 5, + "dcrush": 3 + } + }, + "75": { + "name": "Khazard armour", + "quest": true, + "equipable": true, + "weight": 0.566, + "equipment": { + "slot": 4, + "dstab": 9, + "dslash": 11, + "dcrush": 10 + } + }, + "76": { + "name": "Khazard cell keys", + "quest": true, + "weight": 0.01 + }, + "77": { + "name": "Khali brew", + "quest": true, + "weight": 0.113 + }, + "78": { + "name": "Ice arrows", + "quest": true, + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "83": { + "name": "Lever", + "quest": true, + "weight": 0.056 + }, + "84": { + "name": "Staff of armadyl", + "quest": true, + "weight": 5.0 + }, + "85": { + "name": "Shiny key", + "quest": true, + "weight": 0.01 + }, + "86": { + "name": "Pendant of lucien", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "87": { + "name": "Armadyl pendant", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "88": { + "name": "Boots of lightness", + "quest": true, + "equipable": true, + "equipment": { + "slot": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 1 + } + }, + "89": { + "name": "Boots of lightness", + "quest": true, + "equipable": true, + "equipment": { + "slot": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 1 + } + }, + "90": { + "name": "Child's blanket", + "quest": true, + "weight": 0.907 + }, + "91": { + "name": "Guam potion (unf)", + "weight": 0.056 + }, + "93": { + "name": "Marrentill potion (unf)", + "weight": 0.056 + }, + "95": { + "name": "Tarromin potion (unf)", + "weight": 0.056 + }, + "97": { + "name": "Harralander potion (unf)", + "weight": 0.056 + }, + "99": { + "name": "Ranarr potion (unf)", + "weight": 0.056 + }, + "101": { + "name": "Irit potion (unf)" + }, + "103": { + "name": "Avantoe potion (unf)", + "weight": 0.056 + }, + "105": { + "name": "Kwuarm potion (unf)", + "weight": 0.056 + }, + "107": { + "name": "Cadantine potion (unf)", + "weight": 0.056 + }, + "109": { + "name": "Dwarf weed potion (unf)", + "weight": 0.056 + }, + "111": { + "name": "Torstol potion (unf)", + "weight": 0.056 + }, + "113": { + "name": "Strength potion(4)", + "weight": 0.035 + }, + "115": { + "name": "Strength potion(3)", + "weight": 0.03 + }, + "117": { + "name": "Strength potion(2)", + "weight": 0.025 + }, + "119": { + "name": "Strength potion(1)", + "weight": 0.02 + }, + "121": { + "name": "Attack potion(3)", + "weight": 0.03 + }, + "123": { + "name": "Attack potion(2)", + "weight": 0.025 + }, + "125": { + "name": "Attack potion(1)", + "weight": 0.02 + }, + "127": { + "name": "Restore potion(3)", + "weight": 0.03 + }, + "129": { + "name": "Restore potion(2)", + "weight": 0.025 + }, + "131": { + "name": "Restore potion(1)", + "weight": 0.02 + }, + "133": { + "name": "Defence potion(3)", + "weight": 0.03 + }, + "135": { + "name": "Defence potion(2)", + "weight": 0.025 + }, + "137": { + "name": "Defence potion(1)", + "weight": 0.02 + }, + "139": { + "name": "Prayer potion(3)", + "weight": 0.03 + }, + "141": { + "name": "Prayer potion(2)", + "weight": 0.025 + }, + "143": { + "name": "Prayer potion(1)", + "weight": 0.02 + }, + "145": { + "name": "Super attack(3)", + "weight": 0.03 + }, + "147": { + "name": "Super attack(2)", + "weight": 0.025 + }, + "149": { + "name": "Super attack(1)", + "weight": 0.02 + }, + "151": { + "name": "Fishing potion(3)", + "weight": 0.03 + }, + "153": { + "name": "Fishing potion(2)", + "weight": 0.025 + }, + "155": { + "name": "Fishing potion(1)", + "weight": 0.02 + }, + "157": { + "name": "Super strength(3)", + "weight": 0.03 + }, + "159": { + "name": "Super strength(2)", + "weight": 0.025 + }, + "161": { + "name": "Super strength(1)", + "weight": 0.02 + }, + "163": { + "name": "Super defence(3)", + "weight": 0.03 + }, + "165": { + "name": "Super defence(2)", + "weight": 0.025 + }, + "167": { + "name": "Super defence(1)", + "weight": 0.02 + }, + "169": { + "name": "Ranging potion(3)", + "weight": 0.03 + }, + "171": { + "name": "Ranging potion(2)", + "weight": 0.025 + }, + "173": { + "name": "Ranging potion(1)", + "weight": 0.02 + }, + "175": { + "name": "Antipoison(3)", + "weight": 0.03 + }, + "177": { + "name": "Antipoison(2)", + "weight": 0.025 + }, + "179": { + "name": "Antipoison(1)", + "weight": 0.02 + }, + "181": { + "name": "Superantipoison(3)", + "weight": 0.03 + }, + "183": { + "name": "Superantipoison(2)", + "weight": 0.025 + }, + "185": { + "name": "Superantipoison(1)", + "weight": 0.02 + }, + "187": { + "name": "Weapon poison", + "weight": 0.025 + }, + "189": { + "name": "Zamorak brew(3)", + "weight": 0.03 + }, + "191": { + "name": "Zamorak brew(2)", + "weight": 0.025 + }, + "193": { + "name": "Zamorak brew(1)", + "weight": 0.02 + }, + "195": { + "name": "Potion", + "weight": 0.025 + }, + "197": { + "name": "Poison chalice", + "weight": 0.056 + }, + "199": { + "name": "Grimy guam leaf", + "weight": 0.007 + }, + "201": { + "name": "Grimy marrentill", + "weight": 0.007 + }, + "203": { + "name": "Grimy tarromin" + }, + "205": { + "name": "Grimy harralander", + "weight": 0.007 + }, + "207": { + "name": "Grimy ranarr weed", + "weight": 0.007 + }, + "209": { + "name": "Grimy irit leaf", + "weight": 0.007 + }, + "211": { + "name": "Grimy avantoe", + "weight": 0.007 + }, + "213": { + "name": "Grimy kwuarm", + "weight": 0.007 + }, + "215": { + "name": "Grimy cadantine", + "weight": 0.007 + }, + "217": { + "name": "Grimy dwarf weed", + "weight": 0.007 + }, + "219": { + "name": "Grimy torstol", + "weight": 0.007 + }, + "221": { + "name": "Eye of newt", + "weight": 0.007 + }, + "223": { + "name": "Red spiders' eggs", + "weight": 0.007 + }, + "225": { + "name": "Limpwurt root", + "weight": 0.007 + }, + "227": { + "name": "Vial of water", + "weight": 0.02 + }, + "229": { + "name": "Vial", + "weight": 0.015 + }, + "231": { + "name": "Snape grass", + "weight": 0.007 + }, + "233": { + "name": "Pestle and mortar", + "weight": 0.056 + }, + "235": { + "name": "Unicorn horn dust", + "weight": 0.007 + }, + "237": { + "name": "Unicorn horn", + "weight": 1.0 + }, + "239": { + "name": "White berries", + "weight": 0.007 + }, + "241": { + "name": "Dragon scale dust", + "weight": 0.007 + }, + "243": { + "name": "Blue dragon scale", + "weight": 0.01 + }, + "245": { + "name": "Wine of zamorak", + "weight": 0.085 + }, + "247": { + "name": "Jangerberries", + "weight": 0.007 + }, + "249": { + "name": "Guam leaf", + "weight": 0.007 + }, + "251": { + "name": "Marrentill", + "weight": 0.007 + }, + "253": { + "name": "Tarromin", + "weight": 0.007 + }, + "255": { + "name": "Harralander", + "weight": 0.007 + }, + "257": { + "name": "Ranarr weed", + "weight": 0.007 + }, + "259": { + "name": "Irit leaf", + "weight": 0.007 + }, + "261": { + "name": "Avantoe", + "weight": 0.007 + }, + "263": { + "name": "Kwuarm", + "weight": 0.007 + }, + "265": { + "name": "Cadantine", + "weight": 0.007 + }, + "267": { + "name": "Dwarf weed", + "weight": 0.007 + }, + "269": { + "name": "Torstol", + "weight": 0.007 + }, + "271": { + "name": "Pressure gauge", + "quest": true + }, + "272": { + "name": "Fish food", + "weight": 0.028 + }, + "273": { + "name": "Poison", + "quest": true, + "weight": 0.02 + }, + "274": { + "name": "Poisoned fish food", + "quest": true, + "weight": 0.03 + }, + "275": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "276": { + "name": "Rubber tube", + "quest": true, + "weight": 0.028 + }, + "277": { + "name": "Oil can", + "quest": true, + "weight": 0.028 + }, + "278": { + "name": "Cattleprod", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 2, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 3, + "aspeed": 4 + } + }, + "279": { + "name": "Sheep feed", + "quest": true, + "weight": 2.267 + }, + "280": { + "name": "Sheep bones (1)", + "quest": true, + "weight": 1.36 + }, + "281": { + "name": "Sheep bones (2)", + "quest": true, + "weight": 1.36 + }, + "282": { + "name": "Sheep bones (3)", + "quest": true, + "weight": 1.36 + }, + "283": { + "name": "Sheep bones (4)", + "quest": true, + "weight": 1.36 + }, + "284": { + "name": "Plague jacket", + "quest": true, + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4 + } + }, + "285": { + "name": "Plague trousers", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 7 + } + }, + "286": { + "name": "Orange goblin mail", + "quest": true, + "weight": 3.628 + }, + "287": { + "name": "Blue goblin mail", + "quest": true, + "weight": 3.628 + }, + "288": { + "name": "Goblin mail", + "weight": 3.6 + }, + "290": { + "name": "Research package", + "quest": true, + "weight": 0.907 + }, + "291": { + "name": "Notes", + "quest": true, + "weight": 0.028 + }, + "292": { + "name": "Book on baxtorian", + "quest": true, + "weight": 0.51 + }, + "293": { + "name": "A key", + "quest": true, + "weight": 0.01 + }, + "294": { + "name": "Glarial's pebble", + "quest": true, + "weight": 0.01 + }, + "295": { + "name": "Glarial's amulet", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "296": { + "name": "Glarial's urn", + "quest": true + }, + "297": { + "name": "Glarial's urn", + "quest": true + }, + "298": { + "name": "A key", + "quest": true, + "weight": 0.01 + }, + "299": { + "name": "Mithril seeds" + }, + "300": { + "name": "Rat's tail", + "quest": true, + "weight": 0.003 + }, + "301": { + "name": "Lobster pot", + "weight": 0.255 + }, + "303": { + "name": "Small fishing net", + "weight": 4.535 + }, + "305": { + "name": "Big fishing net", + "weight": 8.1 + }, + "307": { + "name": "Fishing rod", + "weight": 1.36 + }, + "309": { + "name": "Fly fishing rod", + "weight": 1.36 + }, + "311": { + "name": "Harpoon", + "weight": 1.36 + }, + "313": { + "name": "Fishing bait", + "equipable": true + }, + "314": { + "name": "Feather" + }, + "315": { + "name": "Shrimps", + "weight": 0.1 + }, + "317": { + "name": "Raw shrimps", + "weight": 0.12 + }, + "319": { + "name": "Anchovies", + "weight": 0.1 + }, + "321": { + "name": "Raw anchovies", + "weight": 0.12 + }, + "323": { + "name": "Burnt fish" + }, + "325": { + "name": "Sardine", + "weight": 0.12 + }, + "327": { + "name": "Raw sardine", + "weight": 0.14 + }, + "329": { + "name": "Salmon", + "weight": 0.5 + }, + "331": { + "name": "Raw salmon", + "weight": 0.55 + }, + "333": { + "name": "Trout", + "weight": 0.4 + }, + "335": { + "name": "Raw trout", + "weight": 0.45 + }, + "337": { + "name": "Giant carp", + "quest": true, + "weight": 0.5 + }, + "338": { + "name": "Raw giant carp", + "quest": true, + "weight": 0.55 + }, + "339": { + "name": "Cod", + "weight": 0.33 + }, + "341": { + "name": "Raw cod", + "weight": 0.45 + }, + "343": { + "name": "Burnt fish" + }, + "345": { + "name": "Raw herring", + "weight": 0.55 + }, + "347": { + "name": "Herring", + "weight": 0.5 + }, + "349": { + "name": "Raw pike", + "weight": 0.55 + }, + "351": { + "name": "Pike", + "weight": 0.5 + }, + "353": { + "name": "Raw mackerel", + "weight": 0.35 + }, + "355": { + "name": "Mackerel", + "weight": 0.3 + }, + "357": { + "name": "Burnt fish" + }, + "359": { + "name": "Raw tuna", + "weight": 0.45 + }, + "361": { + "name": "Tuna", + "weight": 0.4 + }, + "363": { + "name": "Raw bass", + "weight": 0.4 + }, + "365": { + "name": "Bass", + "weight": 0.35 + }, + "367": { + "name": "Burnt fish" + }, + "369": { + "name": "Burnt fish" + }, + "371": { + "name": "Raw swordfish", + "weight": 0.5 + }, + "373": { + "name": "Swordfish", + "weight": 0.4 + }, + "375": { + "name": "Burnt swordfish" + }, + "377": { + "name": "Raw lobster", + "weight": 0.4 + }, + "379": { + "name": "Lobster", + "weight": 0.35 + }, + "381": { + "name": "Burnt lobster" + }, + "383": { + "name": "Raw shark", + "weight": 0.7 + }, + "385": { + "name": "Shark", + "weight": 0.65 + }, + "387": { + "name": "Burnt shark" + }, + "389": { + "name": "Raw manta ray", + "weight": 0.45 + }, + "391": { + "name": "Manta ray", + "weight": 0.4 + }, + "393": { + "name": "Burnt manta ray" + }, + "395": { + "name": "Raw sea turtle", + "weight": 0.4 + }, + "397": { + "name": "Sea turtle", + "weight": 0.35 + }, + "399": { + "name": "Burnt sea turtle" + }, + "401": { + "name": "Seaweed", + "weight": 0.2 + }, + "403": { + "name": "Edible seaweed", + "weight": 0.25 + }, + "405": { + "name": "Casket", + "weight": 5.0 + }, + "407": { + "name": "Oyster", + "weight": 0.1 + }, + "409": { + "name": "Empty oyster", + "weight": 0.08 + }, + "411": { + "name": "Oyster pearl", + "weight": 0.002 + }, + "413": { + "name": "Oyster pearls", + "weight": 0.004 + }, + "415": { + "name": "Ethenea", + "quest": true, + "weight": 0.03 + }, + "416": { + "name": "Liquid honey", + "quest": true, + "weight": 0.03 + }, + "417": { + "name": "Sulphuric broline", + "quest": true, + "weight": 0.03 + }, + "418": { + "name": "Plague sample", + "quest": true, + "weight": 0.05 + }, + "419": { + "name": "Touch paper", + "quest": true, + "weight": 0.01 + }, + "420": { + "name": "Distillator", + "quest": true, + "weight": 0.02 + }, + "422": { + "name": "Bird feed", + "quest": true, + "weight": 0.05 + }, + "423": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "424": { + "name": "Pigeon cage", + "quest": true, + "weight": 2.0 + }, + "425": { + "name": "Pigeon cage", + "quest": true, + "weight": 2.0 + }, + "426": { + "name": "Priest gown", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 4, + "prayer": 3 + } + }, + "428": { + "name": "Priest gown", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 7, + "prayer": 3 + } + }, + "430": { + "name": "Doctors' gown", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 4 + } + }, + "431": { + "name": "Karamjan rum", + "quest": true, + "weight": 0.907 + }, + "432": { + "name": "Chest key", + "quest": true, + "weight": 0.01 + }, + "433": { + "name": "Pirate message", + "quest": true, + "weight": 0.02 + }, + "434": { + "name": "Clay", + "weight": 1.0 + }, + "436": { + "name": "Copper ore", + "weight": 2.267 + }, + "438": { + "name": "Tin ore", + "weight": 2.267 + }, + "440": { + "name": "Iron ore", + "weight": 2.267 + }, + "442": { + "name": "Silver ore", + "weight": 2.267 + }, + "444": { + "name": "Gold ore", + "weight": 2.267 + }, + "446": { + "name": "'perfect' gold ore", + "quest": true, + "weight": 2.267 + }, + "447": { + "name": "Mithril ore", + "weight": 1.814 + }, + "449": { + "name": "Adamantite ore", + "weight": 2.721 + }, + "451": { + "name": "Runite ore", + "weight": 2.267 + }, + "453": { + "name": "Coal", + "weight": 2.267 + }, + "455": { + "name": "Barcrawl card", + "weight": 0.014 + }, + "456": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "457": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "458": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "459": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "460": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "461": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "462": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "463": { + "name": "Scorpion cage", + "quest": true, + "weight": 0.15 + }, + "464": { + "name": "Strange fruit", + "weight": 0.085 + }, + "466": { + "name": "Pickaxe handle", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 3 + } + }, + "468": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "470": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "472": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "474": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "476": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "478": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "480": { + "name": "Bronze pick head", + "weight": 1.814 + }, + "482": { + "name": "Iron pick head", + "weight": 1.814 + }, + "484": { + "name": "Steel pick head", + "weight": 1.814 + }, + "486": { + "name": "Mithril pick head", + "weight": 1.814 + }, + "488": { + "name": "Adamant pick head", + "weight": 1.814 + }, + "490": { + "name": "Rune pick head", + "weight": 1.814 + }, + "492": { + "name": "Axe handle", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 3 + } + }, + "494": { + "name": "Broken axe", + "weight": 0.907 + }, + "496": { + "name": "Broken axe", + "weight": 0.907 + }, + "498": { + "name": "Broken axe", + "weight": 0.907 + }, + "500": { + "name": "Broken axe", + "weight": 0.907 + }, + "502": { + "name": "Broken axe", + "weight": 0.907 + }, + "504": { + "name": "Broken axe", + "weight": 0.907 + }, + "506": { + "name": "Broken axe", + "weight": 0.907 + }, + "522": { + "name": "Enchanted beef", + "quest": true, + "weight": 0.5 + }, + "523": { + "name": "Enchanted rat", + "quest": true, + "weight": 0.2 + }, + "524": { + "name": "Enchanted bear", + "quest": true, + "weight": 0.5 + }, + "525": { + "name": "Enchanted chicken", + "quest": true, + "weight": 0.3 + }, + "526": { + "name": "Bones", + "weight": 0.5 + }, + "528": { + "name": "Burnt bones", + "weight": 0.5 + }, + "530": { + "name": "Bat bones", + "weight": 0.3 + }, + "532": { + "name": "Big bones", + "weight": 0.8 + }, + "534": { + "name": "Babydragon bones", + "weight": 0.8 + }, + "536": { + "name": "Dragon bones", + "weight": 1.5 + }, + "538": { + "name": "Druid's robe", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "prayer": 4 + } + }, + "540": { + "name": "Druid's robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "prayer": 4 + } + }, + "542": { + "name": "Monk's robe", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "prayer": 5 + } + }, + "544": { + "name": "Monk's robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "prayer": 6 + } + }, + "546": { + "name": "Shade robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "prayer": 5 + } + }, + "548": { + "name": "Shade robe", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "prayer": 4 + } + }, + "550": { + "name": "Newcomer map", + "weight": 0.51 + }, + "552": { + "name": "Ghostspeak amulet", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "553": { + "name": "Ghost's skull", + "quest": true, + "weight": 0.08 + }, + "554": { + "name": "Fire rune" + }, + "555": { + "name": "Water rune" + }, + "556": { + "name": "Air rune" + }, + "557": { + "name": "Earth rune" + }, + "558": { + "name": "Mind rune" + }, + "559": { + "name": "Body rune" + }, + "560": { + "name": "Death rune" + }, + "561": { + "name": "Nature rune" + }, + "562": { + "name": "Chaos rune" + }, + "563": { + "name": "Law rune" + }, + "564": { + "name": "Cosmic rune" + }, + "565": { + "name": "Blood rune" + }, + "566": { + "name": "Soul rune" + }, + "567": { + "name": "Unpowered orb", + "weight": 0.453 + }, + "569": { + "name": "Fire orb", + "weight": 0.453 + }, + "571": { + "name": "Water orb", + "weight": 0.453 + }, + "573": { + "name": "Air orb", + "weight": 0.453 + }, + "575": { + "name": "Earth orb", + "weight": 0.453 + }, + "577": { + "name": "Blue wizard robe", + "equipable": true, + "equipment": { + "slot": 4, + "amagic": 3, + "dmagic": 3 + } + }, + "579": { + "name": "Blue wizard hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "581": { + "name": "Black robe", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "amagic": 3, + "dmagic": 3 + } + }, + "583": { + "name": "Bailing bucket", + "weight": 1.0 + }, + "585": { + "name": "Bailing bucket", + "weight": 1.0 + }, + "587": { + "name": "Orb of protection", + "quest": true, + "weight": 1.0 + }, + "588": { + "name": "Orbs of protection", + "quest": true, + "weight": 2.0 + }, + "589": { + "name": "Gnome amulet", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "dstab": 13, + "dslash": 13, + "dcrush": 13 + } + }, + "590": { + "name": "Tinderbox", + "weight": 0.035 + }, + "592": { + "name": "Ashes", + "weight": 0.056 + }, + "594": { + "name": "Lit torch", + "weight": 0.5 + }, + "596": { + "name": "Unlit torch", + "weight": 0.5 + }, + "598": { + "name": "Bronze fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "600": { + "name": "Astronomy book", + "quest": true, + "weight": 0.003 + }, + "601": { + "name": "Goblin kitchen key", + "quest": true, + "weight": 0.01 + }, + "602": { + "name": "Lens mould", + "quest": true, + "weight": 1.0 + }, + "603": { + "name": "Observatory lens", + "quest": true, + "weight": 0.003 + }, + "604": { + "name": "Bone shard", + "quest": true, + "weight": 0.01 + }, + "605": { + "name": "Bone key", + "quest": true, + "weight": 0.01 + }, + "606": { + "name": "Stone-plaque", + "quest": true, + "weight": 0.8 + }, + "607": { + "name": "Tattered scroll", + "quest": true, + "weight": 0.02 + }, + "608": { + "name": "Crumpled scroll", + "quest": true, + "weight": 0.02 + }, + "609": { + "name": "Rashiliyia corpse", + "quest": true, + "weight": 0.3 + }, + "610": { + "name": "Zadimus corpse", + "quest": true, + "weight": 0.5 + }, + "611": { + "name": "Locating crystal", + "quest": true, + "weight": 0.9 + }, + "616": { + "name": "Beads of the dead", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1, + "prayer": 1 + } + }, + "617": { + "name": "Coins", + "weight": 0.002 + }, + "618": { + "name": "Bone beads", + "quest": true, + "weight": 0.001 + }, + "619": { + "name": "Paramaya ticket", + "weight": 0.004 + }, + "621": { + "name": "Ship ticket", + "weight": 0.004 + }, + "623": { + "name": "Sword pommel", + "quest": true, + "weight": 0.085 + }, + "624": { + "name": "Bervirius notes", + "quest": true, + "weight": 0.02 + }, + "625": { + "name": "Wampum belt", + "quest": true, + "weight": 0.453 + }, + "626": { + "name": "Pink boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "628": { + "name": "Green boots", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "630": { + "name": "Blue boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "632": { + "name": "Cream boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "634": { + "name": "Turquoise boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "636": { + "name": "Pink robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "638": { + "name": "Green robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "640": { + "name": "Blue robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "642": { + "name": "Cream robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "644": { + "name": "Turquoise robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "646": { + "name": "Pink robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "648": { + "name": "Green robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "650": { + "name": "Blue robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "652": { + "name": "Cream robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "654": { + "name": "Turquoise robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "656": { + "name": "Pink hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "658": { + "name": "Green hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "660": { + "name": "Blue hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "662": { + "name": "Cream hat", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "664": { + "name": "Turquoise hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "666": { + "name": "Portrait", + "quest": true, + "weight": 1.36 + }, + "667": { + "name": "Blurite sword", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 14, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 10, + "aspeed": 5 + } + }, + "668": { + "name": "Blurite ore", + "quest": true, + "weight": 2.267 + }, + "669": { + "name": "Specimen jar", + "quest": true, + "weight": 0.056 + }, + "670": { + "name": "Specimen brush", + "quest": true, + "weight": 0.056 + }, + "671": { + "name": "Animal skull", + "quest": true, + "weight": 0.085 + }, + "672": { + "name": "Special cup", + "quest": true, + "weight": 0.085 + }, + "673": { + "name": "Teddy", + "quest": true, + "weight": 0.085 + }, + "674": { + "name": "Cracked sample", + "weight": 0.085 + }, + "675": { + "name": "Rock pick", + "weight": 0.056 + }, + "676": { + "name": "Trowel", + "quest": true, + "weight": 0.056 + }, + "677": { + "name": "Panning tray", + "quest": true, + "weight": 0.085 + }, + "679": { + "name": "Panning tray", + "quest": true, + "weight": 0.085 + }, + "680": { + "name": "Nuggets" + }, + "681": { + "name": "Ancient talisman", + "quest": true, + "weight": 0.085 + }, + "682": { + "name": "Unstamped letter", + "quest": true, + "weight": 0.02 + }, + "683": { + "name": "Sealed letter", + "quest": true, + "weight": 0.02 + }, + "684": { + "name": "Belt buckle", + "weight": 1.0 + }, + "685": { + "name": "Old boot", + "weight": 0.056 + }, + "686": { + "name": "Rusty sword", + "weight": 2.267 + }, + "687": { + "name": "Broken arrow", + "weight": 0.015 + }, + "688": { + "name": "Buttons", + "quest": true, + "weight": 0.001 + }, + "689": { + "name": "Broken staff", + "weight": 1.814 + }, + "690": { + "name": "Broken glass", + "quest": true, + "weight": 0.056 + }, + "691": { + "name": "Level 1 certificate", + "quest": true, + "weight": 0.02 + }, + "692": { + "name": "Level 2 certificate", + "quest": true, + "weight": 0.02 + }, + "693": { + "name": "Level 3 certificate", + "quest": true, + "weight": 0.02 + }, + "694": { + "name": "Ceramic remains", + "weight": 0.056 + }, + "695": { + "name": "Old tooth", + "weight": 0.001 + }, + "696": { + "name": "Invitation letter", + "quest": true + }, + "697": { + "name": "Damaged armour", + "weight": 7.711 + }, + "698": { + "name": "Broken armour", + "weight": 7.711 + }, + "699": { + "name": "Stone tablet", + "quest": true, + "weight": 0.8 + }, + "700": { + "name": "Chemical powder", + "quest": true, + "weight": 0.028 + }, + "701": { + "name": "Ammonium nitrate", + "quest": true, + "weight": 0.015 + }, + "702": { + "name": "Unidentified liquid", + "quest": true, + "weight": 0.025 + }, + "703": { + "name": "Nitroglycerin", + "quest": true, + "weight": 0.025 + }, + "704": { + "name": "Ground charcoal", + "quest": true, + "weight": 0.008 + }, + "705": { + "name": "Mixed chemicals", + "quest": true, + "weight": 0.03 + }, + "706": { + "name": "Mixed chemicals", + "quest": true, + "weight": 0.03 + }, + "707": { + "name": "Chemical compound", + "quest": true, + "weight": 0.035 + }, + "708": { + "name": "Arcenia root", + "quest": true, + "weight": 0.01 + }, + "709": { + "name": "Chest key", + "quest": true, + "weight": 0.01 + }, + "710": { + "name": "Vase", + "weight": 0.5 + }, + "711": { + "name": "Book on chemicals", + "quest": true, + "weight": 0.51 + }, + "713": { + "name": "Clue scroll" + }, + "714": { + "name": "Radimus notes", + "quest": true, + "weight": 0.02 + }, + "715": { + "name": "Radimus notes", + "quest": true, + "weight": 0.02 + }, + "716": { + "name": "Bull roarer", + "quest": true, + "weight": 0.02 + }, + "717": { + "name": "Scrawled note", + "quest": true, + "weight": 0.02 + }, + "718": { + "name": "A scribbled note", + "quest": true, + "weight": 0.02 + }, + "719": { + "name": "Scrumpled note", + "quest": true, + "weight": 0.02 + }, + "720": { + "name": "Sketch", + "quest": true, + "weight": 0.02 + }, + "721": { + "name": "Gold bowl", + "quest": true, + "weight": 0.8 + }, + "722": { + "name": "Blessed gold bowl", + "quest": true, + "weight": 0.8 + }, + "723": { + "name": "Golden bowl", + "quest": true, + "weight": 1.0 + }, + "724": { + "name": "Golden bowl", + "quest": true, + "weight": 1.0 + }, + "725": { + "name": "Golden bowl", + "quest": true, + "weight": 1.0 + }, + "726": { + "name": "Golden bowl", + "quest": true, + "weight": 1.0 + }, + "727": { + "name": "Hollow reed", + "quest": true, + "weight": 0.012 + }, + "729": { + "name": "Shamans tome", + "quest": true, + "weight": 0.51 + }, + "730": { + "name": "Binding book", + "quest": true, + "weight": 0.5 + }, + "731": { + "name": "Enchanted vial", + "weight": 0.01 + }, + "732": { + "name": "Holy water", + "quest": true, + "equipable": true, + "equipment": { + "slot": 3, + "arange": 6, + "rstr": 12, + "aspeed": 3 + } + }, + "733": { + "name": "Smashed glass", + "weight": 0.002 + }, + "735": { + "name": "Yommi tree seeds", + "quest": true + }, + "736": { + "name": "Yommi tree seeds", + "quest": true + }, + "737": { + "name": "Snakeweed mixture", + "weight": 0.025 + }, + "738": { + "name": "Ardrigal mixture", + "quest": true, + "weight": 0.025 + }, + "739": { + "name": "Bravery potion", + "quest": true, + "weight": 0.025 + }, + "740": { + "name": "Blue hat", + "quest": true, + "weight": 0.453 + }, + "741": { + "name": "Chunk of crystal", + "quest": true, + "weight": 0.05 + }, + "742": { + "name": "Hunk of crystal", + "quest": true, + "weight": 0.05 + }, + "743": { + "name": "Lump of crystal", + "quest": true, + "weight": 0.05 + }, + "744": { + "name": "Heart crystal", + "quest": true, + "weight": 0.15 + }, + "745": { + "name": "Heart crystal", + "quest": true, + "weight": 0.15 + }, + "746": { + "name": "Dark dagger", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "aspeed": 4 + } + }, + "747": { + "name": "Glowing dagger", + "quest": true, + "equipable": true, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "aspeed": 4 + } + }, + "748": { + "name": "Holy force", + "quest": true, + "weight": 0.02 + }, + "749": { + "name": "Yommi totem", + "quest": true, + "weight": 3.0 + }, + "750": { + "name": "Gilded totem", + "quest": true, + "weight": 3.0 + }, + "751": { + "name": "Gnomeball", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 3 + } + }, + "753": { + "name": "Cadava berries", + "weight": 0.007 + }, + "755": { + "name": "Message", + "quest": true, + "weight": 0.02 + }, + "756": { + "name": "Cadava potion", + "quest": true, + "weight": 0.025 + }, + "757": { + "name": "Book", + "quest": true, + "weight": 0.2 + }, + "759": { + "name": "Weapon store key", + "quest": true, + "weight": 0.01 + }, + "761": { + "name": "Intel report", + "quest": true, + "weight": 0.02 + }, + "763": { + "name": "Broken shield", + "quest": true, + "weight": 2.721 + }, + "765": { + "name": "Broken shield", + "quest": true, + "weight": 2.721 + }, + "767": { + "name": "Phoenix crossbow", + "quest": true, + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 6, + "aspeed": 6 + } + }, + "769": { + "name": "Certificate", + "quest": true, + "weight": 0.02 + }, + "771": { + "name": "Dramen branch", + "quest": true, + "weight": 2.267 + }, + "772": { + "name": "Dramen staff", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 10, + "aspeed": 4 + } + }, + "773": { + "name": "'perfect' ring", + "quest": true, + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 12 + } + }, + "774": { + "name": "'perfect' necklace", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "775": { + "name": "Cooking gauntlets", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "str": 2 + } + }, + "776": { + "name": "Goldsmith gauntlets", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "str": 2 + } + }, + "777": { + "name": "Chaos gauntlets", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "str": 2 + } + }, + "778": { + "name": "Steel gauntlets", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "str": 2 + } + }, + "779": { + "name": "Crest part", + "quest": true, + "weight": 1.36 + }, + "780": { + "name": "Crest part", + "quest": true, + "weight": 1.36 + }, + "781": { + "name": "Crest part", + "quest": true, + "weight": 1.36 + }, + "782": { + "name": "Family crest", + "quest": true, + "weight": 4.535 + }, + "783": { + "name": "Bark sample", + "quest": true, + "weight": 0.015 + }, + "784": { + "name": "Translation book", + "quest": true, + "weight": 0.51 + }, + "785": { + "name": "Glough's journal", + "quest": true, + "weight": 0.51 + }, + "786": { + "name": "Hazelmere's scroll", + "quest": true, + "weight": 0.02 + }, + "787": { + "name": "Lumber order", + "quest": true, + "weight": 0.02 + }, + "788": { + "name": "Glough's key", + "quest": true, + "weight": 0.01 + }, + "789": { + "name": "Twigs", + "quest": true, + "weight": 0.02 + }, + "790": { + "name": "Twigs", + "quest": true, + "weight": 0.02 + }, + "791": { + "name": "Twigs", + "quest": true, + "weight": 0.02 + }, + "792": { + "name": "Twigs", + "quest": true, + "weight": 0.02 + }, + "793": { + "name": "Daconia rock", + "quest": true, + "weight": 0.907 + }, + "794": { + "name": "Invasion plans", + "quest": true, + "weight": 0.02 + }, + "795": { + "name": "War ship", + "weight": 0.4 + }, + "800": { + "name": "Bronze thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 5, + "aspeed": 5 + } + }, + "801": { + "name": "Iron thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 7, + "aspeed": 5 + } + }, + "802": { + "name": "Steel thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 11, + "aspeed": 5 + } + }, + "803": { + "name": "Mithril thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 12, + "rstr": 16, + "aspeed": 5 + } + }, + "804": { + "name": "Adamant thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 17, + "rstr": 23, + "aspeed": 5 + } + }, + "805": { + "name": "Rune thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 26, + "rstr": 36, + "aspeed": 5 + } + }, + "806": { + "name": "Bronze dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 3, + "rstr": 1, + "aspeed": 3 + } + }, + "807": { + "name": "Iron dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "808": { + "name": "Steel dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "809": { + "name": "Mithril dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "810": { + "name": "Adamant dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "811": { + "name": "Rune dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "812": { + "name": "Bronze dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 3, + "rstr": 1, + "aspeed": 3 + } + }, + "813": { + "name": "Iron dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "814": { + "name": "Steel dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "815": { + "name": "Mithril dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "816": { + "name": "Adamant dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "817": { + "name": "Rune dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "819": { + "name": "Bronze dart tip" + }, + "820": { + "name": "Iron dart tip" + }, + "821": { + "name": "Steel dart tip" + }, + "822": { + "name": "Mithril dart tip" + }, + "823": { + "name": "Adamant dart tip" + }, + "824": { + "name": "Rune dart tip" + }, + "825": { + "name": "Bronze javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 25 + } + }, + "826": { + "name": "Iron javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 42 + } + }, + "827": { + "name": "Steel javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "828": { + "name": "Mithril javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 85 + } + }, + "829": { + "name": "Adamant javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 107 + } + }, + "830": { + "name": "Rune javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 124 + } + }, + "831": { + "name": "Bronze javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 25 + } + }, + "832": { + "name": "Iron javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 42 + } + }, + "833": { + "name": "Steel javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "834": { + "name": "Mithril javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 85 + } + }, + "835": { + "name": "Adamant javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 107 + } + }, + "836": { + "name": "Rune javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 124 + } + }, + "837": { + "name": "Crossbow", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 3, + "arange": 6, + "aspeed": 6 + } + }, + "839": { + "name": "Longbow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 8, + "aspeed": 6 + } + }, + "841": { + "name": "Shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 8, + "aspeed": 4 + } + }, + "843": { + "name": "Oak shortbow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 14, + "aspeed": 4 + } + }, + "845": { + "name": "Oak longbow", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "arange": 14, + "aspeed": 6 + } + }, + "847": { + "name": "Willow longbow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 20, + "aspeed": 6 + } + }, + "849": { + "name": "Willow shortbow", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "arange": 20, + "aspeed": 4 + } + }, + "851": { + "name": "Maple longbow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 29, + "aspeed": 6 + } + }, + "853": { + "name": "Maple shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 29, + "aspeed": 4 + } + }, + "855": { + "name": "Yew longbow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 47, + "aspeed": 6 + } + }, + "857": { + "name": "Yew shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 47, + "aspeed": 4 + } + }, + "859": { + "name": "Magic longbow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 69, + "aspeed": 6 + } + }, + "861": { + "name": "Magic shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 69, + "aspeed": 4 + } + }, + "863": { + "name": "Iron knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "864": { + "name": "Bronze knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "865": { + "name": "Steel knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "866": { + "name": "Mithril knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "867": { + "name": "Adamant knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "868": { + "name": "Rune knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 25, + "rstr": 24, + "aspeed": 3 + } + }, + "869": { + "name": "Black knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 10, + "rstr": 8, + "aspeed": 3 + } + }, + "870": { + "name": "Bronze knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "871": { + "name": "Iron knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "872": { + "name": "Steel knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "873": { + "name": "Mithril knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "874": { + "name": "Black knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 10, + "rstr": 8, + "aspeed": 3 + } + }, + "875": { + "name": "Adamant knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "876": { + "name": "Rune knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 25, + "rstr": 24, + "aspeed": 3 + } + }, + "877": { + "name": "Bronze bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "878": { + "name": "Bronze bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "879": { + "name": "Opal bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 14 + } + }, + "880": { + "name": "Pearl bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 48 + } + }, + "881": { + "name": "Barbed bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 12 + } + }, + "882": { + "name": "Bronze arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "883": { + "name": "Bronze arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "884": { + "name": "Iron arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "885": { + "name": "Iron arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "886": { + "name": "Steel arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "887": { + "name": "Steel arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "888": { + "name": "Mithril arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "889": { + "name": "Mithril arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "890": { + "name": "Adamant arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "891": { + "name": "Adamant arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "892": { + "name": "Rune arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "893": { + "name": "Rune arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "942": { + "name": "Bronze fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "946": { + "name": "Knife", + "weight": 0.453 + }, + "948": { + "name": "Bear fur", + "weight": 3.0 + }, + "950": { + "name": "Silk", + "weight": 1.0 + }, + "952": { + "name": "Spade", + "weight": 1.814 + }, + "954": { + "name": "Rope", + "weight": 1.36 + }, + "956": { + "name": "Flier", + "weight": 0.015 + }, + "958": { + "name": "Grey wolf fur", + "weight": 3.0 + }, + "960": { + "name": "Plank", + "weight": 0.8 + }, + "962": { + "name": "Christmas cracker", + "weight": 0.2 + }, + "964": { + "name": "Skull", + "weight": 0.08 + }, + "966": { + "name": "Tile", + "weight": 0.07 + }, + "968": { + "name": "Rock", + "weight": 1.0 + }, + "970": { + "name": "Papyrus", + "weight": 0.02 + }, + "973": { + "name": "Charcoal", + "weight": 0.005 + }, + "975": { + "name": "Machete", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "aslash": 6, + "acrush": -2, + "str": 5, + "aspeed": 5 + } + }, + "981": { + "name": "Disk of returning", + "weight": 0.453 + }, + "983": { + "name": "Brass key", + "weight": 0.01 + }, + "985": { + "name": "Tooth half of key" + }, + "987": { + "name": "Loop half of key", + "weight": 0.005 + }, + "989": { + "name": "Crystal key", + "weight": 0.01 + }, + "991": { + "name": "Muddy key", + "weight": 0.01 + }, + "993": { + "name": "Sinister key", + "weight": 0.01 + }, + "995": { + "name": "Coins" + }, + "1005": { + "name": "White apron", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 4 + } + }, + "1007": { + "name": "Red cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1009": { + "name": "Brass necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1011": { + "name": "Blue skirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "1013": { + "name": "Pink skirt", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "1015": { + "name": "Black skirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "1017": { + "name": "Wizard hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "1019": { + "name": "Black cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1021": { + "name": "Blue cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1023": { + "name": "Yellow cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1025": { + "name": "Right eye patch", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 0 + } + }, + "1027": { + "name": "Green cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1029": { + "name": "Purple cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1031": { + "name": "Orange cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "1033": { + "name": "Zamorak monk bottom", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "amagic": 2, + "dmagic": 3, + "prayer": 3 + } + }, + "1035": { + "name": "Zamorak monk top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "amagic": 2, + "dmagic": 3, + "prayer": 3 + } + }, + "1037": { + "name": "Bunny ears", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 0 + } + }, + "1038": { + "name": "Red partyhat", + "equipable": true, + "weight": 0.056, + "equipment": { + "slot": 0 + } + }, + "1040": { + "name": "Yellow partyhat", + "equipable": true, + "weight": 0.056, + "equipment": { + "slot": 0 + } + }, + "1042": { + "name": "Blue partyhat", + "equipable": true, + "weight": 0.056, + "equipment": { + "slot": 0 + } + }, + "1044": { + "name": "Green partyhat", + "equipable": true, + "weight": 0.056, + "equipment": { + "slot": 0 + } + }, + "1046": { + "name": "Purple partyhat", + "equipable": true, + "weight": 0.056, + "equipment": { + "slot": 0 + } + }, + "1048": { + "name": "White partyhat", + "equipable": true, + "weight": 0.056, + "equipment": { + "slot": 0 + } + }, + "1050": { + "name": "Santa hat", + "equipable": true, + "weight": 0.113, + "equipment": { + "slot": 0 + } + }, + "1052": { + "name": "Cape of legends", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 1, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "dmagic": 7, + "drange": 7 + } + }, + "1053": { + "name": "Green halloween mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "1055": { + "name": "Blue halloween mask", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 0 + } + }, + "1057": { + "name": "Red halloween mask", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 0 + } + }, + "1059": { + "name": "Leather gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "1061": { + "name": "Leather boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "1063": { + "name": "Leather vambraces", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "arange": 4, + "dstab": 2, + "dslash": 2, + "dcrush": 1 + } + }, + "1065": { + "name": "Green d'hide vamb", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 8, + "dstab": 3, + "dslash": 2, + "dcrush": 4, + "dmagic": 2 + } + }, + "1067": { + "name": "Iron platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "1069": { + "name": "Steel platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "1071": { + "name": "Mithril platelegs", + "equipable": true, + "weight": 7.711, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "1073": { + "name": "Adamant platelegs", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "1075": { + "name": "Bronze platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 8, + "dslash": 7, + "dcrush": 6, + "dmagic": -4, + "drange": 7 + } + }, + "1077": { + "name": "Black platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20 + } + }, + "1079": { + "name": "Rune platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "1081": { + "name": "Iron plateskirt", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "1083": { + "name": "Steel plateskirt", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "1085": { + "name": "Mithril plateskirt", + "equipable": true, + "weight": 7.257, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "1087": { + "name": "Bronze plateskirt", + "equipable": true, + "weight": 8.1, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 8, + "dslash": 7, + "dcrush": 6, + "dmagic": -4, + "drange": 7 + } + }, + "1089": { + "name": "Black plateskirt", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20 + } + }, + "1091": { + "name": "Adamant plateskirt", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "1093": { + "name": "Rune plateskirt", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "1095": { + "name": "Leather chaps", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 7, + "arange": 4, + "dstab": 2, + "dslash": 2, + "dcrush": 1 + } + }, + "1097": { + "name": "Studded chaps", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -5, + "arange": 6, + "dstab": 15, + "dslash": 16, + "dcrush": 17, + "dmagic": 6, + "drange": 16 + } + }, + "1099": { + "name": "Green d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 8, + "dstab": 22, + "dslash": 16, + "dcrush": 24, + "dmagic": 8, + "drange": 22 + } + }, + "1101": { + "name": "Iron chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "dmagic": -3, + "drange": 12 + } + }, + "1103": { + "name": "Bronze chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 7, + "dslash": 11, + "dcrush": 13, + "dmagic": -3, + "drange": 9 + } + }, + "1105": { + "name": "Steel chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 17, + "dslash": 25, + "dcrush": 30, + "dmagic": -3, + "drange": 19 + } + }, + "1107": { + "name": "Black chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 22, + "dslash": 32, + "dcrush": 39, + "dmagic": -3, + "drange": 24 + } + }, + "1109": { + "name": "Mithril chainbody", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 25, + "dslash": 35, + "dcrush": 42, + "dmagic": -3, + "drange": 27 + } + }, + "1111": { + "name": "Adamant chainbody", + "equipable": true, + "weight": 7.711, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 36, + "dslash": 50, + "dcrush": 61, + "dmagic": -3, + "drange": 38 + } + }, + "1113": { + "name": "Rune chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 63, + "dslash": 72, + "dcrush": 78, + "dmagic": -3, + "drange": 65 + } + }, + "1115": { + "name": "Iron platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "1117": { + "name": "Bronze platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 15, + "dslash": 14, + "dcrush": 9, + "dmagic": -6, + "drange": 14 + } + }, + "1119": { + "name": "Steel platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 32, + "dslash": 31, + "dcrush": 24, + "dmagic": -6, + "drange": 31 + } + }, + "1121": { + "name": "Mithril platebody", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 46, + "dslash": 44, + "dcrush": 38, + "dmagic": -6, + "drange": 44 + } + }, + "1123": { + "name": "Adamant platebody", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "1125": { + "name": "Black platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "1127": { + "name": "Rune platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "1129": { + "name": "Leather body", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": -2, + "arange": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 10, + "dmagic": 4, + "drange": 9 + } + }, + "1131": { + "name": "Hardleather body", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 4, + "amagic": -4, + "arange": 8, + "dstab": 12, + "dslash": 15, + "dcrush": 18, + "dmagic": 6, + "drange": 15 + } + }, + "1133": { + "name": "Studded body", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 4, + "amagic": -4, + "arange": 8, + "dstab": 18, + "dslash": 25, + "dcrush": 22, + "dmagic": 8, + "drange": 25 + } + }, + "1135": { + "name": "Green d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 15, + "dstab": 40, + "dslash": 32, + "dcrush": 45, + "dmagic": 20, + "drange": 40 + } + }, + "1137": { + "name": "Iron med helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "1139": { + "name": "Bronze med helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 3, + "dslash": 4, + "dcrush": 2, + "dmagic": -1, + "drange": 4 + } + }, + "1141": { + "name": "Steel med helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "1143": { + "name": "Mithril med helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 10, + "dslash": 11, + "dcrush": 9, + "dmagic": -1, + "drange": 10 + } + }, + "1145": { + "name": "Adamant med helm", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 14, + "dslash": 15, + "dcrush": 13, + "dmagic": -1, + "drange": 14 + } + }, + "1147": { + "name": "Rune med helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 22, + "dslash": 23, + "dcrush": 21, + "dmagic": -1, + "drange": 22 + } + }, + "1149": { + "name": "Dragon med helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 33, + "dslash": 35, + "dcrush": 32, + "dmagic": -1, + "drange": 34 + } + }, + "1151": { + "name": "Black med helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "1153": { + "name": "Iron full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "1155": { + "name": "Bronze full helm", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "1157": { + "name": "Steel full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "1159": { + "name": "Mithril full helm", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 13, + "dslash": 14, + "dcrush": 11, + "dmagic": -1, + "drange": 13 + } + }, + "1161": { + "name": "Adamant full helm", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "1163": { + "name": "Rune full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "1165": { + "name": "Black full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "1167": { + "name": "Leather cowl", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "arange": 1, + "dstab": 2, + "dslash": 3, + "dcrush": 4, + "dmagic": 2, + "drange": 3 + } + }, + "1169": { + "name": "Coif", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 2, + "dstab": 4, + "dslash": 6, + "dcrush": 8, + "dmagic": 4, + "drange": 4 + } + }, + "1171": { + "name": "Wooden shield", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 5, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": 1, + "drange": 4 + } + }, + "1173": { + "name": "Bronze sq shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 5, + "dslash": 6, + "dcrush": 4, + "drange": 5 + } + }, + "1175": { + "name": "Iron sq shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "drange": 8 + } + }, + "1177": { + "name": "Steel sq shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 11, + "drange": 12 + } + }, + "1179": { + "name": "Black sq shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 15, + "dslash": 16, + "dcrush": 14, + "drange": 15 + } + }, + "1181": { + "name": "Mithril sq shield", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 15, + "drange": 17 + } + }, + "1183": { + "name": "Adamant sq shield", + "equipable": true, + "weight": 4.082, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 24, + "dslash": 26, + "dcrush": 22, + "drange": 24 + } + }, + "1185": { + "name": "Rune sq shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 38, + "dslash": 40, + "dcrush": 36, + "drange": 38 + } + }, + "1187": { + "name": "Dragon sq shield", + "quest": true, + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 50, + "dslash": 52, + "dcrush": 48, + "drange": 50 + } + }, + "1189": { + "name": "Bronze kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 5, + "dslash": 7, + "dcrush": 6, + "dmagic": -1, + "drange": 6 + } + }, + "1191": { + "name": "Iron kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 8, + "dslash": 10, + "dcrush": 9, + "dmagic": -1, + "drange": 9 + } + }, + "1193": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "1195": { + "name": "Black kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "1197": { + "name": "Mithril kiteshield", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 18, + "dslash": 22, + "dcrush": 20, + "dmagic": -1, + "drange": 20 + } + }, + "1199": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "1201": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "1203": { + "name": "Iron dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "1205": { + "name": "Bronze dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 2, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 3, + "aspeed": 4 + } + }, + "1207": { + "name": "Steel dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 4, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "1209": { + "name": "Mithril dagger", + "equipable": true, + "weight": 0.396, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 10, + "aspeed": 4 + } + }, + "1211": { + "name": "Adamant dagger", + "equipable": true, + "weight": 0.51, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 8, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 14, + "aspeed": 4 + } + }, + "1213": { + "name": "Rune dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 25, + "aslash": 12, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 24, + "aspeed": 4 + } + }, + "1215": { + "name": "Dragon dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 25, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 40, + "aspeed": 4 + } + }, + "1217": { + "name": "Black dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "1219": { + "name": "Iron dagger(p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "1221": { + "name": "Bronze dagger(p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 2, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 3, + "aspeed": 4 + } + }, + "1223": { + "name": "Steel dagger(p)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 4, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "1225": { + "name": "Mithril dagger(p)", + "equipable": true, + "weight": 0.396, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 10, + "aspeed": 4 + } + }, + "1227": { + "name": "Adamant dagger(p)", + "equipable": true, + "weight": 0.51, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 8, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 14, + "aspeed": 4 + } + }, + "1229": { + "name": "Rune dagger(p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 25, + "aslash": 12, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 24, + "aspeed": 4 + } + }, + "1231": { + "name": "Dragon dagger(p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 25, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 40, + "aspeed": 4 + } + }, + "1233": { + "name": "Black dagger(p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "1237": { + "name": "Bronze spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": 1, + "dslash": 1, + "str": 6, + "aspeed": 5 + } + }, + "1239": { + "name": "Iron spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": 1, + "dslash": 1, + "str": 10, + "aspeed": 5 + } + }, + "1241": { + "name": "Steel spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "1243": { + "name": "Mithril spear", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": 1, + "dslash": 1, + "str": 18, + "aspeed": 5 + } + }, + "1245": { + "name": "Adamant spear", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": 1, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "1247": { + "name": "Rune spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "1249": { + "name": "Dragon spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5, + "str": 60, + "aspeed": 5 + } + }, + "1251": { + "name": "Bronze spear(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": 1, + "dslash": 1, + "str": 6, + "aspeed": 5 + } + }, + "1253": { + "name": "Iron spear(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": 1, + "dslash": 1, + "str": 10, + "aspeed": 5 + } + }, + "1255": { + "name": "Steel spear(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "1257": { + "name": "Mithril spear(p)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": 1, + "dslash": 1, + "str": 18, + "aspeed": 5 + } + }, + "1259": { + "name": "Adamant spear(p)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": 1, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "1261": { + "name": "Rune spear(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "1263": { + "name": "Dragon spear(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5, + "str": 60, + "aspeed": 5 + } + }, + "1265": { + "name": "Bronze pickaxe", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": -2, + "acrush": 2, + "dslash": 1, + "str": 5, + "aspeed": 5 + } + }, + "1267": { + "name": "Iron pickaxe", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": -2, + "acrush": 3, + "dslash": 1, + "str": 7, + "aspeed": 5 + } + }, + "1269": { + "name": "Steel pickaxe", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": -2, + "acrush": 6, + "dslash": 1, + "str": 9, + "aspeed": 5 + } + }, + "1271": { + "name": "Adamant pickaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": -2, + "acrush": 15, + "dslash": 1, + "str": 19, + "aspeed": 5 + } + }, + "1273": { + "name": "Mithril pickaxe", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -2, + "acrush": 10, + "dslash": 1, + "str": 13, + "aspeed": 5 + } + }, + "1275": { + "name": "Rune pickaxe", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 26, + "aslash": -2, + "acrush": 24, + "dslash": 1, + "str": 29, + "aspeed": 5 + } + }, + "1277": { + "name": "Bronze sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 3, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 5, + "aspeed": 4 + } + }, + "1279": { + "name": "Iron sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 6, + "aslash": 4, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 7, + "aspeed": 4 + } + }, + "1281": { + "name": "Steel sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 8, + "acrush": 2, + "dslash": 2, + "dcrush": 1, + "str": 12, + "aspeed": 4 + } + }, + "1283": { + "name": "Black sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 14, + "aslash": 10, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 12, + "aspeed": 4 + } + }, + "1285": { + "name": "Mithril sword", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 16, + "aslash": 11, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 17, + "aspeed": 4 + } + }, + "1287": { + "name": "Adamant sword", + "equipable": true, + "weight": 2.041, + "equipment": { + "slot": 3, + "astab": 23, + "aslash": 18, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 24, + "aspeed": 4 + } + }, + "1289": { + "name": "Rune sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": 26, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 39, + "aspeed": 4 + } + }, + "1291": { + "name": "Bronze longsword", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 5, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 7, + "aspeed": 5 + } + }, + "1293": { + "name": "Iron longsword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 6, + "aslash": 8, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 10, + "aspeed": 5 + } + }, + "1295": { + "name": "Steel longsword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 14, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 16, + "aspeed": 5 + } + }, + "1297": { + "name": "Black longsword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 13, + "aslash": 18, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 16, + "aspeed": 5 + } + }, + "1299": { + "name": "Mithril longsword", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 20, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 22, + "aspeed": 5 + } + }, + "1301": { + "name": "Adamant longsword", + "equipable": true, + "weight": 2.041, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": 29, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 31, + "aspeed": 5 + } + }, + "1303": { + "name": "Rune longsword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": 47, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 49, + "aspeed": 5 + } + }, + "1305": { + "name": "Dragon longsword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 58, + "aslash": 69, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 71, + "aspeed": 5 + } + }, + "1307": { + "name": "Bronze 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 9, + "acrush": 8, + "amagic": -4, + "drange": -1, + "str": 10, + "aspeed": 7 + } + }, + "1309": { + "name": "Iron 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 13, + "acrush": 10, + "amagic": -4, + "drange": -1, + "str": 14, + "aspeed": 7 + } + }, + "1311": { + "name": "Steel 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 21, + "acrush": 16, + "amagic": -4, + "drange": -1, + "str": 22, + "aspeed": 7 + } + }, + "1313": { + "name": "Black 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 27, + "acrush": 21, + "amagic": -4, + "drange": -1, + "str": 26, + "aspeed": 7 + } + }, + "1315": { + "name": "Mithril 2h sword", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 30, + "acrush": 24, + "amagic": -4, + "drange": -1, + "str": 31, + "aspeed": 7 + } + }, + "1317": { + "name": "Adamant 2h sword", + "equipable": true, + "weight": 4.082, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 43, + "acrush": 30, + "amagic": -4, + "drange": -1, + "str": 44, + "aspeed": 7 + } + }, + "1319": { + "name": "Rune 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 69, + "acrush": 50, + "amagic": -4, + "drange": -1, + "str": 70, + "aspeed": 7 + } + }, + "1321": { + "name": "Bronze scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 1, + "aslash": 7, + "acrush": -2, + "dslash": 1, + "str": 6, + "aspeed": 4 + } + }, + "1323": { + "name": "Iron scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": 10, + "acrush": -2, + "dslash": 1, + "str": 9, + "aspeed": 4 + } + }, + "1325": { + "name": "Steel scimitar", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 3, + "aslash": 15, + "acrush": -2, + "dslash": 1, + "str": 14, + "aspeed": 4 + } + }, + "1327": { + "name": "Black scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 19, + "acrush": -2, + "dslash": 1, + "str": 14, + "aspeed": 4 + } + }, + "1329": { + "name": "Mithril scimitar", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 21, + "acrush": -2, + "dslash": 1, + "str": 20, + "aspeed": 4 + } + }, + "1331": { + "name": "Adamant scimitar", + "equipable": true, + "weight": 2.041, + "equipment": { + "slot": 3, + "astab": 6, + "aslash": 29, + "acrush": -2, + "dslash": 1, + "str": 28, + "aspeed": 4 + } + }, + "1333": { + "name": "Rune scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "1335": { + "name": "Iron warhammer", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 11, + "amagic": -4, + "str": 9, + "aspeed": 6 + } + }, + "1337": { + "name": "Bronze warhammer", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 10, + "amagic": -4, + "str": 8, + "aspeed": 6 + } + }, + "1339": { + "name": "Steel warhammer", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 18, + "amagic": -4, + "str": 16, + "aspeed": 6 + } + }, + "1341": { + "name": "Black warhammer", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 22, + "amagic": -4, + "str": 19, + "aspeed": 6 + } + }, + "1343": { + "name": "Mithril warhammer", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 25, + "amagic": -4, + "str": 20, + "aspeed": 6 + } + }, + "1345": { + "name": "Adamant warhammer", + "equipable": true, + "weight": 2.041, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 33, + "amagic": -4, + "str": 31, + "aspeed": 6 + } + }, + "1347": { + "name": "Rune warhammer", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 53, + "amagic": -4, + "str": 48, + "aspeed": 6 + } + }, + "1349": { + "name": "Iron axe", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 5, + "acrush": 3, + "dslash": 1, + "str": 7, + "aspeed": 5 + } + }, + "1351": { + "name": "Bronze axe", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 4, + "acrush": 2, + "dslash": 1, + "str": 5, + "aspeed": 5 + } + }, + "1353": { + "name": "Steel axe", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 8, + "acrush": 6, + "dslash": 1, + "str": 9, + "aspeed": 5 + } + }, + "1355": { + "name": "Mithril axe", + "equipable": true, + "weight": 1.133, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 12, + "acrush": 10, + "dslash": 1, + "str": 13, + "aspeed": 5 + } + }, + "1357": { + "name": "Adamant axe", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 17, + "acrush": 15, + "dslash": 1, + "str": 19, + "aspeed": 5 + } + }, + "1359": { + "name": "Rune axe", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 26, + "acrush": 24, + "dslash": 1, + "str": 29, + "aspeed": 5 + } + }, + "1361": { + "name": "Black axe", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 10, + "acrush": 8, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "1363": { + "name": "Iron battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 8, + "acrush": 5, + "drange": -1, + "str": 13, + "aspeed": 6 + } + }, + "1365": { + "name": "Steel battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 16, + "acrush": 11, + "drange": -1, + "str": 20, + "aspeed": 6 + } + }, + "1367": { + "name": "Black battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 20, + "acrush": 15, + "drange": -1, + "str": 24, + "aspeed": 6 + } + }, + "1369": { + "name": "Mithril battleaxe", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 22, + "acrush": 17, + "drange": -1, + "str": 29, + "aspeed": 6 + } + }, + "1371": { + "name": "Adamant battleaxe", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 31, + "acrush": 26, + "drange": -1, + "str": 41, + "aspeed": 6 + } + }, + "1373": { + "name": "Rune battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 48, + "acrush": 43, + "drange": -1, + "str": 64, + "aspeed": 6 + } + }, + "1375": { + "name": "Bronze battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 6, + "acrush": 3, + "drange": -1, + "str": 9, + "aspeed": 6 + } + }, + "1377": { + "name": "Dragon battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 70, + "acrush": 65, + "drange": -1, + "str": 85, + "aspeed": 6 + } + }, + "1379": { + "name": "Staff", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "1381": { + "name": "Staff of air", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 3, + "aspeed": 5 + } + }, + "1383": { + "name": "Staff of water", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 3, + "aspeed": 5 + } + }, + "1385": { + "name": "Staff of earth", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 1, + "aslash": -1, + "acrush": 9, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 5, + "aspeed": 5 + } + }, + "1387": { + "name": "Staff of fire", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 3, + "aslash": -1, + "acrush": 9, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 6, + "aspeed": 5 + } + }, + "1389": { + "name": "Magic staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 7, + "aspeed": 5 + } + }, + "1391": { + "name": "Battlestaff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 5 + } + }, + "1393": { + "name": "Fire battlestaff", + "equipable": true, + "weight": 2.25, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "1395": { + "name": "Water battlestaff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "1397": { + "name": "Air battlestaff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "1399": { + "name": "Earth battlestaff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "1401": { + "name": "Mystic fire staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "1403": { + "name": "Mystic water staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "1405": { + "name": "Mystic air staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "1407": { + "name": "Mystic earth staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "1409": { + "name": "Iban's staff", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "1410": { + "name": "Iban's staff", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "1419": { + "name": "Scythe", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 3, + "aslash": 8, + "acrush": 3, + "dslash": 3, + "dcrush": 1, + "str": 10, + "aspeed": 6 + } + }, + "1420": { + "name": "Iron mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": -2, + "acrush": 9, + "str": 7, + "prayer": 1, + "aspeed": 5 + } + }, + "1422": { + "name": "Bronze mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 1, + "aslash": -2, + "acrush": 6, + "str": 5, + "prayer": 1, + "aspeed": 5 + } + }, + "1424": { + "name": "Steel mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -2, + "acrush": 13, + "str": 11, + "prayer": 2, + "aspeed": 5 + } + }, + "1426": { + "name": "Black mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": -2, + "acrush": 16, + "str": 13, + "prayer": 2, + "aspeed": 5 + } + }, + "1428": { + "name": "Mithril mace", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": -2, + "acrush": 18, + "str": 16, + "prayer": 3, + "aspeed": 5 + } + }, + "1430": { + "name": "Adamant mace", + "equipable": true, + "weight": 2.041, + "equipment": { + "slot": 3, + "astab": 13, + "aslash": -2, + "acrush": 25, + "str": 23, + "prayer": 3, + "aspeed": 5 + } + }, + "1432": { + "name": "Rune mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": -2, + "acrush": 39, + "str": 36, + "prayer": 4, + "aspeed": 5 + } + }, + "1434": { + "name": "Dragon mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": -2, + "acrush": 60, + "str": 55, + "prayer": 5, + "aspeed": 5 + } + }, + "1436": { + "name": "Rune essence", + "weight": 0.002 + }, + "1438": { + "name": "Air talisman", + "weight": 0.015 + }, + "1440": { + "name": "Earth talisman", + "weight": 0.015 + }, + "1442": { + "name": "Fire talisman", + "weight": 0.015 + }, + "1444": { + "name": "Water talisman" + }, + "1446": { + "name": "Body talisman", + "weight": 0.015 + }, + "1448": { + "name": "Mind talisman", + "weight": 0.015 + }, + "1452": { + "name": "Chaos talisman", + "weight": 0.015 + }, + "1454": { + "name": "Cosmic talisman", + "weight": 0.015 + }, + "1456": { + "name": "Death talisman", + "quest": true, + "weight": 0.015 + }, + "1458": { + "name": "Law talisman", + "weight": 0.015 + }, + "1462": { + "name": "Nature talisman", + "weight": 0.015 + }, + "1464": { + "name": "Archery ticket" + }, + "1466": { + "name": "Sea slug", + "quest": true, + "weight": 0.226 + }, + "1467": { + "name": "Damp sticks", + "quest": true, + "weight": 0.085 + }, + "1468": { + "name": "Dry sticks", + "quest": true, + "weight": 0.056 + }, + "1469": { + "name": "Broken glass", + "quest": true, + "weight": 0.056 + }, + "1470": { + "name": "Red bead", + "quest": true, + "weight": 0.003 + }, + "1472": { + "name": "Yellow bead", + "quest": true, + "weight": 0.003 + }, + "1474": { + "name": "Black bead", + "quest": true, + "weight": 0.003 + }, + "1476": { + "name": "White bead", + "quest": true, + "weight": 0.003 + }, + "1478": { + "name": "Amulet of accuracy", + "quest": true, + "equipable": true, + "equipment": { + "slot": 2, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 4, + "arange": 4 + } + }, + "1480": { + "name": "Rock", + "weight": 0.001 + }, + "1481": { + "name": "Orb of light", + "quest": true, + "weight": 5.0 + }, + "1482": { + "name": "Orb of light", + "quest": true, + "weight": 5.0 + }, + "1483": { + "name": "Orb of light", + "quest": true, + "weight": 5.0 + }, + "1484": { + "name": "Orb of light", + "quest": true, + "weight": 5.0 + }, + "1485": { + "name": "Damp cloth", + "quest": true, + "weight": 0.012 + }, + "1486": { + "name": "Piece of railing", + "quest": true, + "weight": 2.0 + }, + "1487": { + "name": "Unicorn horn", + "quest": true, + "weight": 0.007 + }, + "1488": { + "name": "Paladin's badge", + "quest": true, + "weight": 0.012 + }, + "1489": { + "name": "Paladin's badge", + "quest": true, + "weight": 0.012 + }, + "1490": { + "name": "Paladin's badge", + "quest": true, + "weight": 0.012 + }, + "1491": { + "name": "Witch's cat", + "quest": true, + "weight": 1.2 + }, + "1492": { + "name": "Doll of iban", + "quest": true, + "weight": 0.3 + }, + "1493": { + "name": "Old journal", + "quest": true, + "weight": 0.226 + }, + "1494": { + "name": "History of iban", + "quest": true, + "weight": 0.226 + }, + "1495": { + "name": "Klank's gauntlets", + "quest": true, + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "str": 2 + } + }, + "1496": { + "name": "Iban's dove", + "quest": true, + "weight": 0.1 + }, + "1497": { + "name": "Amulet of othanian", + "quest": true, + "weight": 0.01 + }, + "1498": { + "name": "Amulet of doomion", + "quest": true, + "weight": 0.01 + }, + "1499": { + "name": "Amulet of holthion", + "quest": true, + "weight": 0.01 + }, + "1500": { + "name": "Iban's shadow", + "quest": true, + "weight": 0.025 + }, + "1501": { + "name": "Dwarf brew", + "quest": true, + "weight": 0.15 + }, + "1502": { + "name": "Iban's ashes", + "quest": true, + "weight": 0.056 + }, + "1503": { + "name": "Warrant", + "quest": true, + "weight": 0.01 + }, + "1504": { + "name": "Hangover cure", + "quest": true, + "weight": 2.2 + }, + "1505": { + "name": "A magic scroll", + "quest": true, + "weight": 0.02 + }, + "1506": { + "name": "Gas mask", + "quest": true, + "equipable": true, + "weight": 0.255, + "equipment": { + "slot": 0 + } + }, + "1507": { + "name": "A small key", + "quest": true, + "weight": 0.01 + }, + "1508": { + "name": "A scruffy note", + "quest": true, + "weight": 0.01 + }, + "1509": { + "name": "Book", + "quest": true, + "weight": 0.51 + }, + "1510": { + "name": "Picture", + "quest": true, + "weight": 0.453 + }, + "1511": { + "name": "Logs", + "weight": 2.0 + }, + "1513": { + "name": "Magic logs", + "weight": 2.0 + }, + "1515": { + "name": "Yew logs", + "weight": 2.0 + }, + "1517": { + "name": "Maple logs", + "weight": 2.0 + }, + "1519": { + "name": "Willow logs", + "weight": 2.0 + }, + "1521": { + "name": "Oak logs", + "weight": 2.0 + }, + "1523": { + "name": "Lockpick", + "weight": 0.01 + }, + "1525": { + "name": "Grimy snake weed", + "quest": true, + "weight": 0.007 + }, + "1526": { + "name": "Snake weed", + "quest": true, + "weight": 0.007 + }, + "1527": { + "name": "Grimy ardrigal", + "quest": true, + "weight": 0.007 + }, + "1528": { + "name": "Ardrigal", + "quest": true, + "weight": 0.007 + }, + "1529": { + "name": "Grimy sito foil", + "quest": true + }, + "1530": { + "name": "Sito foil", + "quest": true, + "weight": 0.007 + }, + "1531": { + "name": "Grimy volencia moss", + "quest": true, + "weight": 0.007 + }, + "1532": { + "name": "Volencia moss", + "quest": true, + "weight": 0.007 + }, + "1533": { + "name": "Grimy rogue's purse", + "quest": true, + "weight": 0.007 + }, + "1534": { + "name": "Rogue's purse", + "quest": true, + "weight": 0.007 + }, + "1535": { + "name": "Map part", + "quest": true + }, + "1536": { + "name": "Map part", + "quest": true + }, + "1537": { + "name": "Map part", + "quest": true + }, + "1538": { + "name": "Crandor map", + "quest": true, + "weight": 0.015 + }, + "1539": { + "name": "Steel nails", + "quest": true + }, + "1540": { + "name": "Anti-dragon shield", + "quest": true, + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "dstab": 7, + "dslash": 9, + "dcrush": 8, + "dmagic": 2, + "drange": 8 + } + }, + "1542": { + "name": "Maze key", + "quest": true, + "weight": 0.01 + }, + "1543": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "1544": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "1545": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "1546": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "1547": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "1548": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "1549": { + "name": "Stake", + "quest": true, + "weight": 0.085 + }, + "1550": { + "name": "Garlic", + "weight": 0.028 + }, + "1552": { + "name": "Seasoned sardine", + "quest": true, + "weight": 0.12 + }, + "1554": { + "name": "Fluffs' kitten", + "quest": true, + "weight": 1.0 + }, + "1573": { + "name": "Doogle leaves", + "quest": true, + "weight": 0.007 + }, + "1575": { + "name": "Cat training medal", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1577": { + "name": "Pete's candlestick", + "quest": true, + "weight": 0.5 + }, + "1579": { + "name": "Thieves' armband", + "quest": true, + "weight": 0.025 + }, + "1580": { + "name": "Ice gloves", + "quest": true, + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9, + "dslash": 3, + "dcrush": 4, + "drange": 2 + } + }, + "1581": { + "name": "Blamish snail slime", + "quest": true, + "weight": 0.025 + }, + "1582": { + "name": "Blamish oil", + "quest": true, + "weight": 0.025 + }, + "1583": { + "name": "Fire feather", + "quest": true, + "weight": 0.002 + }, + "1584": { + "name": "Id papers", + "quest": true, + "weight": 0.01 + }, + "1585": { + "name": "Oily fishing rod", + "quest": true, + "weight": 1.36 + }, + "1586": { + "name": "Miscellaneous key", + "quest": true, + "weight": 0.01 + }, + "1588": { + "name": "Grip's keyring", + "quest": true, + "weight": 0.025 + }, + "1590": { + "name": "Dusty key", + "weight": 0.01 + }, + "1591": { + "name": "Jail key", + "weight": 0.01 + }, + "1592": { + "name": "Ring mould", + "weight": 0.453 + }, + "1594": { + "name": "Unholy mould", + "weight": 0.453 + }, + "1595": { + "name": "Amulet mould", + "weight": 0.453 + }, + "1597": { + "name": "Necklace mould" + }, + "1599": { + "name": "Holy mould", + "weight": 0.453 + }, + "1601": { + "name": "Diamond", + "weight": 0.002 + }, + "1603": { + "name": "Ruby", + "weight": 0.002 + }, + "1605": { + "name": "Emerald", + "weight": 0.002 + }, + "1607": { + "name": "Sapphire", + "weight": 0.002 + }, + "1609": { + "name": "Opal", + "weight": 0.002 + }, + "1611": { + "name": "Jade", + "weight": 0.002 + }, + "1613": { + "name": "Red topaz", + "weight": 0.002 + }, + "1615": { + "name": "Dragonstone", + "weight": 0.002 + }, + "1617": { + "name": "Uncut diamond", + "weight": 0.003 + }, + "1619": { + "name": "Uncut ruby", + "weight": 0.003 + }, + "1621": { + "name": "Uncut emerald", + "weight": 0.003 + }, + "1623": { + "name": "Uncut sapphire", + "weight": 0.003 + }, + "1625": { + "name": "Uncut opal", + "weight": 0.003 + }, + "1627": { + "name": "Uncut jade", + "weight": 0.003 + }, + "1629": { + "name": "Uncut red topaz", + "weight": 0.003 + }, + "1631": { + "name": "Uncut dragonstone", + "weight": 0.3 + }, + "1633": { + "name": "Crushed gem", + "weight": 0.003 + }, + "1635": { + "name": "Gold ring", + "equipable": true, + "weight": 0.004, + "equipment": { + "slot": 12 + } + }, + "1637": { + "name": "Sapphire ring", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "1639": { + "name": "Emerald ring", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "1641": { + "name": "Ruby ring", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "1643": { + "name": "Diamond ring", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "1645": { + "name": "Dragonstone ring", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "1654": { + "name": "Gold necklace", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1656": { + "name": "Sapphire necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1658": { + "name": "Emerald necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1660": { + "name": "Ruby necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1662": { + "name": "Diamond necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1664": { + "name": "Dragon necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1673": { + "name": "Gold amulet (u)", + "weight": 0.004 + }, + "1675": { + "name": "Sapphire amulet (u)", + "weight": 0.004 + }, + "1677": { + "name": "Emerald amulet (u)", + "weight": 0.004 + }, + "1679": { + "name": "Ruby amulet (u)", + "weight": 0.004 + }, + "1681": { + "name": "Diamond amulet (u)", + "weight": 0.004 + }, + "1683": { + "name": "Dragonstone amulet (u)", + "weight": 0.004 + }, + "1692": { + "name": "Gold amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1694": { + "name": "Sapphire amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1696": { + "name": "Emerald amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1698": { + "name": "Ruby amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1700": { + "name": "Diamond amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1702": { + "name": "Dragonstone amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1704": { + "name": "Amulet of glory", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "1706": { + "name": "Amulet of glory(1)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "1708": { + "name": "Amulet of glory(2)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "1710": { + "name": "Amulet of glory(3)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "1712": { + "name": "Amulet of glory(4)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "1714": { + "name": "Unstrung symbol", + "weight": 0.004 + }, + "1716": { + "name": "Unblessed symbol", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "1718": { + "name": "Holy symbol", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": 2, + "prayer": 8 + } + }, + "1720": { + "name": "Unstrung emblem", + "weight": 0.004 + }, + "1722": { + "name": "Unpowered symbol", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "1724": { + "name": "Unholy symbol", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2, + "astab": 2, + "aslash": 2, + "acrush": 2, + "amagic": 2, + "arange": 2, + "prayer": 8 + } + }, + "1725": { + "name": "Amulet of strength", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "str": 10 + } + }, + "1727": { + "name": "Amulet of magic", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "amagic": 10 + } + }, + "1729": { + "name": "Amulet of defence", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "dmagic": 7, + "drange": 7 + } + }, + "1731": { + "name": "Amulet of power", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 6, + "aslash": 6, + "acrush": 6, + "amagic": 6, + "arange": 6, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6, + "str": 6, + "prayer": 1 + } + }, + "1733": { + "name": "Needle" + }, + "1734": { + "name": "Thread" + }, + "1735": { + "name": "Shears", + "weight": 0.113 + }, + "1737": { + "name": "Wool", + "weight": 0.003 + }, + "1739": { + "name": "Cowhide", + "weight": 2.721 + }, + "1741": { + "name": "Leather", + "weight": 2.267 + }, + "1743": { + "name": "Hard leather", + "weight": 3.175 + }, + "1745": { + "name": "Green dragon leather", + "weight": 3.175 + }, + "1747": { + "name": "Black dragonhide", + "weight": 3.175 + }, + "1749": { + "name": "Red dragonhide", + "weight": 3.175 + }, + "1751": { + "name": "Blue dragonhide", + "weight": 3.175 + }, + "1753": { + "name": "Green dragonhide", + "weight": 3.175 + }, + "1755": { + "name": "Chisel", + "weight": 0.453 + }, + "1757": { + "name": "Brown apron", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 4 + } + }, + "1759": { + "name": "Ball of wool", + "weight": 0.012 + }, + "1761": { + "name": "Soft clay", + "weight": 0.907 + }, + "1763": { + "name": "Red dye", + "weight": 0.02 + }, + "1765": { + "name": "Yellow dye", + "weight": 0.02 + }, + "1767": { + "name": "Blue dye", + "weight": 1.0 + }, + "1769": { + "name": "Orange dye", + "quest": true, + "weight": 0.02 + }, + "1771": { + "name": "Green dye", + "weight": 0.02 + }, + "1773": { + "name": "Purple dye", + "weight": 0.02 + }, + "1775": { + "name": "Molten glass", + "weight": 0.907 + }, + "1777": { + "name": "Bow string", + "weight": 0.014 + }, + "1779": { + "name": "Flax", + "weight": 0.453 + }, + "1781": { + "name": "Soda ash", + "weight": 0.056 + }, + "1783": { + "name": "Bucket of sand", + "weight": 2.5 + }, + "1785": { + "name": "Glassblowing pipe", + "weight": 0.056 + }, + "1787": { + "name": "Unfired pot", + "weight": 0.68 + }, + "1789": { + "name": "Unfired pie dish", + "weight": 0.68 + }, + "1791": { + "name": "Unfired bowl", + "weight": 0.68 + }, + "1793": { + "name": "Woad leaf" + }, + "1794": { + "name": "Bronze wire", + "weight": 0.005 + }, + "1796": { + "name": "Silver necklace", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1797": { + "name": "Silver necklace", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "1798": { + "name": "Silver cup", + "quest": true, + "weight": 0.07 + }, + "1799": { + "name": "Silver cup", + "quest": true, + "weight": 0.07 + }, + "1800": { + "name": "Silver bottle", + "quest": true, + "weight": 0.09 + }, + "1801": { + "name": "Silver bottle", + "quest": true + }, + "1802": { + "name": "Silver book", + "quest": true, + "weight": 0.226 + }, + "1803": { + "name": "Silver book", + "quest": true, + "weight": 0.226 + }, + "1804": { + "name": "Silver needle", + "quest": true, + "weight": 0.001 + }, + "1805": { + "name": "Silver needle", + "quest": true, + "weight": 0.001 + }, + "1806": { + "name": "Silver pot", + "quest": true, + "weight": 0.907 + }, + "1807": { + "name": "Silver pot", + "quest": true, + "weight": 0.907 + }, + "1808": { + "name": "Criminal's thread", + "quest": true, + "weight": 0.002 + }, + "1809": { + "name": "Criminal's thread", + "quest": true, + "weight": 0.002 + }, + "1810": { + "name": "Criminal's thread", + "quest": true, + "weight": 0.002 + }, + "1811": { + "name": "Flypaper", + "quest": true, + "weight": 0.01 + }, + "1812": { + "name": "Pungent pot", + "quest": true, + "weight": 0.907 + }, + "1813": { + "name": "Criminal's dagger", + "quest": true, + "weight": 0.453 + }, + "1814": { + "name": "Criminal's dagger", + "quest": true, + "weight": 0.453 + }, + "1815": { + "name": "Killer's print", + "quest": true, + "weight": 0.01 + }, + "1816": { + "name": "Anna's print", + "quest": true, + "weight": 0.01 + }, + "1817": { + "name": "Bob's print", + "quest": true, + "weight": 0.01 + }, + "1818": { + "name": "Carol's print", + "quest": true + }, + "1819": { + "name": "David's print", + "quest": true, + "weight": 0.01 + }, + "1820": { + "name": "Elizabeth's print", + "quest": true, + "weight": 0.01 + }, + "1821": { + "name": "Frank's print", + "quest": true, + "weight": 0.01 + }, + "1822": { + "name": "Unknown print", + "quest": true, + "weight": 0.01 + }, + "1823": { + "name": "Waterskin(4)", + "weight": 1.1 + }, + "1825": { + "name": "Waterskin(3)", + "weight": 0.85 + }, + "1827": { + "name": "Waterskin(2)", + "weight": 0.6 + }, + "1829": { + "name": "Waterskin(1)", + "weight": 0.35 + }, + "1831": { + "name": "Waterskin(0)", + "weight": 0.1 + }, + "1833": { + "name": "Desert shirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4 + } + }, + "1835": { + "name": "Desert robe", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "1837": { + "name": "Desert boots", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 10 + } + }, + "1839": { + "name": "Metal key", + "quest": true, + "weight": 0.01 + }, + "1840": { + "name": "Cell door key", + "quest": true, + "weight": 0.01 + }, + "1841": { + "name": "Barrel", + "quest": true, + "weight": 9.979 + }, + "1842": { + "name": "Ana in a barrel", + "quest": true, + "weight": 32.0 + }, + "1843": { + "name": "Wrought iron key", + "quest": true, + "weight": 0.01 + }, + "1844": { + "name": "Slave shirt", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4 + } + }, + "1845": { + "name": "Slave robe", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "1846": { + "name": "Slave boots", + "quest": true, + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 10 + } + }, + "1847": { + "name": "Scrumpled paper", + "weight": 0.01 + }, + "1849": { + "name": "Prototype dart", + "quest": true + }, + "1850": { + "name": "Technical plans", + "quest": true, + "weight": 0.015 + }, + "1851": { + "name": "Tenti pineapple", + "quest": true, + "weight": 0.907 + }, + "1852": { + "name": "Bedabin key", + "quest": true + }, + "1853": { + "name": "Prototype dart tip", + "quest": true + }, + "1854": { + "name": "Shantay pass" + }, + "1855": { + "name": "Rock", + "quest": true, + "weight": 0.5 + }, + "1856": { + "name": "Guide book", + "quest": true, + "weight": 7.257 + }, + "1857": { + "name": "Totem", + "quest": true, + "weight": 3.0 + }, + "1858": { + "name": "Address label", + "quest": true, + "weight": 0.01 + }, + "1859": { + "name": "Raw ugthanki meat", + "weight": 0.8 + }, + "1861": { + "name": "Ugthanki meat", + "weight": 0.6 + }, + "1863": { + "name": "Pitta dough", + "weight": 0.12 + }, + "1865": { + "name": "Pitta bread", + "weight": 0.1 + }, + "1867": { + "name": "Burnt pitta bread" + }, + "1869": { + "name": "Chopped tomato", + "weight": 0.2 + }, + "1871": { + "name": "Chopped onion", + "weight": 0.2 + }, + "1873": { + "name": "Chopped ugthanki", + "weight": 0.2 + }, + "1875": { + "name": "Onion & tomato", + "weight": 0.3 + }, + "1877": { + "name": "Ugthanki & onion", + "weight": 0.3 + }, + "1879": { + "name": "Ugthanki & tomato", + "weight": 0.3 + }, + "1881": { + "name": "Kebab mix", + "weight": 0.4 + }, + "1883": { + "name": "Ugthanki kebab", + "weight": 0.5 + }, + "1885": { + "name": "Ugthanki kebab", + "weight": 0.5 + }, + "1887": { + "name": "Cake tin", + "weight": 0.1 + }, + "1889": { + "name": "Uncooked cake", + "weight": 0.5 + }, + "1891": { + "name": "Cake", + "weight": 0.3 + }, + "1893": { + "name": "2/3 cake", + "weight": 0.2 + }, + "1895": { + "name": "Slice of cake", + "weight": 0.1 + }, + "1897": { + "name": "Chocolate cake", + "weight": 0.3 + }, + "1899": { + "name": "2/3 chocolate cake", + "weight": 0.2 + }, + "1901": { + "name": "Chocolate slice", + "weight": 0.1 + }, + "1903": { + "name": "Burnt cake" + }, + "1905": { + "name": "Asgarnian ale", + "weight": 0.55 + }, + "1907": { + "name": "Wizard's mind bomb", + "weight": 0.55 + }, + "1909": { + "name": "Greenman's ale", + "quest": true, + "weight": 0.55 + }, + "1911": { + "name": "Dragon bitter", + "weight": 0.55 + }, + "1913": { + "name": "Dwarven stout", + "weight": 0.55 + }, + "1915": { + "name": "Grog", + "weight": 0.55 + }, + "1917": { + "name": "Beer", + "weight": 0.55 + }, + "1919": { + "name": "Beer glass", + "weight": 0.05 + }, + "1921": { + "name": "Bowl of water", + "weight": 0.907 + }, + "1923": { + "name": "Bowl", + "weight": 0.453 + }, + "1925": { + "name": "Bucket", + "weight": 1.0 + }, + "1927": { + "name": "Bucket of milk", + "weight": 2.2 + }, + "1929": { + "name": "Bucket of water", + "weight": 3.0 + }, + "1931": { + "name": "Pot", + "weight": 0.453 + }, + "1933": { + "name": "Pot of flour", + "weight": 1.36 + }, + "1935": { + "name": "Jug", + "weight": 0.453 + }, + "1937": { + "name": "Jug of water", + "weight": 1.0 + }, + "1939": { + "name": "Swamp tar" + }, + "1940": { + "name": "Raw swamp paste" + }, + "1941": { + "name": "Swamp paste" + }, + "1942": { + "name": "Potato", + "weight": 0.5 + }, + "1944": { + "name": "Egg", + "weight": 0.02 + }, + "1947": { + "name": "Grain", + "weight": 0.6 + }, + "1949": { + "name": "Chef's hat", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0 + } + }, + "1951": { + "name": "Redberries", + "weight": 0.007 + }, + "1953": { + "name": "Pastry dough", + "weight": 0.17 + }, + "1955": { + "name": "Cooking apple", + "weight": 0.085 + }, + "1957": { + "name": "Onion", + "weight": 0.15 + }, + "1959": { + "name": "Pumpkin", + "weight": 0.5 + }, + "1961": { + "name": "Easter egg" + }, + "1963": { + "name": "Banana", + "weight": 0.028 + }, + "1965": { + "name": "Cabbage", + "weight": 0.453 + }, + "1967": { + "name": "Cabbage", + "weight": 0.35 + }, + "1969": { + "name": "Spinach roll", + "weight": 0.1 + }, + "1971": { + "name": "Kebab", + "weight": 0.25 + }, + "1973": { + "name": "Chocolate bar", + "weight": 0.15 + }, + "1975": { + "name": "Chocolate dust", + "weight": 0.15 + }, + "1977": { + "name": "Chocolatey milk", + "weight": 2.0 + }, + "1978": { + "name": "Cup of tea", + "weight": 0.1 + }, + "1980": { + "name": "Empty cup", + "weight": 0.05 + }, + "1982": { + "name": "Tomato", + "weight": 0.08 + }, + "1984": { + "name": "Rotten apple", + "quest": true, + "weight": 0.12 + }, + "1985": { + "name": "Cheese", + "weight": 0.2 + }, + "1987": { + "name": "Grapes", + "weight": 0.25 + }, + "1989": { + "name": "Half full wine jug", + "weight": 1.0 + }, + "1991": { + "name": "Jug of bad wine", + "weight": 1.5 + }, + "1993": { + "name": "Jug of wine", + "weight": 1.5 + }, + "1995": { + "name": "Unfermented wine", + "weight": 1.5 + }, + "1997": { + "name": "Incomplete stew", + "weight": 1.0 + }, + "1999": { + "name": "Incomplete stew", + "weight": 1.0 + }, + "2001": { + "name": "Uncooked stew", + "weight": 1.5 + }, + "2003": { + "name": "Stew", + "weight": 1.5 + }, + "2005": { + "name": "Burnt stew" + }, + "2007": { + "name": "Spice", + "weight": 0.2 + }, + "2009": { + "name": "Uncooked curry", + "weight": 1.5 + }, + "2011": { + "name": "Curry", + "weight": 1.5 + }, + "2013": { + "name": "Burnt curry" + }, + "2015": { + "name": "Vodka", + "weight": 1.0 + }, + "2017": { + "name": "Whisky", + "weight": 1.0 + }, + "2019": { + "name": "Gin", + "weight": 1.0 + }, + "2021": { + "name": "Brandy", + "weight": 1.0 + }, + "2023": { + "name": "Cocktail guide", + "weight": 0.51 + }, + "2025": { + "name": "Cocktail shaker", + "weight": 0.15 + }, + "2026": { + "name": "Cocktail glass", + "weight": 0.1 + }, + "2028": { + "name": "Premade blurb' sp.", + "weight": 0.45 + }, + "2030": { + "name": "Premade choc s'dy", + "weight": 0.45 + }, + "2032": { + "name": "Premade dr' dragon", + "weight": 0.45 + }, + "2034": { + "name": "Premade fr' blast", + "weight": 0.45 + }, + "2036": { + "name": "Premade p' punch", + "weight": 0.45 + }, + "2038": { + "name": "Premade sgg", + "weight": 0.45 + }, + "2040": { + "name": "Premade wiz blz'd", + "weight": 0.45 + }, + "2048": { + "name": "Pineapple punch", + "weight": 0.5 + }, + "2054": { + "name": "Wizard blizzard", + "weight": 0.5 + }, + "2064": { + "name": "Blurberry special", + "weight": 0.5 + }, + "2074": { + "name": "Choc saturday", + "weight": 0.5 + }, + "2080": { + "name": "Short green guy", + "weight": 0.5 + }, + "2084": { + "name": "Fruit blast", + "weight": 0.5 + }, + "2092": { + "name": "Drunk dragon", + "weight": 0.5 + }, + "2102": { + "name": "Lemon", + "weight": 0.1 + }, + "2104": { + "name": "Lemon chunks", + "weight": 0.08 + }, + "2106": { + "name": "Lemon slices", + "weight": 0.08 + }, + "2108": { + "name": "Orange", + "weight": 0.11 + }, + "2110": { + "name": "Orange chunks", + "weight": 0.09 + }, + "2112": { + "name": "Orange slices", + "weight": 0.09 + }, + "2114": { + "name": "Pineapple", + "weight": 0.15 + }, + "2116": { + "name": "Pineapple chunks", + "weight": 0.12 + }, + "2118": { + "name": "Pineapple ring", + "weight": 0.03 + }, + "2120": { + "name": "Lime", + "weight": 0.1 + }, + "2122": { + "name": "Lime chunks", + "weight": 0.08 + }, + "2124": { + "name": "Lime slices" + }, + "2126": { + "name": "Dwellberries", + "weight": 0.014 + }, + "2128": { + "name": "Equa leaves", + "weight": 0.014 + }, + "2130": { + "name": "Pot of cream", + "weight": 0.2 + }, + "2132": { + "name": "Raw beef", + "weight": 0.34 + }, + "2134": { + "name": "Raw rat meat", + "weight": 0.141 + }, + "2136": { + "name": "Raw bear meat", + "weight": 0.425 + }, + "2138": { + "name": "Raw chicken", + "weight": 0.17 + }, + "2140": { + "name": "Cooked chicken", + "weight": 0.141 + }, + "2142": { + "name": "Cooked meat", + "weight": 0.283 + }, + "2144": { + "name": "Burnt chicken" + }, + "2146": { + "name": "Burnt meat" + }, + "2148": { + "name": "Raw lava eel", + "quest": true, + "weight": 0.226 + }, + "2149": { + "name": "Lava eel", + "quest": true, + "weight": 0.198 + }, + "2150": { + "name": "Swamp toad", + "weight": 0.5 + }, + "2152": { + "name": "Toad's legs", + "weight": 0.15 + }, + "2162": { + "name": "King worm", + "weight": 0.12 + }, + "2164": { + "name": "Batta tin", + "weight": 0.1 + }, + "2165": { + "name": "Crunchy tray", + "weight": 0.1 + }, + "2166": { + "name": "Gnomebowl mould", + "weight": 0.15 + }, + "2167": { + "name": "Gianne's cook book", + "weight": 0.51 + }, + "2169": { + "name": "Gnome spice", + "weight": 0.15 + }, + "2171": { + "name": "Gianne dough", + "weight": 0.5 + }, + "2175": { + "name": "Burnt gnomebowl" + }, + "2177": { + "name": "Half baked bowl", + "weight": 0.275 + }, + "2178": { + "name": "Raw gnomebowl", + "weight": 0.3 + }, + "2185": { + "name": "Chocolate bomb", + "weight": 0.35 + }, + "2187": { + "name": "Tangled toad's legs", + "weight": 0.35 + }, + "2191": { + "name": "Worm hole", + "weight": 0.35 + }, + "2195": { + "name": "Veg ball", + "weight": 0.35 + }, + "2199": { + "name": "Burnt crunchies" + }, + "2201": { + "name": "Half baked crunchy", + "weight": 0.35 + }, + "2202": { + "name": "Raw crunchies", + "weight": 0.4 + }, + "2203": { + "name": "Rock-climbing boots", + "weight": 0.3 + }, + "2205": { + "name": "Worm crunchies", + "weight": 0.25 + }, + "2209": { + "name": "Chocchip crunchies", + "weight": 0.2 + }, + "2213": { + "name": "Spicy crunchies", + "weight": 0.25 + }, + "2217": { + "name": "Toad crunchies", + "weight": 0.25 + }, + "2219": { + "name": "Premade w'm batta", + "weight": 0.25 + }, + "2221": { + "name": "Premade t'd batta", + "weight": 0.25 + }, + "2223": { + "name": "Premade c+t batta", + "weight": 0.25 + }, + "2225": { + "name": "Premade fr't batta", + "weight": 0.25 + }, + "2227": { + "name": "Premade veg batta", + "weight": 0.25 + }, + "2229": { + "name": "Premade choc bomb", + "weight": 0.35 + }, + "2231": { + "name": "Premade ttl", + "weight": 0.35 + }, + "2233": { + "name": "Premade worm hole", + "weight": 0.35 + }, + "2235": { + "name": "Premade veg ball", + "weight": 0.35 + }, + "2237": { + "name": "Premade w'm crun'", + "weight": 0.25 + }, + "2239": { + "name": "Premade ch' crunch", + "weight": 0.25 + }, + "2241": { + "name": "Premade s'y crunch", + "weight": 0.25 + }, + "2243": { + "name": "Premade t'd crunch" + }, + "2247": { + "name": "Burnt batta" + }, + "2249": { + "name": "Half baked batta", + "weight": 0.25 + }, + "2250": { + "name": "Raw batta", + "weight": 0.25 + }, + "2251": { + "name": "Unfinished batta", + "weight": 0.25 + }, + "2253": { + "name": "Worm batta", + "weight": 0.25 + }, + "2255": { + "name": "Toad batta", + "weight": 0.25 + }, + "2257": { + "name": "Unfinished batta", + "weight": 0.25 + }, + "2259": { + "name": "Cheese+tom batta", + "weight": 0.25 + }, + "2277": { + "name": "Fruit batta" + }, + "2279": { + "name": "Unfinished batta", + "weight": 0.25 + }, + "2281": { + "name": "Vegetable batta", + "weight": 0.25 + }, + "2283": { + "name": "Pizza base", + "weight": 0.1 + }, + "2285": { + "name": "Incomplete pizza", + "weight": 0.6 + }, + "2287": { + "name": "Uncooked pizza", + "weight": 0.8 + }, + "2289": { + "name": "Plain pizza", + "weight": 0.8 + }, + "2291": { + "name": "1/2 plain pizza", + "weight": 0.4 + }, + "2293": { + "name": "Meat pizza", + "weight": 0.9 + }, + "2295": { + "name": "1/2 meat pizza", + "weight": 0.45 + }, + "2297": { + "name": "Anchovy pizza", + "weight": 0.9 + }, + "2299": { + "name": "1/2 anchovy pizza", + "weight": 0.45 + }, + "2301": { + "name": "Pineapple pizza", + "weight": 0.9 + }, + "2303": { + "name": "1/2 pineapple pizza", + "weight": 0.45 + }, + "2305": { + "name": "Burnt pizza" + }, + "2307": { + "name": "Bread dough", + "weight": 0.6 + }, + "2309": { + "name": "Bread", + "weight": 0.5 + }, + "2311": { + "name": "Burnt bread" + }, + "2313": { + "name": "Pie dish", + "weight": 0.1 + }, + "2315": { + "name": "Pie shell", + "weight": 0.25 + }, + "2317": { + "name": "Uncooked apple pie", + "weight": 0.5 + }, + "2319": { + "name": "Uncooked meat pie", + "weight": 0.5 + }, + "2321": { + "name": "Uncooked berry pie", + "weight": 0.5 + }, + "2323": { + "name": "Apple pie", + "weight": 0.45 + }, + "2325": { + "name": "Redberry pie", + "weight": 0.45 + }, + "2327": { + "name": "Meat pie", + "weight": 0.45 + }, + "2329": { + "name": "Burnt pie" + }, + "2331": { + "name": "Half a meat pie", + "weight": 0.225 + }, + "2333": { + "name": "Half a redberry pie", + "weight": 0.225 + }, + "2335": { + "name": "Half an apple pie", + "weight": 0.225 + }, + "2337": { + "name": "Raw oomlie", + "weight": 0.225 + }, + "2339": { + "name": "Palm leaf", + "quest": true, + "weight": 0.1 + }, + "2340": { + "name": "Palm leaf", + "quest": true, + "weight": 0.1 + }, + "2341": { + "name": "Wrapped oomlie", + "quest": true, + "weight": 0.325 + }, + "2343": { + "name": "Cooked oomlie wrap", + "quest": true, + "weight": 0.3 + }, + "2345": { + "name": "Burnt oomlie wrap" + }, + "2347": { + "name": "Hammer", + "weight": 0.907 + }, + "2349": { + "name": "Bronze bar", + "weight": 1.814 + }, + "2351": { + "name": "Iron bar", + "weight": 1.814 + }, + "2353": { + "name": "Steel bar", + "weight": 1.814 + }, + "2355": { + "name": "Silver bar", + "weight": 1.814 + }, + "2357": { + "name": "Gold bar", + "weight": 1.814 + }, + "2359": { + "name": "Mithril bar", + "weight": 1.587 + }, + "2361": { + "name": "Adamantite bar", + "weight": 2.041 + }, + "2363": { + "name": "Runite bar", + "weight": 1.814 + }, + "2365": { + "name": "'perfect' gold bar", + "quest": true, + "weight": 1.814 + }, + "2366": { + "name": "Shield left half", + "weight": 2.721 + }, + "2368": { + "name": "Shield right half", + "weight": 2.721 + }, + "2370": { + "name": "Steel studs", + "weight": 1.36 + }, + "2372": { + "name": "Ogre relic", + "quest": true, + "weight": 3.0 + }, + "2373": { + "name": "Relic part 1", + "quest": true, + "weight": 1.0 + }, + "2374": { + "name": "Relic part 2", + "quest": true, + "weight": 1.0 + }, + "2375": { + "name": "Relic part 3", + "quest": true, + "weight": 1.0 + }, + "2376": { + "name": "Skavid map", + "quest": true, + "weight": 0.01 + }, + "2377": { + "name": "Ogre tooth", + "quest": true, + "weight": 0.01 + }, + "2378": { + "name": "Toban's key", + "quest": true, + "weight": 0.01 + }, + "2379": { + "name": "Rock cake", + "quest": true + }, + "2380": { + "name": "Crystal", + "quest": true, + "weight": 0.907 + }, + "2381": { + "name": "Crystal", + "quest": true, + "weight": 0.907 + }, + "2382": { + "name": "Crystal", + "quest": true, + "weight": 0.907 + }, + "2383": { + "name": "Crystal", + "quest": true, + "weight": 0.907 + }, + "2384": { + "name": "Fingernails", + "quest": true, + "weight": 0.002 + }, + "2385": { + "name": "Old robe", + "quest": true, + "weight": 1.814 + }, + "2386": { + "name": "Unusual armour", + "quest": true, + "weight": 3.628 + }, + "2387": { + "name": "Damaged dagger", + "quest": true, + "weight": 0.453 + }, + "2388": { + "name": "Tattered eye patch", + "quest": true, + "weight": 0.006 + }, + "2389": { + "name": "Vial", + "quest": true, + "weight": 0.015 + }, + "2390": { + "name": "Vial", + "quest": true, + "weight": 0.025 + }, + "2391": { + "name": "Ground bat bones", + "quest": true, + "weight": 0.1 + }, + "2393": { + "name": "Toban's gold", + "quest": true, + "weight": 1.814 + }, + "2394": { + "name": "Potion", + "quest": true, + "weight": 0.025 + }, + "2395": { + "name": "Magic ogre potion", + "quest": true, + "weight": 0.025 + }, + "2396": { + "name": "Spell scroll", + "quest": true + }, + "2397": { + "name": "Shaman robe", + "quest": true, + "weight": 1.814 + }, + "2398": { + "name": "Cave nightshade", + "weight": 0.015 + }, + "2399": { + "name": "Silverlight key", + "quest": true, + "weight": 1.0 + }, + "2400": { + "name": "Silverlight key", + "quest": true, + "weight": 1.0 + }, + "2401": { + "name": "Silverlight key", + "quest": true, + "weight": 1.0 + }, + "2402": { + "name": "Silverlight", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 14, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "dmagic": 1, + "str": 12, + "aspeed": 5 + } + }, + "2403": { + "name": "Hazeel scroll", + "quest": true, + "weight": 0.01 + }, + "2404": { + "name": "Chest key", + "quest": true, + "weight": 0.01 + }, + "2405": { + "name": "Carnillean armour", + "quest": true, + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 4, + "dstab": 20, + "dslash": 14, + "dcrush": 8 + } + }, + "2406": { + "name": "Hazeel's mark", + "quest": true, + "equipable": true, + "weight": 0.012, + "equipment": { + "slot": 2 + } + }, + "2407": { + "name": "Ball", + "quest": true, + "weight": 0.15 + }, + "2408": { + "name": "Diary", + "quest": true, + "weight": 0.51 + }, + "2409": { + "name": "Door key", + "quest": true, + "weight": 0.01 + }, + "2410": { + "name": "Magnet", + "quest": true, + "weight": 0.02 + }, + "2411": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "2412": { + "name": "Saradomin cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "amagic": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 10 + } + }, + "2413": { + "name": "Guthix cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 10 + } + }, + "2414": { + "name": "Zamorak cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "amagic": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 10 + } + }, + "2415": { + "name": "Saradomin staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 6, + "amagic": 6, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 6, + "str": 2, + "aspeed": 5 + } + }, + "2416": { + "name": "Guthix staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 6, + "amagic": 6, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 6, + "str": 2, + "aspeed": 5 + } + }, + "2417": { + "name": "Zamorak staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 6, + "amagic": 6, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 6, + "str": 2, + "aspeed": 5 + } + }, + "2418": { + "name": "Bronze key", + "quest": true, + "weight": 0.01 + }, + "2419": { + "name": "Wig", + "quest": true, + "weight": 0.01 + }, + "2421": { + "name": "Wig", + "quest": true, + "weight": 0.01 + }, + "2423": { + "name": "Key print", + "quest": true, + "weight": 0.01 + }, + "2424": { + "name": "Paste", + "quest": true, + "weight": 0.015 + }, + "2426": { + "name": "Burnt oomlie" + }, + "2428": { + "name": "Attack potion(4)", + "weight": 0.035 + }, + "2430": { + "name": "Restore potion(4)", + "weight": 0.035 + }, + "2432": { + "name": "Defence potion(4)", + "weight": 0.035 + }, + "2434": { + "name": "Prayer potion(4)", + "weight": 0.035 + }, + "2436": { + "name": "Super attack(4)", + "weight": 0.035 + }, + "2438": { + "name": "Fishing potion(4)", + "weight": 0.035 + }, + "2440": { + "name": "Super strength(4)", + "weight": 0.035 + }, + "2442": { + "name": "Super defence(4)", + "weight": 0.035 + }, + "2444": { + "name": "Ranging potion(4)", + "weight": 0.035 + }, + "2446": { + "name": "Antipoison(4)", + "weight": 0.035 + }, + "2448": { + "name": "Superantipoison(4)", + "weight": 0.035 + }, + "2450": { + "name": "Zamorak brew(4)", + "weight": 0.035 + }, + "2452": { + "name": "Antifire potion(4)", + "weight": 0.035 + }, + "2454": { + "name": "Antifire potion(3)", + "weight": 0.03 + }, + "2456": { + "name": "Antifire potion(2)", + "weight": 0.025 + }, + "2458": { + "name": "Antifire potion(1)", + "weight": 0.02 + }, + "2460": { + "name": "Assorted flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2462": { + "name": "Red flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2464": { + "name": "Blue flowers", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2466": { + "name": "Yellow flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2468": { + "name": "Purple flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2470": { + "name": "Orange flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2472": { + "name": "Mixed flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2474": { + "name": "White flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2476": { + "name": "Black flowers", + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "2481": { + "name": "Lantadyme" + }, + "2483": { + "name": "Lantadyme potion (unf)", + "weight": 0.056 + }, + "2485": { + "name": "Grimy lantadyme", + "weight": 0.007 + }, + "2487": { + "name": "Blue d'hide vamb", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 9, + "dstab": 4, + "dslash": 3, + "dcrush": 5, + "dmagic": 4 + } + }, + "2489": { + "name": "Red d'hide vamb", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 10, + "dstab": 5, + "dslash": 4, + "dcrush": 6, + "dmagic": 6 + } + }, + "2491": { + "name": "Black d'hide vamb", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8 + } + }, + "2493": { + "name": "Blue d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 11, + "dstab": 25, + "dslash": 19, + "dcrush": 27, + "dmagic": 14, + "drange": 25 + } + }, + "2495": { + "name": "Red d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 14, + "dstab": 28, + "dslash": 22, + "dcrush": 30, + "dmagic": 20, + "drange": 28 + } + }, + "2497": { + "name": "Black d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31 + } + }, + "2499": { + "name": "Blue d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 20, + "dstab": 45, + "dslash": 37, + "dcrush": 50, + "dmagic": 30, + "drange": 45 + } + }, + "2501": { + "name": "Red d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 25, + "dstab": 50, + "dslash": 42, + "dcrush": 55, + "dmagic": 40, + "drange": 50 + } + }, + "2503": { + "name": "Black d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55 + } + }, + "2505": { + "name": "Blue dragon leather", + "weight": 3.175 + }, + "2507": { + "name": "Red dragon leather", + "weight": 3.175 + }, + "2509": { + "name": "Black dragon leather", + "weight": 3.175 + }, + "2511": { + "name": "Logs", + "weight": 2.0 + }, + "2513": { + "name": "Dragon chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 81, + "dslash": 93, + "dcrush": 98, + "dmagic": -3, + "drange": 82 + } + }, + "2514": { + "name": "Raw shrimps", + "weight": 0.12 + }, + "2516": { + "name": "Pot of flour", + "weight": 1.36 + }, + "2518": { + "name": "Rotten tomato", + "weight": 0.08 + }, + "2520": { + "name": "Brown toy horsey", + "weight": 0.05 + }, + "2522": { + "name": "White toy horsey", + "weight": 0.05 + }, + "2524": { + "name": "Black toy horsey", + "weight": 0.05 + }, + "2526": { + "name": "Grey toy horsey", + "weight": 0.05 + }, + "2528": { + "name": "Lamp", + "weight": 0.1 + }, + "2529": { + "name": "Dead orb", + "quest": true, + "weight": 5.0 + }, + "2532": { + "name": "Iron fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "2533": { + "name": "Iron fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "2534": { + "name": "Steel fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "2535": { + "name": "Steel fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "2536": { + "name": "Mithril fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "2537": { + "name": "Mithril fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "2538": { + "name": "Adamant fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "2539": { + "name": "Adamant fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "2540": { + "name": "Rune fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "2541": { + "name": "Rune fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "2550": { + "name": "Ring of recoil", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2552": { + "name": "Ring of dueling(8)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2554": { + "name": "Ring of dueling(7)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2556": { + "name": "Ring of dueling(6)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2558": { + "name": "Ring of dueling(5)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2560": { + "name": "Ring of dueling(4)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2562": { + "name": "Ring of dueling(3)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2564": { + "name": "Ring of dueling(2)", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2566": { + "name": "Ring of dueling(1)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "2568": { + "name": "Ring of forging", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2570": { + "name": "Ring of life", + "equipable": true, + "weight": 0.006 + }, + "2572": { + "name": "Ring of wealth", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "2574": { + "name": "Sextant", + "weight": 0.2 + }, + "2575": { + "name": "Watch", + "weight": 0.1 + }, + "2576": { + "name": "Chart", + "weight": 0.01 + }, + "2577": { + "name": "Ranger boots", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 8, + "dstab": 2, + "dslash": 3, + "dcrush": 4, + "dmagic": 2 + } + }, + "2579": { + "name": "Wizard boots", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 10, + "amagic": 4, + "dmagic": 4 + } + }, + "2581": { + "name": "Robin hood hat", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 0, + "amagic": -10, + "arange": 8, + "dstab": 4, + "dslash": 6, + "dcrush": 8, + "dmagic": 4, + "drange": 4 + } + }, + "2583": { + "name": "Black platebody (t)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "2585": { + "name": "Black platelegs (t)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20 + } + }, + "2587": { + "name": "Black full helm (t)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "2589": { + "name": "Black kiteshield (t)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "2591": { + "name": "Black platebody (g)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "2593": { + "name": "Black platelegs (g)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20 + } + }, + "2595": { + "name": "Black full helm (g)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "2597": { + "name": "Black kiteshield (g)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "2599": { + "name": "Adamant platebody (t)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "2601": { + "name": "Adamant platelegs (t)", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "2603": { + "name": "Adamant kiteshield (t)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "2605": { + "name": "Adamant full helm (t)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "2607": { + "name": "Adamant platebody (g)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "2609": { + "name": "Adamant platelegs (g)", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "2611": { + "name": "Adamant kiteshield (g)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "2613": { + "name": "Adamant full helm (g)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "2615": { + "name": "Rune platebody (g)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "2617": { + "name": "Rune platelegs (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "2619": { + "name": "Rune full helm (g)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "2621": { + "name": "Rune kiteshield (g)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "2623": { + "name": "Rune platebody (t)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "2625": { + "name": "Rune platelegs (t)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "2627": { + "name": "Rune full helm (t)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "2629": { + "name": "Rune kiteshield (t)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "2631": { + "name": "Highwayman mask", + "equipable": true, + "weight": 0.02, + "equipment": { + "slot": 0 + } + }, + "2633": { + "name": "Blue beret", + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "2635": { + "name": "Black beret", + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "2637": { + "name": "White beret", + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "2639": { + "name": "Tan cavalier", + "equipable": true, + "weight": 0.08, + "equipment": { + "slot": 0 + } + }, + "2641": { + "name": "Dark cavalier", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 0 + } + }, + "2643": { + "name": "Black cavalier", + "equipable": true, + "weight": 0.08, + "equipment": { + "slot": 0 + } + }, + "2645": { + "name": "Red headband", + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "2647": { + "name": "Black headband", + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "2649": { + "name": "Brown headband", + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "2651": { + "name": "Pirate's hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "2653": { + "name": "Zamorak platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80, + "prayer": 1 + } + }, + "2655": { + "name": "Zamorak platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "2657": { + "name": "Zamorak full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30, + "prayer": 1 + } + }, + "2659": { + "name": "Zamorak kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46, + "prayer": 1 + } + }, + "2661": { + "name": "Saradomin platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80, + "prayer": 1 + } + }, + "2663": { + "name": "Saradomin platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "2665": { + "name": "Saradomin full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30, + "prayer": 1 + } + }, + "2667": { + "name": "Saradomin kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46, + "prayer": 1 + } + }, + "2669": { + "name": "Guthix platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80, + "prayer": 1 + } + }, + "2671": { + "name": "Guthix platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "2673": { + "name": "Guthix full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30, + "prayer": 1 + } + }, + "2675": { + "name": "Guthix kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46, + "prayer": 1 + } + }, + "2677": { + "name": "Clue scroll (easy)" + }, + "2678": { + "name": "Clue scroll (easy)" + }, + "2679": { + "name": "Clue scroll (easy)" + }, + "2680": { + "name": "Clue scroll (easy)" + }, + "2681": { + "name": "Clue scroll (easy)" + }, + "2682": { + "name": "Clue scroll (easy)" + }, + "2683": { + "name": "Clue scroll (easy)" + }, + "2684": { + "name": "Clue scroll (easy)" + }, + "2685": { + "name": "Clue scroll (easy)" + }, + "2686": { + "name": "Clue scroll (easy)" + }, + "2687": { + "name": "Clue scroll (easy)" + }, + "2688": { + "name": "Clue scroll (easy)" + }, + "2689": { + "name": "Clue scroll (easy)" + }, + "2690": { + "name": "Clue scroll (easy)" + }, + "2691": { + "name": "Clue scroll (easy)" + }, + "2692": { + "name": "Clue scroll (easy)" + }, + "2693": { + "name": "Clue scroll (easy)" + }, + "2694": { + "name": "Clue scroll (easy)" + }, + "2695": { + "name": "Clue scroll (easy)" + }, + "2696": { + "name": "Clue scroll (easy)" + }, + "2697": { + "name": "Clue scroll (easy)" + }, + "2698": { + "name": "Clue scroll (easy)" + }, + "2699": { + "name": "Clue scroll (easy)" + }, + "2700": { + "name": "Clue scroll (easy)" + }, + "2701": { + "name": "Clue scroll (easy)" + }, + "2702": { + "name": "Clue scroll (easy)" + }, + "2703": { + "name": "Clue scroll (easy)" + }, + "2704": { + "name": "Clue scroll (easy)" + }, + "2705": { + "name": "Clue scroll (easy)" + }, + "2706": { + "name": "Clue scroll (easy)" + }, + "2707": { + "name": "Clue scroll (easy)" + }, + "2708": { + "name": "Clue scroll (easy)" + }, + "2709": { + "name": "Clue scroll (easy)" + }, + "2710": { + "name": "Clue scroll (easy)" + }, + "2711": { + "name": "Clue scroll (easy)" + }, + "2712": { + "name": "Clue scroll (easy)" + }, + "2713": { + "name": "Clue scroll (easy)" + }, + "2716": { + "name": "Clue scroll (easy)" + }, + "2719": { + "name": "Clue scroll (easy)" + }, + "2722": { + "name": "Clue scroll (hard)" + }, + "2723": { + "name": "Clue scroll (hard)" + }, + "2725": { + "name": "Clue scroll (hard)" + }, + "2727": { + "name": "Clue scroll (hard)" + }, + "2729": { + "name": "Clue scroll (hard)" + }, + "2731": { + "name": "Clue scroll (hard)" + }, + "2733": { + "name": "Clue scroll (hard)" + }, + "2735": { + "name": "Clue scroll (hard)" + }, + "2737": { + "name": "Clue scroll (hard)" + }, + "2739": { + "name": "Clue scroll (hard)" + }, + "2741": { + "name": "Clue scroll (hard)" + }, + "2743": { + "name": "Clue scroll (hard)" + }, + "2745": { + "name": "Clue scroll (hard)" + }, + "2747": { + "name": "Clue scroll (hard)" + }, + "2773": { + "name": "Clue scroll (hard)" + }, + "2774": { + "name": "Clue scroll (hard)" + }, + "2776": { + "name": "Clue scroll (hard)" + }, + "2778": { + "name": "Clue scroll (hard)" + }, + "2780": { + "name": "Clue scroll (hard)" + }, + "2782": { + "name": "Clue scroll (hard)" + }, + "2783": { + "name": "Clue scroll (hard)" + }, + "2785": { + "name": "Clue scroll (hard)" + }, + "2786": { + "name": "Clue scroll (hard)" + }, + "2788": { + "name": "Clue scroll (hard)" + }, + "2790": { + "name": "Clue scroll (hard)" + }, + "2792": { + "name": "Clue scroll (hard)" + }, + "2793": { + "name": "Clue scroll (hard)" + }, + "2794": { + "name": "Clue scroll (hard)" + }, + "2795": { + "name": "Puzzle box (hard)" + }, + "2796": { + "name": "Clue scroll (hard)" + }, + "2797": { + "name": "Clue scroll (hard)" + }, + "2798": { + "name": "Puzzle box (hard)" + }, + "2799": { + "name": "Clue scroll (hard)" + }, + "2800": { + "name": "Puzzle box (hard)" + }, + "2801": { + "name": "Clue scroll (medium)" + }, + "2803": { + "name": "Clue scroll (medium)" + }, + "2805": { + "name": "Clue scroll (medium)" + }, + "2807": { + "name": "Clue scroll (medium)" + }, + "2809": { + "name": "Clue scroll (medium)" + }, + "2811": { + "name": "Clue scroll (medium)" + }, + "2813": { + "name": "Clue scroll (medium)" + }, + "2815": { + "name": "Clue scroll (medium)" + }, + "2817": { + "name": "Clue scroll (medium)" + }, + "2819": { + "name": "Clue scroll (medium)" + }, + "2821": { + "name": "Clue scroll (medium)" + }, + "2823": { + "name": "Clue scroll (medium)" + }, + "2825": { + "name": "Clue scroll (medium)" + }, + "2827": { + "name": "Clue scroll (medium)" + }, + "2829": { + "name": "Clue scroll (medium)" + }, + "2831": { + "name": "Clue scroll (medium)" + }, + "2832": { + "name": "Key (medium)" + }, + "2833": { + "name": "Clue scroll (medium)" + }, + "2834": { + "name": "Key (medium)" + }, + "2835": { + "name": "Clue scroll (medium)" + }, + "2836": { + "name": "Key (medium)" + }, + "2837": { + "name": "Clue scroll (medium)" + }, + "2838": { + "name": "Key (medium)" + }, + "2839": { + "name": "Clue scroll (medium)" + }, + "2840": { + "name": "Key (medium)" + }, + "2841": { + "name": "Clue scroll (medium)" + }, + "2842": { + "name": "Challenge scroll (medium)" + }, + "2843": { + "name": "Clue scroll (medium)" + }, + "2844": { + "name": "Challenge scroll (medium)" + }, + "2845": { + "name": "Clue scroll (medium)" + }, + "2846": { + "name": "Challenge scroll (medium)" + }, + "2847": { + "name": "Clue scroll (medium)" + }, + "2848": { + "name": "Clue scroll (medium)" + }, + "2849": { + "name": "Clue scroll (medium)" + }, + "2850": { + "name": "Challenge scroll (medium)" + }, + "2851": { + "name": "Clue scroll (medium)" + }, + "2852": { + "name": "Challenge scroll (medium)" + }, + "2853": { + "name": "Clue scroll (medium)" + }, + "2854": { + "name": "Challenge scroll (medium)" + }, + "2855": { + "name": "Clue scroll (medium)" + }, + "2856": { + "name": "Clue scroll (medium)" + }, + "2857": { + "name": "Clue scroll (medium)" + }, + "2858": { + "name": "Clue scroll (medium)" + }, + "2859": { + "name": "Wolf bones", + "weight": 0.5 + }, + "2861": { + "name": "Wolfbone arrowtips", + "quest": true + }, + "2862": { + "name": "Achey tree logs", + "weight": 1.36 + }, + "2864": { + "name": "Ogre arrow shaft" + }, + "2865": { + "name": "Flighted ogre arrow", + "quest": true + }, + "2866": { + "name": "Ogre arrow", + "quest": true, + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "2871": { + "name": "Ogre bellows", + "quest": true, + "weight": 0.51 + }, + "2872": { + "name": "Ogre bellows (3)", + "quest": true, + "weight": 0.5 + }, + "2873": { + "name": "Ogre bellows (2)", + "quest": true, + "weight": 0.51 + }, + "2874": { + "name": "Ogre bellows (1)", + "quest": true, + "weight": 0.51 + }, + "2875": { + "name": "Bloated toad", + "quest": true, + "weight": 0.75 + }, + "2876": { + "name": "Raw chompy", + "weight": 10.0 + }, + "2878": { + "name": "Cooked chompy", + "weight": 10.0 + }, + "2880": { + "name": "Ruined chompy" + }, + "2882": { + "name": "Seasoned chompy", + "quest": true, + "weight": 10.0 + }, + "2883": { + "name": "Ogre bow", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 38, + "aspeed": 8 + } + }, + "2886": { + "name": "Battered book", + "quest": true, + "weight": 0.113 + }, + "2887": { + "name": "Battered key", + "quest": true, + "weight": 0.01 + }, + "2888": { + "name": "A stone bowl", + "quest": true, + "weight": 0.141 + }, + "2889": { + "name": "A stone bowl", + "quest": true, + "weight": 0.141 + }, + "2890": { + "name": "Elemental shield", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 5, + "dmagic": 6 + } + }, + "2892": { + "name": "Elemental ore", + "quest": true, + "weight": 2.267 + }, + "2893": { + "name": "Elemental metal", + "quest": true, + "weight": 1.814 + }, + "2894": { + "name": "Grey boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "2896": { + "name": "Grey robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "2898": { + "name": "Grey robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "2900": { + "name": "Grey hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "2902": { + "name": "Grey gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "2904": { + "name": "Red boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "2906": { + "name": "Red robe top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "2908": { + "name": "Red robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "2910": { + "name": "Red hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "2912": { + "name": "Red gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "2914": { + "name": "Yellow boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "2916": { + "name": "Yellow robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "2918": { + "name": "Yellow robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "2920": { + "name": "Yellow hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "2922": { + "name": "Yellow gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "2924": { + "name": "Teal boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "2926": { + "name": "Teal robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "2928": { + "name": "Teal robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "2930": { + "name": "Teal hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "2932": { + "name": "Teal gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "2934": { + "name": "Purple boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "2936": { + "name": "Purple robe top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "2938": { + "name": "Purple robe bottoms", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "2940": { + "name": "Purple hat", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "2942": { + "name": "Purple gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "2944": { + "name": "Golden key", + "quest": true, + "weight": 0.01 + }, + "2945": { + "name": "Iron key", + "quest": true, + "weight": 0.01 + }, + "2946": { + "name": "Golden tinderbox", + "quest": true, + "weight": 0.035 + }, + "2947": { + "name": "Golden candle", + "quest": true, + "weight": 0.028 + }, + "2948": { + "name": "Golden pot", + "quest": true, + "weight": 0.453 + }, + "2949": { + "name": "Golden hammer", + "quest": true, + "weight": 0.907 + }, + "2950": { + "name": "Golden feather", + "quest": true, + "weight": 0.002 + }, + "2951": { + "name": "Golden needle", + "quest": true, + "weight": 0.001 + }, + "2952": { + "name": "Wolfbane", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 10, + "prayer": 5, + "aspeed": 4 + } + }, + "2953": { + "name": "Murky water", + "quest": true, + "weight": 3.0 + }, + "2954": { + "name": "Blessed water", + "quest": true, + "weight": 3.0 + }, + "2955": { + "name": "Moonlight mead", + "weight": 0.55 + }, + "2957": { + "name": "Druid pouch", + "quest": true + }, + "2958": { + "name": "Druid pouch", + "quest": true + }, + "2959": { + "name": "Rotten food", + "weight": 0.453 + }, + "2961": { + "name": "Silver sickle", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1, + "aspeed": 5 + } + }, + "2963": { + "name": "Silver sickle (b)", + "quest": true, + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1, + "prayer": 5, + "aspeed": 5 + } + }, + "2964": { + "name": "Washing bowl", + "quest": true, + "weight": 0.453 + }, + "2966": { + "name": "Mirror", + "quest": true, + "weight": 0.226 + }, + "2967": { + "name": "Journal", + "quest": true, + "weight": 0.51 + }, + "2968": { + "name": "Druidic spell", + "quest": true, + "weight": 0.02 + }, + "2969": { + "name": "A used spell", + "quest": true, + "weight": 0.02 + }, + "2970": { + "name": "Mort myre fungus", + "weight": 0.01 + }, + "2972": { + "name": "Mort myre stem", + "weight": 0.01 + }, + "2974": { + "name": "Mort myre pear", + "weight": 0.1 + }, + "2976": { + "name": "Sickle mould", + "weight": 0.453 + }, + "2978": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2979": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2980": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2981": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2982": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2983": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2984": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2985": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2986": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2987": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2988": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2989": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2990": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2991": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.33, + "equipment": { + "slot": 0 + } + }, + "2992": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2993": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2994": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2995": { + "name": "Chompy bird hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "2996": { + "name": "Agility arena ticket" + }, + "2997": { + "name": "Pirate's hook", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 9, + "dstab": 1, + "dslash": 5, + "dcrush": 3 + } + }, + "2998": { + "name": "Toadflax", + "weight": 0.007 + }, + "3000": { + "name": "Snapdragon", + "weight": 0.007 + }, + "3002": { + "name": "Toadflax potion (unf)", + "weight": 0.056 + }, + "3004": { + "name": "Snapdragon potion (unf)", + "weight": 0.056 + }, + "3008": { + "name": "Energy potion(4)", + "weight": 0.035 + }, + "3010": { + "name": "Energy potion(3)", + "weight": 0.03 + }, + "3012": { + "name": "Energy potion(2)", + "weight": 0.025 + }, + "3014": { + "name": "Energy potion(1)", + "weight": 0.02 + }, + "3016": { + "name": "Super energy(4)", + "weight": 0.035 + }, + "3018": { + "name": "Super energy(3)", + "weight": 0.03 + }, + "3020": { + "name": "Super energy(2)", + "weight": 0.025 + }, + "3022": { + "name": "Super energy(1)", + "weight": 0.02 + }, + "3024": { + "name": "Super restore(4)", + "weight": 0.035 + }, + "3026": { + "name": "Super restore(3)", + "weight": 0.03 + }, + "3028": { + "name": "Super restore(2)", + "weight": 0.025 + }, + "3030": { + "name": "Super restore(1)", + "weight": 0.02 + }, + "3032": { + "name": "Agility potion(4)", + "weight": 0.035 + }, + "3034": { + "name": "Agility potion(3)", + "weight": 0.03 + }, + "3036": { + "name": "Agility potion(2)", + "weight": 0.025 + }, + "3038": { + "name": "Agility potion(1)", + "weight": 0.02 + }, + "3040": { + "name": "Magic potion(4)", + "weight": 0.035 + }, + "3042": { + "name": "Magic potion(3)", + "weight": 0.03 + }, + "3044": { + "name": "Magic potion(2)", + "weight": 0.025 + }, + "3046": { + "name": "Magic potion(1)", + "weight": 0.02 + }, + "3049": { + "name": "Grimy toadflax", + "weight": 0.007 + }, + "3051": { + "name": "Grimy snapdragon", + "weight": 0.007 + }, + "3053": { + "name": "Lava battlestaff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "3054": { + "name": "Mystic lava staff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "3057": { + "name": "Mime mask", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 0 + } + }, + "3058": { + "name": "Mime top", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 4 + } + }, + "3059": { + "name": "Mime legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "3060": { + "name": "Mime gloves", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 9 + } + }, + "3061": { + "name": "Mime boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10 + } + }, + "3062": { + "name": "Strange box" + }, + "3093": { + "name": "Black dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 7, + "rstr": 6, + "aspeed": 3 + } + }, + "3094": { + "name": "Black dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 7, + "rstr": 6, + "aspeed": 3 + } + }, + "3095": { + "name": "Bronze claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 3, + "aslash": 4, + "acrush": -4, + "dstab": 1, + "dslash": 2, + "dcrush": 1, + "str": 5, + "aspeed": 4 + } + }, + "3096": { + "name": "Iron claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 6, + "acrush": -4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "str": 7, + "aspeed": 4 + } + }, + "3097": { + "name": "Steel claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 11, + "acrush": -4, + "dstab": 3, + "dslash": 6, + "dcrush": 2, + "str": 12, + "aspeed": 4 + } + }, + "3098": { + "name": "Black claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 14, + "acrush": -4, + "dstab": 4, + "dslash": 7, + "dcrush": 2, + "str": 14, + "aspeed": 4 + } + }, + "3099": { + "name": "Mithril claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 16, + "acrush": -4, + "dstab": 4, + "dslash": 8, + "dcrush": 2, + "str": 17, + "aspeed": 4 + } + }, + "3100": { + "name": "Adamant claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 18, + "aslash": 23, + "acrush": -4, + "dstab": 6, + "dslash": 12, + "dcrush": 3, + "str": 24, + "aspeed": 4 + } + }, + "3101": { + "name": "Rune claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 26, + "aslash": 38, + "acrush": -4, + "dstab": 10, + "dslash": 19, + "dcrush": 5, + "str": 39, + "aspeed": 4 + } + }, + "3102": { + "name": "Combination", + "quest": true, + "weight": 0.005 + }, + "3103": { + "name": "Iou", + "quest": true, + "weight": 0.005 + }, + "3104": { + "name": "Secret way map", + "quest": true, + "weight": 0.005 + }, + "3105": { + "name": "Climbing boots", + "quest": true, + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 2, + "dcrush": 2, + "str": 2 + } + }, + "3107": { + "name": "Spiked boots", + "quest": true, + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 2, + "dcrush": 2, + "str": 2 + } + }, + "3109": { + "name": "Stone ball", + "quest": true, + "weight": 3.628 + }, + "3110": { + "name": "Stone ball", + "quest": true, + "weight": 3.628 + }, + "3111": { + "name": "Stone ball", + "quest": true, + "weight": 3.628 + }, + "3112": { + "name": "Stone ball", + "quest": true, + "weight": 3.628 + }, + "3113": { + "name": "Stone ball", + "quest": true, + "weight": 3.628 + }, + "3114": { + "name": "Certificate", + "quest": true + }, + "3122": { + "name": "Granite shield", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 5, + "amagic": -12, + "arange": -8, + "dstab": 40, + "dslash": 42, + "dcrush": 38, + "drange": 65 + } + }, + "3123": { + "name": "Shaikahan bones", + "weight": 1.5 + }, + "3125": { + "name": "Jogre bones", + "weight": 0.8 + }, + "3127": { + "name": "Burnt jogre bones", + "weight": 0.8 + }, + "3128": { + "name": "Pasty jogre bones", + "quest": true, + "weight": 0.8 + }, + "3129": { + "name": "Pasty jogre bones", + "quest": true, + "weight": 0.8 + }, + "3130": { + "name": "Marinated j' bones", + "quest": true, + "weight": 0.8 + }, + "3131": { + "name": "Pasty jogre bones", + "quest": true, + "weight": 0.8 + }, + "3132": { + "name": "Pasty jogre bones", + "quest": true, + "weight": 0.8 + }, + "3133": { + "name": "Marinated j' bones", + "quest": true, + "weight": 0.8 + }, + "3135": { + "name": "Prison key", + "quest": true, + "weight": 0.055 + }, + "3136": { + "name": "Cell key 1", + "quest": true, + "weight": 0.055 + }, + "3137": { + "name": "Cell key 2", + "quest": true, + "weight": 0.055 + }, + "3138": { + "name": "Potato cactus", + "weight": 0.5 + }, + "3140": { + "name": "Dragon chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 81, + "dslash": 93, + "dcrush": 98, + "dmagic": -3, + "drange": 82 + } + }, + "3142": { + "name": "Raw karambwan", + "weight": 0.7 + }, + "3144": { + "name": "Cooked karambwan", + "weight": 0.5 + }, + "3146": { + "name": "Poison karambwan", + "weight": 0.65 + }, + "3148": { + "name": "Burnt karambwan" + }, + "3150": { + "name": "Raw karambwanji", + "weight": 0.14 + }, + "3152": { + "name": "Karambwan paste", + "quest": true, + "weight": 0.01 + }, + "3153": { + "name": "Karambwan paste", + "quest": true, + "weight": 0.01 + }, + "3154": { + "name": "Karambwan paste", + "quest": true, + "weight": 0.01 + }, + "3155": { + "name": "Karambwanji paste", + "quest": true, + "weight": 0.01 + }, + "3156": { + "name": "Karambwanji paste", + "quest": true, + "weight": 0.01 + }, + "3157": { + "name": "Karambwan vessel", + "quest": true, + "weight": 3.0 + }, + "3159": { + "name": "Karambwan vessel", + "quest": true, + "weight": 3.0 + }, + "3161": { + "name": "Crafting manual", + "quest": true + }, + "3162": { + "name": "Sliced banana", + "weight": 0.028 + }, + "3164": { + "name": "Karamjan rum", + "quest": true, + "weight": 0.907 + }, + "3165": { + "name": "Karamjan rum", + "weight": 1.0 + }, + "3166": { + "name": "Monkey corpse", + "quest": true, + "weight": 1.0 + }, + "3167": { + "name": "Monkey skin", + "quest": true, + "weight": 0.3 + }, + "3168": { + "name": "Seaweed sandwich", + "quest": true, + "weight": 0.5 + }, + "3169": { + "name": "Stuffed monkey", + "quest": true, + "weight": 1.2 + }, + "3170": { + "name": "Bronze spear(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": 1, + "dslash": 1, + "str": 6, + "aspeed": 5 + } + }, + "3171": { + "name": "Iron spear(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": 1, + "dslash": 1, + "str": 10, + "aspeed": 5 + } + }, + "3172": { + "name": "Steel spear(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "3173": { + "name": "Mithril spear(kp)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": 1, + "dslash": 1, + "str": 18, + "aspeed": 5 + } + }, + "3174": { + "name": "Adamant spear(kp)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": 1, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "3175": { + "name": "Rune spear(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "3176": { + "name": "Dragon spear(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5, + "str": 60, + "aspeed": 5 + } + }, + "3177": { + "name": "Left-handed banana", + "quest": true + }, + "3179": { + "name": "Monkey bones", + "quest": true, + "weight": 0.5 + }, + "3180": { + "name": "Monkey bones", + "quest": true, + "weight": 0.5 + }, + "3181": { + "name": "Monkey bones", + "weight": 0.8 + }, + "3182": { + "name": "Monkey bones", + "weight": 0.8 + }, + "3183": { + "name": "Monkey bones", + "weight": 0.5 + }, + "3185": { + "name": "Monkey bones", + "weight": 0.5 + }, + "3186": { + "name": "Monkey bones", + "weight": 0.5 + }, + "3187": { + "name": "Bones", + "weight": 0.5 + }, + "3188": { + "name": "Cleaning cloth", + "weight": 1.0 + }, + "3190": { + "name": "Bronze halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 8, + "amagic": -4, + "dstab": -1, + "dslash": 1, + "dcrush": 2, + "str": 8, + "aspeed": 7 + } + }, + "3192": { + "name": "Iron halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 12, + "amagic": -4, + "dstab": -1, + "dslash": 1, + "dcrush": 2, + "str": 12, + "aspeed": 7 + } + }, + "3194": { + "name": "Steel halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 14, + "aslash": 19, + "amagic": -4, + "dstab": -1, + "dslash": 1, + "dcrush": 2, + "str": 20, + "aspeed": 7 + } + }, + "3196": { + "name": "Black halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 19, + "aslash": 25, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 3, + "str": 20, + "aspeed": 7 + } + }, + "3198": { + "name": "Mithril halberd", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 22, + "aslash": 28, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 4, + "str": 29, + "aspeed": 7 + } + }, + "3200": { + "name": "Adamant halberd", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": 28, + "aslash": 41, + "amagic": -4, + "dstab": -1, + "dslash": 3, + "dcrush": 4, + "str": 42, + "aspeed": 7 + } + }, + "3202": { + "name": "Rune halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 48, + "aslash": 67, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 68, + "aspeed": 7 + } + }, + "3204": { + "name": "Dragon halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 70, + "aslash": 95, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 89, + "aspeed": 7 + } + }, + "3206": { + "name": "King's message", + "quest": true, + "weight": 0.056 + }, + "3207": { + "name": "Iorwerths message", + "quest": true, + "weight": 0.056 + }, + "3208": { + "name": "Crystal pendant", + "quest": true, + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2 + } + }, + "3209": { + "name": "Sulphur", + "quest": true, + "weight": 0.01 + }, + "3211": { + "name": "Limestone", + "weight": 2.267 + }, + "3213": { + "name": "Quicklime", + "quest": true, + "weight": 2.267 + }, + "3214": { + "name": "Pot of quicklime", + "quest": true, + "weight": 0.453 + }, + "3215": { + "name": "Ground sulphur", + "quest": true, + "weight": 0.056 + }, + "3216": { + "name": "Barrel", + "quest": true, + "weight": 10.0 + }, + "3218": { + "name": "Barrel bomb", + "quest": true, + "weight": 32.0 + }, + "3219": { + "name": "Barrel bomb", + "quest": true, + "weight": 32.0 + }, + "3220": { + "name": "Barrel of coal-tar", + "quest": true, + "weight": 32.0 + }, + "3221": { + "name": "Barrel of naphtha", + "quest": true, + "weight": 32.0 + }, + "3222": { + "name": "Naphtha mix", + "quest": true, + "weight": 32.0 + }, + "3223": { + "name": "Naphtha mix", + "quest": true, + "weight": 32.0 + }, + "3224": { + "name": "Strip of cloth", + "weight": 0.34 + }, + "3226": { + "name": "Raw rabbit", + "weight": 0.17 + }, + "3228": { + "name": "Cooked rabbit", + "weight": 0.141 + }, + "3230": { + "name": "Big book of bangs", + "quest": true, + "weight": 0.226 + }, + "3239": { + "name": "Bark", + "weight": 1.0 + }, + "3261": { + "name": "Goutweed", + "quest": true, + "weight": 0.007 + }, + "3262": { + "name": "Troll thistle", + "quest": true, + "weight": 0.001 + }, + "3263": { + "name": "Dried thistle", + "quest": true + }, + "3264": { + "name": "Ground thistle", + "quest": true, + "weight": 0.028 + }, + "3265": { + "name": "Troll potion", + "quest": true, + "weight": 0.056 + }, + "3266": { + "name": "Drunk parrot", + "quest": true, + "weight": 0.001 + }, + "3267": { + "name": "Dirty robe", + "quest": true, + "weight": 0.001 + }, + "3268": { + "name": "Fake man", + "quest": true, + "weight": 0.001 + }, + "3269": { + "name": "Storeroom key", + "quest": true, + "weight": 0.055 + }, + "3270": { + "name": "Alco-chunks", + "quest": true, + "weight": 0.08 + }, + "3325": { + "name": "Vampyre dust", + "weight": 0.056 + }, + "3327": { + "name": "Myre snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3329": { + "name": "Blood'n'tar snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3331": { + "name": "Ochre snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3333": { + "name": "Bruise blue snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3335": { + "name": "Broken bark snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3337": { + "name": "Myre snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3339": { + "name": "Blood'n'tar snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3341": { + "name": "Ochre snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3343": { + "name": "Bruise blue snelm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "3345": { + "name": "Blamish myre shell", + "weight": 10.0 + }, + "3347": { + "name": "Blamish red shell", + "weight": 10.0 + }, + "3349": { + "name": "Blamish ochre shell", + "weight": 10.0 + }, + "3351": { + "name": "Blamish blue shell", + "weight": 10.0 + }, + "3353": { + "name": "Blamish bark shell", + "weight": 10.0 + }, + "3355": { + "name": "Blamish myre shell", + "weight": 10.0 + }, + "3357": { + "name": "Blamish red shell", + "weight": 10.0 + }, + "3359": { + "name": "Blamish ochre shell", + "weight": 10.0 + }, + "3361": { + "name": "Blamish blue shell", + "weight": 10.0 + }, + "3363": { + "name": "Thin snail", + "weight": 2.0 + }, + "3365": { + "name": "Lean snail", + "weight": 2.0 + }, + "3367": { + "name": "Fat snail", + "weight": 2.0 + }, + "3369": { + "name": "Thin snail meat", + "weight": 3.0 + }, + "3371": { + "name": "Lean snail meat", + "weight": 4.0 + }, + "3373": { + "name": "Fat snail meat", + "weight": 5.0 + }, + "3375": { + "name": "Burnt snail" + }, + "3377": { + "name": "Sample bottle", + "weight": 0.02 + }, + "3379": { + "name": "Raw slimy eel", + "weight": 2.0 + }, + "3381": { + "name": "Cooked slimy eel", + "weight": 2.0 + }, + "3383": { + "name": "Burnt eel" + }, + "3385": { + "name": "Splitbark helm", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": -2, + "dstab": 10, + "dslash": 9, + "dcrush": 11, + "dmagic": 3 + } + }, + "3387": { + "name": "Splitbark body", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 10, + "arange": -10, + "dstab": 36, + "dslash": 26, + "dcrush": 42, + "dmagic": 15 + } + }, + "3389": { + "name": "Splitbark legs", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 7, + "amagic": 7, + "arange": -7, + "dstab": 22, + "dslash": 20, + "dcrush": 25, + "dmagic": 10 + } + }, + "3391": { + "name": "Splitbark gauntlets", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 9, + "amagic": 2, + "arange": -1, + "dstab": 3, + "dslash": 2, + "dcrush": 4, + "dmagic": 2 + } + }, + "3393": { + "name": "Splitbark boots", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 10, + "amagic": 2, + "arange": -1, + "dstab": 3, + "dslash": 2, + "dcrush": 4, + "dmagic": 2 + } + }, + "3395": { + "name": "Diary", + "quest": true, + "weight": 0.51 + }, + "3396": { + "name": "Loar remains" + }, + "3398": { + "name": "Phrin remains" + }, + "3400": { + "name": "Riyl remains" + }, + "3402": { + "name": "Asyn remains" + }, + "3404": { + "name": "Fiyr remains" + }, + "3406": { + "name": "Unfinished potion" + }, + "3408": { + "name": "Serum 207 (4)", + "quest": true, + "weight": 0.035 + }, + "3410": { + "name": "Serum 207 (3)", + "quest": true, + "weight": 0.03 + }, + "3412": { + "name": "Serum 207 (2)", + "quest": true, + "weight": 0.025 + }, + "3414": { + "name": "Serum 207 (1)", + "quest": true, + "weight": 0.02 + }, + "3416": { + "name": "Serum 208 (4)", + "quest": true, + "weight": 0.035 + }, + "3417": { + "name": "Serum 208 (3)", + "quest": true, + "weight": 0.03 + }, + "3418": { + "name": "Serum 208 (2)", + "quest": true, + "weight": 0.025 + }, + "3419": { + "name": "Serum 208 (1)", + "quest": true, + "weight": 0.02 + }, + "3420": { + "name": "Limestone brick", + "weight": 1.36 + }, + "3422": { + "name": "Olive oil(4)", + "weight": 0.035 + }, + "3424": { + "name": "Olive oil(3)", + "weight": 0.03 + }, + "3426": { + "name": "Olive oil(2)", + "weight": 0.025 + }, + "3428": { + "name": "Olive oil(1)", + "weight": 0.02 + }, + "3430": { + "name": "Sacred oil(4)", + "weight": 0.035 + }, + "3432": { + "name": "Sacred oil(3)", + "weight": 0.03 + }, + "3434": { + "name": "Sacred oil(2)", + "weight": 0.025 + }, + "3436": { + "name": "Sacred oil(1)", + "weight": 0.02 + }, + "3438": { + "name": "Pyre logs", + "weight": 1.36 + }, + "3440": { + "name": "Oak pyre logs", + "weight": 1.814 + }, + "3442": { + "name": "Willow pyre logs", + "weight": 1.36 + }, + "3444": { + "name": "Maple pyre logs", + "weight": 1.36 + }, + "3446": { + "name": "Yew pyre logs", + "weight": 1.36 + }, + "3448": { + "name": "Magic pyre logs", + "weight": 1.36 + }, + "3450": { + "name": "Bronze key red" + }, + "3451": { + "name": "Bronze key brown", + "weight": 0.01 + }, + "3452": { + "name": "Bronze key crimson", + "weight": 0.01 + }, + "3453": { + "name": "Bronze key black", + "weight": 0.01 + }, + "3454": { + "name": "Bronze key purple", + "weight": 0.01 + }, + "3455": { + "name": "Steel key red", + "weight": 0.01 + }, + "3456": { + "name": "Steel key brown", + "weight": 0.01 + }, + "3457": { + "name": "Steel key crimson", + "weight": 0.01 + }, + "3458": { + "name": "Steel key black", + "weight": 0.01 + }, + "3459": { + "name": "Steel key purple", + "weight": 0.01 + }, + "3460": { + "name": "Black key red", + "weight": 0.01 + }, + "3461": { + "name": "Black key brown", + "weight": 0.01 + }, + "3462": { + "name": "Black key crimson", + "weight": 0.01 + }, + "3463": { + "name": "Black key black", + "weight": 0.01 + }, + "3464": { + "name": "Black key purple", + "weight": 0.01 + }, + "3465": { + "name": "Silver key red", + "weight": 0.01 + }, + "3466": { + "name": "Silver key brown", + "weight": 0.01 + }, + "3467": { + "name": "Silver key crimson" + }, + "3468": { + "name": "Silver key black", + "weight": 0.01 + }, + "3469": { + "name": "Silver key purple", + "weight": 0.01 + }, + "3470": { + "name": "Fine cloth", + "weight": 1.0 + }, + "3472": { + "name": "Black plateskirt (t)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20 + } + }, + "3473": { + "name": "Black plateskirt (g)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20 + } + }, + "3474": { + "name": "Adamant plateskirt (t)", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "3475": { + "name": "Adamant plateskirt (g)", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "3476": { + "name": "Rune plateskirt (g)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "3477": { + "name": "Rune plateskirt (t)", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "3478": { + "name": "Zamorak plateskirt", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "3479": { + "name": "Saradomin plateskirt", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "3480": { + "name": "Guthix plateskirt", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "3481": { + "name": "Gilded platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "3483": { + "name": "Gilded platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "3485": { + "name": "Gilded plateskirt", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "3486": { + "name": "Gilded full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "3488": { + "name": "Gilded kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "3490": { + "name": "Clue scroll (easy)" + }, + "3491": { + "name": "Clue scroll (easy)" + }, + "3492": { + "name": "Clue scroll (easy)" + }, + "3493": { + "name": "Clue scroll (easy)" + }, + "3494": { + "name": "Clue scroll (easy)" + }, + "3495": { + "name": "Clue scroll (easy)" + }, + "3496": { + "name": "Clue scroll (easy)" + }, + "3497": { + "name": "Clue scroll (easy)" + }, + "3498": { + "name": "Clue scroll (easy)" + }, + "3499": { + "name": "Clue scroll (easy)" + }, + "3500": { + "name": "Clue scroll (easy)" + }, + "3501": { + "name": "Clue scroll (easy)" + }, + "3502": { + "name": "Clue scroll (easy)" + }, + "3503": { + "name": "Clue scroll (easy)" + }, + "3504": { + "name": "Clue scroll (easy)" + }, + "3505": { + "name": "Clue scroll (easy)" + }, + "3506": { + "name": "Clue scroll (easy)" + }, + "3507": { + "name": "Clue scroll (easy)" + }, + "3508": { + "name": "Clue scroll (easy)" + }, + "3509": { + "name": "Clue scroll (easy)" + }, + "3510": { + "name": "Clue scroll (easy)" + }, + "3512": { + "name": "Clue scroll (easy)" + }, + "3513": { + "name": "Clue scroll (easy)" + }, + "3514": { + "name": "Clue scroll (easy)" + }, + "3515": { + "name": "Clue scroll (easy)" + }, + "3516": { + "name": "Clue scroll (easy)" + }, + "3518": { + "name": "Clue scroll (easy)" + }, + "3520": { + "name": "Clue scroll (hard)" + }, + "3522": { + "name": "Clue scroll (hard)" + }, + "3524": { + "name": "Clue scroll (hard)" + }, + "3525": { + "name": "Clue scroll (hard)" + }, + "3526": { + "name": "Clue scroll (hard)" + }, + "3528": { + "name": "Clue scroll (hard)" + }, + "3530": { + "name": "Clue scroll (hard)" + }, + "3532": { + "name": "Clue scroll (hard)" + }, + "3534": { + "name": "Clue scroll (hard)" + }, + "3536": { + "name": "Clue scroll (hard)" + }, + "3538": { + "name": "Clue scroll (hard)" + }, + "3540": { + "name": "Clue scroll (hard)" + }, + "3542": { + "name": "Clue scroll (hard)" + }, + "3544": { + "name": "Clue scroll (hard)" + }, + "3546": { + "name": "Clue scroll (hard)" + }, + "3548": { + "name": "Clue scroll (hard)" + }, + "3550": { + "name": "Clue scroll (hard)" + }, + "3552": { + "name": "Clue scroll (hard)" + }, + "3554": { + "name": "Clue scroll (hard)" + }, + "3556": { + "name": "Clue scroll (hard)" + }, + "3558": { + "name": "Clue scroll (hard)" + }, + "3560": { + "name": "Clue scroll (hard)" + }, + "3562": { + "name": "Clue scroll (hard)" + }, + "3564": { + "name": "Clue scroll (hard)" + }, + "3565": { + "name": "Puzzle box (hard)" + }, + "3566": { + "name": "Clue scroll (hard)" + }, + "3567": { + "name": "Puzzle box (hard)" + }, + "3568": { + "name": "Clue scroll (hard)" + }, + "3569": { + "name": "Puzzle box (hard)" + }, + "3570": { + "name": "Clue scroll (hard)" + }, + "3571": { + "name": "Puzzle box (hard)" + }, + "3572": { + "name": "Clue scroll (hard)" + }, + "3573": { + "name": "Clue scroll (hard)" + }, + "3574": { + "name": "Clue scroll (hard)" + }, + "3575": { + "name": "Clue scroll (hard)" + }, + "3576": { + "name": "Puzzle box (hard)" + }, + "3577": { + "name": "Clue scroll (hard)" + }, + "3578": { + "name": "Puzzle box (hard)" + }, + "3579": { + "name": "Clue scroll (hard)" + }, + "3580": { + "name": "Clue scroll (hard)" + }, + "3582": { + "name": "Clue scroll (medium)" + }, + "3584": { + "name": "Clue scroll (medium)" + }, + "3586": { + "name": "Clue scroll (medium)" + }, + "3588": { + "name": "Clue scroll (medium)" + }, + "3590": { + "name": "Clue scroll (medium)" + }, + "3592": { + "name": "Clue scroll (medium)" + }, + "3594": { + "name": "Clue scroll (medium)" + }, + "3596": { + "name": "Clue scroll (medium)" + }, + "3598": { + "name": "Clue scroll (medium)" + }, + "3599": { + "name": "Clue scroll (medium)" + }, + "3601": { + "name": "Clue scroll (medium)" + }, + "3602": { + "name": "Clue scroll (medium)" + }, + "3604": { + "name": "Clue scroll (medium)" + }, + "3605": { + "name": "Clue scroll (medium)" + }, + "3606": { + "name": "Key (medium)" + }, + "3607": { + "name": "Clue scroll (medium)" + }, + "3608": { + "name": "Key (medium)" + }, + "3609": { + "name": "Clue scroll (medium)" + }, + "3610": { + "name": "Clue scroll (medium)" + }, + "3611": { + "name": "Clue scroll (medium)" + }, + "3612": { + "name": "Clue scroll (medium)" + }, + "3613": { + "name": "Clue scroll (medium)" + }, + "3614": { + "name": "Clue scroll (medium)" + }, + "3615": { + "name": "Clue scroll (medium)" + }, + "3616": { + "name": "Clue scroll (medium)" + }, + "3617": { + "name": "Clue scroll (medium)" + }, + "3618": { + "name": "Clue scroll (medium)" + }, + "3678": { + "name": "Flamtaer hammer", + "quest": true, + "weight": 1.36 + }, + "3688": { + "name": "Unstrung lyre", + "quest": true, + "weight": 1.0 + }, + "3689": { + "name": "Lyre", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "3690": { + "name": "Enchanted lyre", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "3691": { + "name": "Enchanted lyre(1)", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "3692": { + "name": "Branch", + "quest": true, + "weight": 1.814 + }, + "3693": { + "name": "Golden fleece", + "quest": true, + "weight": 0.012 + }, + "3694": { + "name": "Golden wool", + "quest": true, + "weight": 0.012 + }, + "3695": { + "name": "Pet rock", + "quest": true, + "equipable": true, + "weight": 1.0 + }, + "3696": { + "name": "Hunters' talisman", + "quest": true + }, + "3697": { + "name": "Hunters' talisman", + "quest": true + }, + "3698": { + "name": "Exotic flower", + "quest": true, + "weight": 0.028 + }, + "3699": { + "name": "Fremennik ballad", + "quest": true, + "weight": 0.005 + }, + "3700": { + "name": "Sturdy boots", + "quest": true, + "weight": 0.34 + }, + "3701": { + "name": "Tracking map", + "quest": true, + "weight": 0.51 + }, + "3702": { + "name": "Custom bow string", + "quest": true, + "weight": 0.014 + }, + "3703": { + "name": "Unusual fish", + "quest": true, + "weight": 0.4 + }, + "3704": { + "name": "Sea fishing map", + "quest": true, + "weight": 0.51 + }, + "3705": { + "name": "Weather forecast", + "quest": true + }, + "3706": { + "name": "Champions token", + "quest": true, + "weight": 0.004 + }, + "3707": { + "name": "Legendary cocktail", + "quest": true, + "weight": 0.45 + }, + "3708": { + "name": "Fiscal statement", + "quest": true, + "weight": 0.005 + }, + "3709": { + "name": "Promissory note", + "quest": true, + "weight": 0.005 + }, + "3710": { + "name": "Warriors' contract", + "quest": true, + "weight": 0.005 + }, + "3711": { + "name": "Keg of beer", + "quest": true, + "weight": 20.0 + }, + "3712": { + "name": "Low alcohol keg", + "quest": true, + "weight": 20.0 + }, + "3713": { + "name": "Strange object", + "quest": true, + "weight": 0.001 + }, + "3714": { + "name": "Lit strange object", + "quest": true, + "weight": 0.001 + }, + "3718": { + "name": "Magnet", + "quest": true, + "weight": 0.02 + }, + "3719": { + "name": "Blue thread", + "quest": true, + "weight": 0.002 + }, + "3720": { + "name": "Small pick", + "quest": true, + "weight": 0.056 + }, + "3721": { + "name": "Toy ship", + "quest": true, + "weight": 0.4 + }, + "3722": { + "name": "Full bucket", + "quest": true + }, + "3723": { + "name": "4/5ths full bucket", + "quest": true, + "weight": 0.001 + }, + "3724": { + "name": "3/5ths full bucket", + "quest": true, + "weight": 0.001 + }, + "3725": { + "name": "2/5ths full bucket", + "quest": true, + "weight": 0.001 + }, + "3726": { + "name": "1/5ths full bucket", + "quest": true, + "weight": 0.001 + }, + "3727": { + "name": "Empty bucket", + "quest": true, + "weight": 0.001 + }, + "3728": { + "name": "Frozen bucket", + "quest": true, + "weight": 0.001 + }, + "3729": { + "name": "Full jug", + "quest": true, + "weight": 0.001 + }, + "3730": { + "name": "2/3rds full jug", + "quest": true, + "weight": 0.001 + }, + "3731": { + "name": "1/3rds full jug", + "quest": true, + "weight": 0.001 + }, + "3732": { + "name": "Empty jug", + "quest": true, + "weight": 0.001 + }, + "3733": { + "name": "Frozen jug", + "quest": true, + "weight": 0.453 + }, + "3734": { + "name": "Vase", + "quest": true, + "weight": 0.001 + }, + "3735": { + "name": "Vase of water", + "quest": true, + "weight": 0.001 + }, + "3736": { + "name": "Frozen vase", + "quest": true, + "weight": 0.001 + }, + "3737": { + "name": "Vase lid", + "quest": true, + "weight": 0.001 + }, + "3738": { + "name": "Sealed vase", + "quest": true, + "weight": 0.001 + }, + "3739": { + "name": "Sealed vase", + "quest": true, + "weight": 0.001 + }, + "3740": { + "name": "Sealed vase", + "quest": true, + "weight": 0.001 + }, + "3741": { + "name": "Frozen key", + "quest": true, + "weight": 0.001 + }, + "3742": { + "name": "Red herring", + "quest": true, + "weight": 0.5 + }, + "3743": { + "name": "Red disk", + "quest": true, + "weight": 0.002 + }, + "3744": { + "name": "Wooden disk", + "quest": true, + "weight": 0.002 + }, + "3745": { + "name": "Seer's key", + "quest": true, + "weight": 0.01 + }, + "3746": { + "name": "Sticky red goop", + "quest": true, + "weight": 0.001 + }, + "3748": { + "name": "Fremennik helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "3749": { + "name": "Archer helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": -5, + "arange": 6, + "dstab": 6, + "dslash": 8, + "dcrush": 10, + "dmagic": 6, + "drange": 6 + } + }, + "3751": { + "name": "Berserker helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -5, + "dstab": 31, + "dslash": 29, + "dcrush": 33, + "drange": 30, + "str": 3 + } + }, + "3753": { + "name": "Warrior helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "aslash": 5, + "amagic": -5, + "arange": -5, + "dstab": 31, + "dslash": 33, + "dcrush": 29, + "drange": 30 + } + }, + "3755": { + "name": "Farseer helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": 6, + "arange": -5, + "dstab": 8, + "dslash": 10, + "dcrush": 12, + "dmagic": 6 + } + }, + "3757": { + "name": "Fremennik blade", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 6, + "aslash": 29, + "acrush": -2, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "3758": { + "name": "Fremennik shield", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "3759": { + "name": "Fremennik cyan cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3761": { + "name": "Fremennik brown cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3763": { + "name": "Fremennik blue cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3765": { + "name": "Fremennik green cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3767": { + "name": "Fremennik brown shirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "3769": { + "name": "Fremennik grey shirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "3771": { + "name": "Fremennik beige shirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "3773": { + "name": "Fremennik red shirt", + "equipable": true, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "3775": { + "name": "Fremennik blue shirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "3777": { + "name": "Fremennik red cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3779": { + "name": "Fremennik grey cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3781": { + "name": "Fremennik yellow cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3783": { + "name": "Fremennik teal cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3785": { + "name": "Fremennik purple cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3787": { + "name": "Fremennik pink cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3789": { + "name": "Fremennik black cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "3791": { + "name": "Fremennik boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "3793": { + "name": "Fremennik robe", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "3795": { + "name": "Fremennik skirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "3797": { + "name": "Fremennik hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "3799": { + "name": "Fremennik gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "3801": { + "name": "Keg of beer", + "weight": 20.0 + }, + "3803": { + "name": "Beer tankard", + "weight": 0.55 + }, + "3805": { + "name": "Tankard", + "weight": 0.05 + }, + "3827": { + "name": "Saradomin page 1" + }, + "3828": { + "name": "Saradomin page 2" + }, + "3829": { + "name": "Saradomin page 3" + }, + "3830": { + "name": "Saradomin page 4" + }, + "3831": { + "name": "Zamorak page 1" + }, + "3832": { + "name": "Zamorak page 2" + }, + "3833": { + "name": "Zamorak page 3" + }, + "3834": { + "name": "Zamorak page 4" + }, + "3835": { + "name": "Guthix page 1" + }, + "3836": { + "name": "Guthix page 2" + }, + "3837": { + "name": "Guthix page 3" + }, + "3838": { + "name": "Guthix page 4" + }, + "3839": { + "name": "Damaged book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "prayer": 5 + } + }, + "3840": { + "name": "Holy book", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "dstab": 8, + "dslash": 8, + "dcrush": 8, + "dmagic": 8, + "drange": 8, + "prayer": 5 + } + }, + "3841": { + "name": "Damaged book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "prayer": 5 + } + }, + "3842": { + "name": "Unholy book", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "astab": 8, + "aslash": 8, + "acrush": 8, + "amagic": 8, + "arange": 8, + "prayer": 5 + } + }, + "3843": { + "name": "Damaged book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "prayer": 5 + } + }, + "3844": { + "name": "Book of balance", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 4, + "arange": 4, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 5 + } + }, + "3845": { + "name": "Journal", + "quest": true, + "weight": 0.51 + }, + "3846": { + "name": "Diary", + "quest": true, + "weight": 0.51 + }, + "3847": { + "name": "Manual", + "quest": true, + "weight": 0.51 + }, + "3848": { + "name": "Lighthouse key", + "quest": true, + "weight": 0.01 + }, + "3849": { + "name": "Rusty casket", + "quest": true, + "weight": 5.0 + }, + "3853": { + "name": "Games necklace(8)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3855": { + "name": "Games necklace(7)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3857": { + "name": "Games necklace(6)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3859": { + "name": "Games necklace(5)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3861": { + "name": "Games necklace(4)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3863": { + "name": "Games necklace(3)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3865": { + "name": "Games necklace(2)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3867": { + "name": "Games necklace(1)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "3894": { + "name": "Awful anthem", + "quest": true, + "weight": 0.005 + }, + "3895": { + "name": "Good anthem", + "quest": true, + "weight": 0.005 + }, + "3896": { + "name": "Treaty", + "quest": true, + "weight": 0.005 + }, + "3897": { + "name": "Giant nib", + "quest": true, + "weight": 0.035 + }, + "3898": { + "name": "Giant pen", + "quest": true, + "weight": 0.035 + }, + "3899": { + "name": "Iron sickle", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1, + "aspeed": 5 + } + }, + "3901": { + "name": "Ghrim's book", + "weight": 1.0 + }, + "4001": { + "name": "Hardy gout tuber", + "quest": true, + "weight": 0.1 + }, + "4002": { + "name": "Spare controls", + "quest": true, + "weight": 0.2 + }, + "4004": { + "name": "Gnome royal seal", + "quest": true, + "weight": 0.02 + }, + "4005": { + "name": "Narnode's orders", + "quest": true, + "weight": 0.02 + }, + "4006": { + "name": "Monkey dentures", + "quest": true, + "weight": 0.2 + }, + "4007": { + "name": "Enchanted bar", + "quest": true, + "weight": 1.814 + }, + "4008": { + "name": "Eye of gnome", + "weight": 1.0 + }, + "4009": { + "name": "Eye of gnome", + "weight": 1.0 + }, + "4012": { + "name": "Monkey nuts", + "quest": true, + "weight": 0.007 + }, + "4014": { + "name": "Monkey bar", + "weight": 0.15 + }, + "4016": { + "name": "Banana stew", + "weight": 0.25 + }, + "4020": { + "name": "M'amulet mould", + "quest": true, + "weight": 0.007 + }, + "4021": { + "name": "M'speak amulet", + "quest": true, + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 2 + } + }, + "4022": { + "name": "M'speak amulet", + "quest": true, + "weight": 1.36 + }, + "4023": { + "name": "Monkey talisman", + "quest": true, + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "4024": { + "name": "Ninja monkey greegree", + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 3 + } + }, + "4025": { + "name": "Ninja monkey greegree", + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 3 + } + }, + "4026": { + "name": "Gorilla greegree", + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 3 + } + }, + "4027": { + "name": "Bearded gorilla greegree", + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 3 + } + }, + "4028": { + "name": "Ancient gorilla greegree", + "equipable": true, + "equipment": { + "slot": 3 + } + }, + "4029": { + "name": "Zombie monkey greegree", + "equipable": true, + "equipment": { + "slot": 3 + } + }, + "4030": { + "name": "Zombie monkey greegree", + "equipable": true, + "equipment": { + "slot": 3 + } + }, + "4031": { + "name": "Karamjan monkey greegree", + "quest": true, + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 3 + } + }, + "4033": { + "name": "Monkey", + "quest": true, + "weight": 15.0 + }, + "4034": { + "name": "Monkey skull", + "weight": 0.5 + }, + "4035": { + "name": "10th squad sigil", + "quest": true, + "equipable": true, + "weight": 0.085, + "equipment": { + "slot": 2 + } + }, + "4037": { + "name": "Saradomin banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "4039": { + "name": "Zamorak banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "4041": { + "name": "Hooded cloak", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1 + } + }, + "4042": { + "name": "Hooded cloak", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1 + } + }, + "4043": { + "name": "Rock", + "weight": 5.0 + }, + "4045": { + "name": "Explosive potion", + "weight": 0.035 + }, + "4047": { + "name": "Climbing rope", + "weight": 1.36 + }, + "4049": { + "name": "Bandages", + "weight": 0.001 + }, + "4051": { + "name": "Toolkit", + "weight": 0.001 + }, + "4053": { + "name": "Barricade", + "weight": 5.0 + }, + "4055": { + "name": "Castlewars manual", + "weight": 0.51 + }, + "4067": { + "name": "Castle wars ticket" + }, + "4068": { + "name": "Decorative sword", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 14, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 16, + "aspeed": 5 + } + }, + "4069": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.618, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 32, + "dslash": 31, + "dcrush": 24, + "dmagic": -6, + "drange": 31 + } + }, + "4070": { + "name": "Decorative armour", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "4071": { + "name": "Decorative helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "4072": { + "name": "Decorative shield", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "4073": { + "name": "Damp tinderbox", + "weight": 0.035 + }, + "4075": { + "name": "Glowing fungus", + "quest": true, + "weight": 0.056 + }, + "4077": { + "name": "Crystal-mine key", + "quest": true, + "weight": 0.01 + }, + "4078": { + "name": "Zealot's key", + "quest": true, + "weight": 0.01 + }, + "4079": { + "name": "Yo-yo" + }, + "4081": { + "name": "Salve amulet", + "quest": true, + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "prayer": 3 + } + }, + "4082": { + "name": "Salve shard", + "quest": true, + "weight": 0.007 + }, + "4083": { + "name": "Sled", + "quest": true, + "weight": 0.018 + }, + "4084": { + "name": "Sled", + "quest": true, + "weight": 0.018 + }, + "4085": { + "name": "Wax", + "quest": true, + "weight": 0.025 + }, + "4086": { + "name": "Trollweiss", + "quest": true, + "equipable": true, + "weight": 0.028, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 5 + } + }, + "4087": { + "name": "Dragon platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 68, + "dslash": 66, + "dcrush": 63, + "dmagic": -4, + "drange": 65 + } + }, + "4089": { + "name": "Mystic hat", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "4091": { + "name": "Mystic robe top", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "4093": { + "name": "Mystic robe bottom", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "4095": { + "name": "Mystic gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "amagic": 3, + "dmagic": 3 + } + }, + "4097": { + "name": "Mystic boots", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 10, + "amagic": 3, + "dmagic": 3 + } + }, + "4099": { + "name": "Mystic hat (dark)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "4101": { + "name": "Mystic robe top (dark)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "4103": { + "name": "Mystic robe bottom (dark)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "4105": { + "name": "Mystic gloves (dark)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "amagic": 3, + "dmagic": 3 + } + }, + "4107": { + "name": "Mystic boots (dark)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 10, + "amagic": 3, + "dmagic": 3 + } + }, + "4109": { + "name": "Mystic hat (light)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "4111": { + "name": "Mystic robe top (light)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "4113": { + "name": "Mystic robe bottom (light)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "4115": { + "name": "Mystic gloves (light)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "amagic": 3, + "dmagic": 3 + } + }, + "4117": { + "name": "Mystic boots (light)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 10, + "amagic": 3, + "dmagic": 3 + } + }, + "4119": { + "name": "Bronze boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 1, + "dslash": 2, + "dcrush": 3 + } + }, + "4121": { + "name": "Iron boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 2, + "dslash": 3, + "dcrush": 4 + } + }, + "4123": { + "name": "Steel boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 5, + "dslash": 6, + "dcrush": 7 + } + }, + "4125": { + "name": "Black boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 9 + } + }, + "4127": { + "name": "Mithril boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 8, + "dslash": 9, + "dcrush": 10 + } + }, + "4129": { + "name": "Adamant boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 10, + "dslash": 11, + "dcrush": 12, + "str": 1 + } + }, + "4131": { + "name": "Rune boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 12, + "dslash": 13, + "dcrush": 14, + "str": 2 + } + }, + "4151": { + "name": "Abyssal whip", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "aslash": 82, + "str": 82, + "aspeed": 4 + } + }, + "4153": { + "name": "Granite maul", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 3, + "acrush": 81, + "str": 79, + "aspeed": 7 + } + }, + "4155": { + "name": "Enchanted gem", + "weight": 0.002 + }, + "4156": { + "name": "Mirror shield", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 5, + "dstab": 10, + "dslash": 15, + "dcrush": 5, + "dmagic": 5, + "drange": 10 + } + }, + "4158": { + "name": "Leaf-bladed spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 47, + "aslash": 42, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 50, + "aspeed": 5 + } + }, + "4160": { + "name": "Broad arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 28 + } + }, + "4161": { + "name": "Bag of salt" + }, + "4162": { + "name": "Rock hammer", + "weight": 2.267 + }, + "4164": { + "name": "Facemask", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "4166": { + "name": "Earmuffs", + "equipable": true, + "weight": 0.113, + "equipment": { + "slot": 0 + } + }, + "4168": { + "name": "Nose peg", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 0 + } + }, + "4170": { + "name": "Slayer's staff", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 12, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 4 + } + }, + "4179": { + "name": "Stick", + "weight": 0.01 + }, + "4183": { + "name": "Star amulet", + "quest": true, + "weight": 0.01 + }, + "4184": { + "name": "Cavern key", + "quest": true, + "weight": 0.005 + }, + "4185": { + "name": "Tower key", + "quest": true, + "weight": 0.005 + }, + "4186": { + "name": "Shed key", + "quest": true, + "weight": 0.005 + }, + "4187": { + "name": "Marble amulet", + "quest": true, + "weight": 0.005 + }, + "4188": { + "name": "Obsidian amulet", + "quest": true, + "weight": 0.005 + }, + "4189": { + "name": "Garden cane", + "quest": true, + "weight": 0.1 + }, + "4190": { + "name": "Garden brush", + "quest": true, + "weight": 0.8 + }, + "4191": { + "name": "Extended brush", + "quest": true, + "weight": 0.9 + }, + "4192": { + "name": "Extended brush", + "quest": true, + "weight": 0.9 + }, + "4193": { + "name": "Extended brush", + "quest": true, + "weight": 0.9 + }, + "4194": { + "name": "Torso", + "quest": true, + "weight": 19.05 + }, + "4195": { + "name": "Arms", + "quest": true, + "weight": 6.35 + }, + "4196": { + "name": "Legs", + "quest": true, + "weight": 6.35 + }, + "4197": { + "name": "Decapitated head", + "quest": true, + "weight": 2.721 + }, + "4198": { + "name": "Decapitated head", + "quest": true, + "weight": 2.721 + }, + "4199": { + "name": "Pickled brain", + "quest": true, + "weight": 0.907 + }, + "4200": { + "name": "Conductor mould", + "quest": true, + "weight": 0.05 + }, + "4201": { + "name": "Conductor", + "quest": true, + "weight": 3.628 + }, + "4202": { + "name": "Ring of charos", + "quest": true, + "equipable": true, + "weight": 0.005 + }, + "4203": { + "name": "Journal", + "quest": true, + "weight": 0.01 + }, + "4204": { + "name": "Letter", + "quest": true, + "weight": 0.001 + }, + "4205": { + "name": "Consecration seed", + "quest": true, + "weight": 0.014 + }, + "4206": { + "name": "Consecration seed", + "quest": true, + "weight": 0.014 + }, + "4207": { + "name": "Crystal seed", + "quest": true, + "weight": 0.014 + }, + "4209": { + "name": "Cadarn lineage", + "quest": true, + "weight": 0.51 + }, + "4212": { + "name": "New crystal bow", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "4214": { + "name": "Crystal bow full", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "4215": { + "name": "Crystal bow 9/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 96, + "rstr": 68, + "aspeed": 5 + } + }, + "4216": { + "name": "Crystal bow 8/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 92, + "rstr": 66, + "aspeed": 5 + } + }, + "4217": { + "name": "Crystal bow 7/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 88, + "rstr": 64, + "aspeed": 5 + } + }, + "4218": { + "name": "Crystal bow 6/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 84, + "rstr": 62, + "aspeed": 5 + } + }, + "4219": { + "name": "Crystal bow 5/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 80, + "rstr": 60, + "aspeed": 5 + } + }, + "4220": { + "name": "Crystal bow 4/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 76, + "rstr": 58, + "aspeed": 5 + } + }, + "4221": { + "name": "Crystal bow 3/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 72, + "rstr": 56, + "aspeed": 5 + } + }, + "4222": { + "name": "Crystal bow 2/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 68, + "rstr": 54, + "aspeed": 5 + } + }, + "4223": { + "name": "Crystal bow 1/10", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 64, + "rstr": 52, + "aspeed": 5 + } + }, + "4224": { + "name": "New crystal shield", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "4225": { + "name": "Crystal shield full", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "4226": { + "name": "Crystal shield 9/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 49, + "dslash": 52, + "dcrush": 51, + "drange": 78 + } + }, + "4227": { + "name": "Crystal shield 8/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 47, + "dslash": 50, + "dcrush": 49, + "drange": 76 + } + }, + "4228": { + "name": "Crystal shield 7/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 45, + "dslash": 48, + "dcrush": 47, + "drange": 74 + } + }, + "4229": { + "name": "Crystal shield 6/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 43, + "dslash": 46, + "dcrush": 45, + "drange": 72 + } + }, + "4230": { + "name": "Crystal shield 5/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 41, + "dslash": 44, + "dcrush": 43, + "drange": 70 + } + }, + "4231": { + "name": "Crystal shield 4/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 39, + "dslash": 42, + "dcrush": 41, + "drange": 68 + } + }, + "4232": { + "name": "Crystal shield 3/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 37, + "dslash": 40, + "dcrush": 39, + "drange": 66 + } + }, + "4233": { + "name": "Crystal shield 2/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 35, + "dslash": 38, + "dcrush": 37, + "drange": 64 + } + }, + "4234": { + "name": "Crystal shield 1/10", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 33, + "dslash": 36, + "dcrush": 35, + "drange": 62 + } + }, + "4236": { + "name": "Signed oak bow", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "arange": 14, + "aspeed": 6 + } + }, + "4237": { + "name": "Nettle-water", + "quest": true, + "weight": 0.907 + }, + "4239": { + "name": "Nettle tea", + "quest": true, + "weight": 0.907 + }, + "4240": { + "name": "Nettle tea", + "weight": 0.907 + }, + "4241": { + "name": "Nettles", + "quest": true, + "weight": 0.007 + }, + "4242": { + "name": "Cup of tea", + "weight": 0.15 + }, + "4243": { + "name": "Cup of tea", + "weight": 0.15 + }, + "4244": { + "name": "Porcelain cup", + "quest": true, + "weight": 0.05 + }, + "4245": { + "name": "Cup of tea", + "quest": true, + "weight": 0.15 + }, + "4246": { + "name": "Cup of tea", + "quest": true, + "weight": 0.15 + }, + "4247": { + "name": "Mystical robes", + "quest": true, + "weight": 0.907 + }, + "4248": { + "name": "Book of haricanto", + "quest": true, + "weight": 1.814 + }, + "4249": { + "name": "Translation manual", + "quest": true, + "weight": 1.0 + }, + "4250": { + "name": "Ghostspeak amulet", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "4251": { + "name": "Ectophial", + "quest": true, + "weight": 0.035 + }, + "4252": { + "name": "Ectophial", + "quest": true, + "weight": 0.035 + }, + "4253": { + "name": "Model ship", + "quest": true, + "weight": 0.01 + }, + "4254": { + "name": "Model ship", + "quest": true, + "weight": 0.01 + }, + "4255": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4256": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4257": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4258": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4259": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4260": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4261": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4262": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4263": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4264": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4265": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4266": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4267": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4268": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4269": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4270": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4271": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4272": { + "name": "Bone key", + "quest": true, + "weight": 0.01 + }, + "4273": { + "name": "Chest key", + "quest": true, + "weight": 0.01 + }, + "4274": { + "name": "Map scrap", + "quest": true, + "weight": 0.01 + }, + "4275": { + "name": "Map scrap", + "quest": true, + "weight": 0.01 + }, + "4276": { + "name": "Map scrap", + "quest": true, + "weight": 0.01 + }, + "4277": { + "name": "Treasure map", + "quest": true, + "weight": 0.01 + }, + "4278": { + "name": "Ecto-token" + }, + "4283": { + "name": "Petition form", + "quest": true + }, + "4284": { + "name": "Bedsheet", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "4285": { + "name": "Bedsheet", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "4286": { + "name": "Bucket of slime", + "weight": 3.0 + }, + "4287": { + "name": "Raw beef", + "weight": 0.283 + }, + "4289": { + "name": "Raw chicken", + "weight": 0.17 + }, + "4291": { + "name": "Cooked chicken", + "weight": 0.141 + }, + "4293": { + "name": "Cooked meat", + "weight": 0.283 + }, + "4298": { + "name": "Ham shirt", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "4300": { + "name": "Ham robe", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "4302": { + "name": "Ham hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "dslash": 1, + "dcrush": 2, + "drange": 1 + } + }, + "4304": { + "name": "Ham cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4306": { + "name": "Ham logo", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "4308": { + "name": "Ham gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "4310": { + "name": "Ham boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "4313": { + "name": "Crystal of seren", + "weight": 0.51 + }, + "4315": { + "name": "Team-1 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4317": { + "name": "Team-2 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4319": { + "name": "Team-3 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4321": { + "name": "Team-4 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4323": { + "name": "Team-5 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4325": { + "name": "Team-6 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4327": { + "name": "Team-7 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4329": { + "name": "Team-8 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4331": { + "name": "Team-9 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4333": { + "name": "Team-10 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4335": { + "name": "Team-11 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4337": { + "name": "Team-12 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4339": { + "name": "Team-13 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4341": { + "name": "Team-14 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4343": { + "name": "Team-15 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4345": { + "name": "Team-16 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4347": { + "name": "Team-17 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4349": { + "name": "Team-18 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4351": { + "name": "Team-19 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4353": { + "name": "Team-20 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4355": { + "name": "Team-21 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4357": { + "name": "Team-22 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4359": { + "name": "Team-23 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4361": { + "name": "Team-24 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4363": { + "name": "Team-25 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4365": { + "name": "Team-26 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4367": { + "name": "Team-27 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4369": { + "name": "Team-28 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4371": { + "name": "Team-29 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4373": { + "name": "Team-30 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4375": { + "name": "Team-31 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4377": { + "name": "Team-32 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4379": { + "name": "Team-33 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4381": { + "name": "Team-34 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4383": { + "name": "Team-35 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4385": { + "name": "Team-36 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4387": { + "name": "Team-37 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4389": { + "name": "Team-38 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4391": { + "name": "Team-39 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4393": { + "name": "Team-40 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4395": { + "name": "Team-41 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4397": { + "name": "Team-42 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4399": { + "name": "Team-43 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4401": { + "name": "Team-44 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4403": { + "name": "Team-45 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4405": { + "name": "Team-46 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4407": { + "name": "Team-47 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4409": { + "name": "Team-48 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4411": { + "name": "Team-49 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4413": { + "name": "Team-50 cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4415": { + "name": "Blunt axe", + "quest": true, + "weight": 1.36 + }, + "4416": { + "name": "Herbal tincture", + "quest": true, + "weight": 0.15 + }, + "4417": { + "name": "Guthix rest(4)", + "quest": true, + "weight": 0.05 + }, + "4419": { + "name": "Guthix rest(3)", + "quest": true, + "weight": 0.05 + }, + "4421": { + "name": "Guthix rest(2)", + "quest": true, + "weight": 0.05 + }, + "4423": { + "name": "Guthix rest(1)", + "quest": true, + "weight": 0.05 + }, + "4425": { + "name": "Stodgy mattress", + "quest": true, + "weight": 10.0 + }, + "4426": { + "name": "Comfy mattress", + "quest": true, + "weight": 15.0 + }, + "4427": { + "name": "Iron oxide", + "quest": true, + "weight": 1.0 + }, + "4428": { + "name": "Animate rock scroll", + "quest": true, + "weight": 0.01 + }, + "4429": { + "name": "Broken vane part", + "quest": true, + "weight": 0.001 + }, + "4430": { + "name": "Directionals", + "quest": true, + "weight": 0.001 + }, + "4431": { + "name": "Broken vane part", + "quest": true, + "weight": 0.001 + }, + "4432": { + "name": "Ornament", + "quest": true, + "weight": 0.001 + }, + "4433": { + "name": "Broken vane part", + "quest": true, + "weight": 0.001 + }, + "4434": { + "name": "Weathervane pillar", + "quest": true, + "weight": 0.001 + }, + "4435": { + "name": "Weather report", + "quest": true, + "weight": 0.03 + }, + "4436": { + "name": "Airtight pot", + "quest": true, + "weight": 0.5 + }, + "4438": { + "name": "Unfired pot lid", + "quest": true, + "weight": 0.198 + }, + "4440": { + "name": "Pot lid", + "quest": true, + "weight": 0.198 + }, + "4442": { + "name": "Breathing salts", + "quest": true, + "weight": 0.001 + }, + "4443": { + "name": "Chicken cage", + "quest": true, + "weight": 1.0 + }, + "4444": { + "name": "Sharpened axe", + "quest": true, + "weight": 1.36 + }, + "4445": { + "name": "Red mahogany log", + "quest": true, + "weight": 1.36 + }, + "4446": { + "name": "Steel key ring", + "quest": true, + "weight": 0.001 + }, + "4447": { + "name": "Antique lamp", + "quest": true + }, + "4456": { + "name": "Bowl of hot water", + "weight": 0.907 + }, + "4458": { + "name": "Cup of water", + "weight": 0.05 + }, + "4460": { + "name": "Cup of hot water", + "weight": 0.05 + }, + "4462": { + "name": "Ruined herb tea", + "weight": 0.05 + }, + "4464": { + "name": "Herb tea mix", + "quest": true + }, + "4466": { + "name": "Herb tea mix", + "quest": true + }, + "4468": { + "name": "Herb tea mix", + "quest": true + }, + "4470": { + "name": "Herb tea mix", + "quest": true + }, + "4472": { + "name": "Herb tea mix", + "quest": true + }, + "4474": { + "name": "Herb tea mix", + "quest": true + }, + "4476": { + "name": "Herb tea mix", + "quest": true + }, + "4478": { + "name": "Herb tea mix", + "quest": true + }, + "4480": { + "name": "Herb tea mix", + "quest": true + }, + "4482": { + "name": "Herb tea mix", + "quest": true + }, + "4484": { + "name": "Safety guarantee", + "quest": true, + "weight": 0.3 + }, + "4485": { + "name": "White pearl", + "quest": true, + "weight": 0.75 + }, + "4486": { + "name": "White pearl seed", + "quest": true, + "weight": 0.025 + }, + "4487": { + "name": "Half a rock", + "quest": true, + "weight": 1.0 + }, + "4488": { + "name": "Corpse of woman", + "quest": true, + "weight": 1.0 + }, + "4489": { + "name": "Asleif's necklace", + "quest": true, + "weight": 0.1 + }, + "4490": { + "name": "Mud", + "quest": true, + "weight": 0.03 + }, + "4492": { + "name": "Muddy rock", + "quest": true, + "weight": 1.0 + }, + "4494": { + "name": "Pole", + "quest": true, + "weight": 0.01 + }, + "4496": { + "name": "Broken pole", + "weight": 0.01 + }, + "4502": { + "name": "Bearhead", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -3, + "dstab": 12, + "dslash": 14, + "dcrush": 10, + "dmagic": 7, + "drange": 9 + } + }, + "4503": { + "name": "Decorative sword", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 20, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 22, + "aspeed": 5 + } + }, + "4504": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.6175, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 46, + "dslash": 44, + "dcrush": 38, + "dmagic": -6, + "drange": 44 + } + }, + "4505": { + "name": "Decorative armour", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "4506": { + "name": "Decorative helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 10, + "dslash": 11, + "dcrush": 9, + "dmagic": -1, + "drange": 10 + } + }, + "4507": { + "name": "Decorative shield", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 18, + "dslash": 22, + "dcrush": 20, + "dmagic": -1, + "drange": 20 + } + }, + "4508": { + "name": "Decorative sword", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": 29, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 31, + "aspeed": 5 + } + }, + "4509": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.618, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "4510": { + "name": "Decorative armour", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "4511": { + "name": "Decorative helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 14, + "dslash": 15, + "dcrush": 13, + "dmagic": -1, + "drange": 14 + } + }, + "4512": { + "name": "Decorative shield", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "4513": { + "name": "Castlewars hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "dslash": 1, + "dcrush": 2, + "drange": 1 + } + }, + "4514": { + "name": "Castlewars cloak", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4515": { + "name": "Castlewars hood", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 0, + "dslash": 1, + "dcrush": 2, + "drange": 1 + } + }, + "4516": { + "name": "Castlewars cloak", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "4517": { + "name": "Giant frog legs", + "weight": 0.453 + }, + "4522": { + "name": "Oil lamp", + "weight": 0.453 + }, + "4524": { + "name": "Oil lamp", + "weight": 0.453 + }, + "4525": { + "name": "Empty oil lamp", + "weight": 0.453 + }, + "4527": { + "name": "Empty candle lantern", + "weight": 0.907 + }, + "4529": { + "name": "Candle lantern", + "weight": 0.907 + }, + "4531": { + "name": "Candle lantern", + "weight": 0.907 + }, + "4532": { + "name": "Candle lantern", + "weight": 0.907 + }, + "4534": { + "name": "Candle lantern", + "weight": 0.907 + }, + "4535": { + "name": "Empty oil lantern", + "weight": 0.907 + }, + "4537": { + "name": "Oil lantern", + "weight": 0.907 + }, + "4539": { + "name": "Oil lantern", + "weight": 0.907 + }, + "4540": { + "name": "Oil lantern frame", + "weight": 0.453 + }, + "4542": { + "name": "Lantern lens", + "weight": 0.028 + }, + "4544": { + "name": "Bullseye lantern (unf)", + "weight": 1.36 + }, + "4546": { + "name": "Bullseye lantern (empty)", + "weight": 1.36 + }, + "4548": { + "name": "Bullseye lantern", + "weight": 1.36 + }, + "4550": { + "name": "Bullseye lantern", + "weight": 1.36 + }, + "4551": { + "name": "Spiny helmet", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "4565": { + "name": "Easter basket", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "4566": { + "name": "Rubber chicken", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "4567": { + "name": "Gold helmet", + "quest": true, + "equipable": true, + "weight": 31.751, + "equipment": { + "slot": 0, + "dslash": 10, + "dcrush": 20, + "drange": 10 + } + }, + "4568": { + "name": "Dwarven lore", + "quest": true, + "weight": 0.08 + }, + "4569": { + "name": "Book page 1", + "quest": true, + "weight": 0.002 + }, + "4570": { + "name": "Book page 2", + "quest": true, + "weight": 0.002 + }, + "4571": { + "name": "Book page 3", + "quest": true, + "weight": 0.002 + }, + "4573": { + "name": "Pages", + "quest": true, + "weight": 0.002 + }, + "4574": { + "name": "Base schematics", + "quest": true, + "weight": 0.002 + }, + "4575": { + "name": "Schematic", + "quest": true, + "weight": 0.004 + }, + "4576": { + "name": "Schematics", + "quest": true, + "weight": 0.004 + }, + "4577": { + "name": "Schematics", + "quest": true, + "weight": 0.004 + }, + "4578": { + "name": "Schematic", + "quest": true, + "weight": 0.014 + }, + "4579": { + "name": "Cannon ball", + "quest": true, + "weight": 20.0 + }, + "4580": { + "name": "Black spear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 15, + "acrush": 15, + "dstab": 1, + "dslash": 1, + "str": 16, + "aspeed": 5 + } + }, + "4582": { + "name": "Black spear(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 15, + "acrush": 15, + "dstab": 1, + "dslash": 1, + "str": 16, + "aspeed": 5 + } + }, + "4584": { + "name": "Black spear(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 15, + "acrush": 15, + "dstab": 1, + "dslash": 1, + "str": 16, + "aspeed": 5 + } + }, + "4585": { + "name": "Dragon plateskirt", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 68, + "dslash": 66, + "dcrush": 63, + "dmagic": -4, + "drange": 65 + } + }, + "4587": { + "name": "Dragon scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 67, + "acrush": -2, + "dslash": 1, + "str": 66, + "aspeed": 4 + } + }, + "4589": { + "name": "Keys", + "quest": true + }, + "4590": { + "name": "Jewels", + "quest": true, + "weight": 0.01 + }, + "4591": { + "name": "Kharidian headpiece", + "weight": 0.07 + }, + "4593": { + "name": "Fake beard", + "quest": true, + "weight": 0.03 + }, + "4595": { + "name": "Karidian disguise", + "quest": true, + "weight": 0.1 + }, + "4597": { + "name": "Note", + "quest": true, + "weight": 0.02 + }, + "4598": { + "name": "Note", + "quest": true, + "weight": 0.02 + }, + "4599": { + "name": "Oak blackjack", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "str": 2, + "aspeed": 4 + } + }, + "4600": { + "name": "Willow blackjack", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "str": 8, + "aspeed": 4 + } + }, + "4601": { + "name": "Ugthanki dung", + "quest": true, + "weight": 0.4 + }, + "4602": { + "name": "Ugthanki dung", + "quest": true, + "weight": 0.4 + }, + "4603": { + "name": "Receipt", + "quest": true, + "weight": 0.02 + }, + "4604": { + "name": "Hag's poison", + "quest": true, + "weight": 0.2 + }, + "4605": { + "name": "Snake charm", + "quest": true, + "weight": 0.1 + }, + "4606": { + "name": "Snake basket", + "quest": true, + "weight": 0.5 + }, + "4607": { + "name": "Snake basket full", + "quest": true, + "weight": 1.0 + }, + "4608": { + "name": "Super kebab", + "weight": 0.25 + }, + "4610": { + "name": "Red hot sauce", + "quest": true, + "weight": 0.1 + }, + "4611": { + "name": "Desert disguise", + "quest": true, + "equipable": true, + "weight": 0.04, + "equipment": { + "slot": 0 + } + }, + "4613": { + "name": "Spinning plate", + "weight": 0.05 + }, + "4615": { + "name": "Letter", + "quest": true, + "weight": 0.005 + }, + "4616": { + "name": "Varmen's notes", + "quest": true, + "weight": 1.0 + }, + "4617": { + "name": "Display cabinet key", + "quest": true, + "weight": 0.01 + }, + "4618": { + "name": "Statuette", + "quest": true, + "weight": 0.5 + }, + "4619": { + "name": "Strange implement", + "quest": true, + "weight": 0.01 + }, + "4620": { + "name": "Black mushroom", + "quest": true, + "weight": 0.01 + }, + "4621": { + "name": "Phoenix feather", + "quest": true, + "weight": 0.002 + }, + "4622": { + "name": "Black mushroom ink", + "quest": true, + "weight": 0.01 + }, + "4623": { + "name": "Phoenix quill pen", + "quest": true + }, + "4624": { + "name": "Golem program", + "quest": true, + "weight": 0.02 + }, + "4627": { + "name": "Bandit's brew", + "weight": 0.55 + }, + "4654": { + "name": "Etchings", + "quest": true, + "weight": 0.51 + }, + "4655": { + "name": "Translation", + "quest": true, + "weight": 0.51 + }, + "4656": { + "name": "Warm key", + "quest": true, + "weight": 0.01 + }, + "4657": { + "name": "Ring of visibility", + "quest": true, + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "4658": { + "name": "Silver pot", + "quest": true, + "weight": 0.453 + }, + "4659": { + "name": "Blessed pot", + "quest": true, + "weight": 0.453 + }, + "4660": { + "name": "Silver pot", + "quest": true, + "weight": 0.453 + }, + "4661": { + "name": "Blessed pot", + "quest": true, + "weight": 0.453 + }, + "4662": { + "name": "Silver pot", + "quest": true, + "weight": 0.453 + }, + "4663": { + "name": "Blessed pot", + "quest": true, + "weight": 0.453 + }, + "4664": { + "name": "Silver pot", + "quest": true, + "weight": 0.453 + }, + "4665": { + "name": "Blessed pot", + "quest": true, + "weight": 0.453 + }, + "4666": { + "name": "Silver pot", + "quest": true, + "weight": 0.453 + }, + "4667": { + "name": "Blessed pot", + "quest": true, + "weight": 0.453 + }, + "4668": { + "name": "Garlic powder", + "quest": true, + "weight": 0.007 + }, + "4670": { + "name": "Blood diamond", + "quest": true, + "weight": 0.001 + }, + "4671": { + "name": "Ice diamond", + "quest": true, + "weight": 0.001 + }, + "4672": { + "name": "Smoke diamond", + "quest": true, + "weight": 0.001 + }, + "4673": { + "name": "Shadow diamond", + "quest": true, + "weight": 0.001 + }, + "4674": { + "name": "Gilded cross", + "quest": true + }, + "4675": { + "name": "Ancient staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "str": 50, + "prayer": -1, + "aspeed": 4 + } + }, + "4677": { + "name": "Catspeak amulet", + "quest": true, + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 2 + } + }, + "4678": { + "name": "Canopic jar", + "quest": true, + "weight": 0.1 + }, + "4679": { + "name": "Canopic jar", + "quest": true, + "weight": 0.1 + }, + "4680": { + "name": "Canopic jar", + "quest": true, + "weight": 0.1 + }, + "4681": { + "name": "Canopic jar", + "quest": true, + "weight": 0.1 + }, + "4682": { + "name": "Holy symbol", + "quest": true, + "weight": 2.267 + }, + "4683": { + "name": "Unholy symbol", + "quest": true, + "weight": 2.267 + }, + "4684": { + "name": "Linen", + "quest": true, + "weight": 0.907 + }, + "4686": { + "name": "Embalming manual", + "quest": true, + "weight": 0.51 + }, + "4687": { + "name": "Bucket of sap", + "quest": true, + "weight": 2.5 + }, + "4689": { + "name": "Pile of salt", + "quest": true, + "weight": 0.5 + }, + "4691": { + "name": "Sphinx's token", + "quest": true + }, + "4693": { + "name": "Full bucket", + "quest": true, + "weight": 3.0 + }, + "4694": { + "name": "Steam rune" + }, + "4695": { + "name": "Mist rune" + }, + "4696": { + "name": "Dust rune" + }, + "4697": { + "name": "Smoke rune" + }, + "4698": { + "name": "Mud rune" + }, + "4699": { + "name": "Lava rune" + }, + "4700": { + "name": "Sapphire lantern", + "quest": true, + "weight": 1.36 + }, + "4701": { + "name": "Sapphire lantern", + "quest": true, + "weight": 1.36 + }, + "4702": { + "name": "Sapphire lantern", + "quest": true, + "weight": 1.36 + }, + "4703": { + "name": "Magic stone", + "quest": true, + "weight": 2.267 + }, + "4704": { + "name": "Stone bowl", + "quest": true, + "weight": 1.814 + }, + "4707": { + "name": "Crumbling tome", + "weight": 0.51 + }, + "4708": { + "name": "Ahrim's hood", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": 6, + "arange": -2, + "dstab": 15, + "dslash": 13, + "dcrush": 16, + "dmagic": 6 + } + }, + "4710": { + "name": "Ahrim's staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -1, + "acrush": 65, + "amagic": 15, + "dstab": 3, + "dslash": 5, + "dcrush": 2, + "dmagic": 15, + "str": 68, + "mdmg": 5, + "aspeed": 6 + } + }, + "4712": { + "name": "Ahrim's robetop", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "4714": { + "name": "Ahrim's robeskirt", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "4716": { + "name": "Dharok's helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 45, + "dslash": 48, + "dcrush": 44, + "dmagic": -1, + "drange": 51 + } + }, + "4718": { + "name": "Dharok's greataxe", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 103, + "acrush": 95, + "amagic": -4, + "drange": -1, + "str": 105, + "aspeed": 7 + } + }, + "4720": { + "name": "Dharok's platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4722": { + "name": "Dharok's platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4724": { + "name": "Guthan's helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4726": { + "name": "Guthan's warspear", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 75, + "acrush": 75, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "str": 75, + "aspeed": 5 + } + }, + "4728": { + "name": "Guthan's platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4730": { + "name": "Guthan's chainskirt", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -7, + "dstab": 75, + "dslash": 72, + "dcrush": 73, + "dmagic": -4, + "drange": 82 + } + }, + "4732": { + "name": "Karil's coif", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 10 + } + }, + "4734": { + "name": "Karil's crossbow", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 84, + "aspeed": 4 + } + }, + "4736": { + "name": "Karil's leathertop", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 47, + "dslash": 42, + "dcrush": 50, + "dmagic": 65, + "drange": 57 + } + }, + "4738": { + "name": "Karil's leatherskirt", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 26, + "dslash": 20, + "dcrush": 28, + "dmagic": 35, + "drange": 33 + } + }, + "4740": { + "name": "Bolt rack", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "4745": { + "name": "Torag's helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4747": { + "name": "Torag's hammers", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 85, + "amagic": -4, + "str": 72, + "aspeed": 5 + } + }, + "4749": { + "name": "Torag's platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4751": { + "name": "Torag's platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4753": { + "name": "Verac's helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "drange": 56, + "prayer": 3 + } + }, + "4755": { + "name": "Verac's flail", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 68, + "aslash": -2, + "acrush": 82, + "str": 72, + "prayer": 6, + "aspeed": 5 + } + }, + "4757": { + "name": "Verac's brassard", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": -6, + "arange": -2, + "dstab": 81, + "dslash": 95, + "dcrush": 85, + "drange": 81, + "prayer": 5 + } + }, + "4759": { + "name": "Verac's plateskirt", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "drange": 84, + "prayer": 4 + } + }, + "4773": { + "name": "Bronze brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 11 + } + }, + "4778": { + "name": "Iron brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 13 + } + }, + "4783": { + "name": "Steel brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 19 + } + }, + "4788": { + "name": "Black brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "4793": { + "name": "Mithril brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 34 + } + }, + "4798": { + "name": "Adamant brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 45 + } + }, + "4803": { + "name": "Rune brutal", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "4808": { + "name": "Black prism", + "quest": true, + "weight": 0.001 + }, + "4809": { + "name": "Torn page", + "quest": true, + "weight": 0.005 + }, + "4810": { + "name": "Ruined backpack", + "quest": true + }, + "4811": { + "name": "Dragon inn tankard", + "quest": true, + "weight": 0.001 + }, + "4812": { + "name": "Zogre bones", + "weight": 0.8 + }, + "4814": { + "name": "Sithik portrait", + "quest": true, + "weight": 0.02 + }, + "4815": { + "name": "Sithik portrait", + "quest": true, + "weight": 0.02 + }, + "4816": { + "name": "Signed portrait", + "quest": true, + "weight": 0.02 + }, + "4817": { + "name": "Book of portraiture", + "quest": true, + "weight": 1.0 + }, + "4818": { + "name": "Ogre artefact", + "quest": true, + "weight": 0.8 + }, + "4819": { + "name": "Bronze nails" + }, + "4820": { + "name": "Iron nails" + }, + "4821": { + "name": "Black nails" + }, + "4822": { + "name": "Mithril nails" + }, + "4823": { + "name": "Adamantite nails" + }, + "4824": { + "name": "Rune nails" + }, + "4825": { + "name": "Unstrung comp bow", + "weight": 5.0 + }, + "4827": { + "name": "Comp ogre bow", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "arange": 38, + "aspeed": 5 + } + }, + "4829": { + "name": "Book of 'h.a.m'", + "quest": true, + "weight": 1.0 + }, + "4830": { + "name": "Fayrg bones", + "weight": 0.8 + }, + "4832": { + "name": "Raurg bones", + "weight": 0.8 + }, + "4834": { + "name": "Ourg bones", + "weight": 0.8 + }, + "4836": { + "name": "Strange potion", + "quest": true, + "weight": 0.001 + }, + "4837": { + "name": "Necromancy book", + "quest": true, + "weight": 1.0 + }, + "4838": { + "name": "Cup of tea", + "quest": true, + "weight": 0.15 + }, + "4839": { + "name": "Ogre gate key", + "quest": true, + "weight": 0.055 + }, + "4840": { + "name": "Unfinished potion" + }, + "4842": { + "name": "Relicym's balm(4)", + "weight": 0.035 + }, + "4844": { + "name": "Relicym's balm(3)", + "weight": 0.03 + }, + "4846": { + "name": "Relicym's balm(2)", + "weight": 0.025 + }, + "4848": { + "name": "Relicym's balm(1)", + "weight": 0.02 + }, + "4850": { + "name": "Ogre coffin key", + "weight": 0.055 + }, + "4852": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4853": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4854": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4855": { + "name": "Bonemeal", + "weight": 1.0 + }, + "4856": { + "name": "Ahrim's hood 100", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 6, + "arange": -2, + "dstab": 15, + "dslash": 13, + "dcrush": 16, + "dmagic": 6 + } + }, + "4857": { + "name": "Ahrim's hood 75", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 6, + "arange": -2, + "dstab": 15, + "dslash": 13, + "dcrush": 16, + "dmagic": 6 + } + }, + "4858": { + "name": "Ahrim's hood 50", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 6, + "arange": -2, + "dstab": 15, + "dslash": 13, + "dcrush": 16, + "dmagic": 6 + } + }, + "4859": { + "name": "Ahrim's hood 25", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 6, + "arange": -2, + "dstab": 15, + "dslash": 13, + "dcrush": 16, + "dmagic": 6 + } + }, + "4860": { + "name": "Ahrim's hood 0", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 6, + "arange": -2, + "dstab": 15, + "dslash": 13, + "dcrush": 16, + "dmagic": 6 + } + }, + "4862": { + "name": "Ahrim's staff 100", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -1, + "acrush": 65, + "amagic": 15, + "dstab": 3, + "dslash": 5, + "dcrush": 2, + "dmagic": 15, + "str": 68, + "mdmg": 5, + "aspeed": 6 + } + }, + "4863": { + "name": "Ahrim's staff 75", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -1, + "acrush": 65, + "amagic": 15, + "dstab": 3, + "dslash": 5, + "dcrush": 2, + "dmagic": 15, + "str": 68, + "mdmg": 5, + "aspeed": 6 + } + }, + "4864": { + "name": "Ahrim's staff 50", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -1, + "acrush": 65, + "amagic": 15, + "dstab": 3, + "dslash": 5, + "dcrush": 2, + "dmagic": 15, + "str": 68, + "mdmg": 5, + "aspeed": 6 + } + }, + "4865": { + "name": "Ahrim's staff 25", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -1, + "acrush": 65, + "amagic": 15, + "dstab": 3, + "dslash": 5, + "dcrush": 2, + "dmagic": 15, + "str": 68, + "mdmg": 5, + "aspeed": 6 + } + }, + "4866": { + "name": "Ahrim's staff 0", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": -1, + "acrush": 65, + "amagic": 15, + "dstab": 3, + "dslash": 5, + "dcrush": 2, + "dmagic": 15, + "str": 68, + "mdmg": 5, + "aspeed": 6 + } + }, + "4868": { + "name": "Ahrim's robetop 100", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "4869": { + "name": "Ahrim's robetop 75", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "4870": { + "name": "Ahrim's robetop 50", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "4871": { + "name": "Ahrim's robetop 25", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "4872": { + "name": "Ahrim's robetop 0", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "4874": { + "name": "Ahrim's robeskirt 100", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "4875": { + "name": "Ahrim's robeskirt 75", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "4876": { + "name": "Ahrim's robeskirt 50", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "4877": { + "name": "Ahrim's robeskirt 25", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "4878": { + "name": "Ahrim's robeskirt 0", + "equipable": true, + "weight": 11.3, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "4880": { + "name": "Dharok's helm 100", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 45, + "dslash": 48, + "dcrush": 44, + "dmagic": -1, + "drange": 51 + } + }, + "4881": { + "name": "Dharok's helm 75", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 45, + "dslash": 48, + "dcrush": 44, + "dmagic": -1, + "drange": 51 + } + }, + "4882": { + "name": "Dharok's helm 50", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 45, + "dslash": 48, + "dcrush": 44, + "dmagic": -1, + "drange": 51 + } + }, + "4883": { + "name": "Dharok's helm 25", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 45, + "dslash": 48, + "dcrush": 44, + "dmagic": -1, + "drange": 51 + } + }, + "4884": { + "name": "Dharok's helm 0", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 45, + "dslash": 48, + "dcrush": 44, + "dmagic": -1, + "drange": 51 + } + }, + "4886": { + "name": "Dharok's greataxe 100", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 103, + "acrush": 95, + "amagic": -4, + "drange": -1, + "str": 105, + "aspeed": 7 + } + }, + "4887": { + "name": "Dharok's greataxe 75", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 103, + "acrush": 95, + "amagic": -4, + "drange": -1, + "str": 105, + "aspeed": 7 + } + }, + "4888": { + "name": "Dharok's greataxe 50", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 103, + "acrush": 95, + "amagic": -4, + "drange": -1, + "str": 105, + "aspeed": 7 + } + }, + "4889": { + "name": "Dharok's greataxe 25", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 103, + "acrush": 95, + "amagic": -4, + "drange": -1, + "str": 105, + "aspeed": 7 + } + }, + "4890": { + "name": "Dharok's greataxe 0", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 103, + "acrush": 95, + "amagic": -4, + "drange": -1, + "str": 105, + "aspeed": 7 + } + }, + "4892": { + "name": "Dharok's platebody 100", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4893": { + "name": "Dharok's platebody 75", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4894": { + "name": "Dharok's platebody 50", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4895": { + "name": "Dharok's platebody 25", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4896": { + "name": "Dharok's platebody 0", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4898": { + "name": "Dharok's platelegs 100", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4899": { + "name": "Dharok's platelegs 75", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4900": { + "name": "Dharok's platelegs 50", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4901": { + "name": "Dharok's platelegs 25", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4902": { + "name": "Dharok's platelegs 0", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4904": { + "name": "Guthan's helm 100", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4905": { + "name": "Guthan's helm 75", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4906": { + "name": "Guthan's helm 50", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4907": { + "name": "Guthan's helm 25", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4908": { + "name": "Guthan's helm 0", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4910": { + "name": "Guthan's warspear 100", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 75, + "acrush": 75, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "str": 75, + "aspeed": 5 + } + }, + "4911": { + "name": "Guthan's warspear 75", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 75, + "acrush": 75, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "str": 75, + "aspeed": 5 + } + }, + "4912": { + "name": "Guthan's warspear 50", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 75, + "acrush": 75, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "str": 75, + "aspeed": 5 + } + }, + "4913": { + "name": "Guthan's warspear 25", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 75, + "acrush": 75, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "str": 75, + "aspeed": 5 + } + }, + "4914": { + "name": "Guthan's warspear 0", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 75, + "acrush": 75, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "str": 75, + "aspeed": 5 + } + }, + "4916": { + "name": "Guthan's platebody 100", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4917": { + "name": "Guthan's platebody 75", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4918": { + "name": "Guthan's platebody 50", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4919": { + "name": "Guthan's platebody 25", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4920": { + "name": "Guthan's platebody 0", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4922": { + "name": "Guthan's chainskirt 100", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -7, + "dstab": 75, + "dslash": 72, + "dcrush": 73, + "dmagic": -4, + "drange": 82 + } + }, + "4923": { + "name": "Guthan's chainskirt 75", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -7, + "dstab": 75, + "dslash": 72, + "dcrush": 73, + "dmagic": -4, + "drange": 82 + } + }, + "4924": { + "name": "Guthan's chainskirt 50", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -7, + "dstab": 75, + "dslash": 72, + "dcrush": 73, + "dmagic": -4, + "drange": 82 + } + }, + "4925": { + "name": "Guthan's chainskirt 25", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -7, + "dstab": 75, + "dslash": 72, + "dcrush": 73, + "dmagic": -4, + "drange": 82 + } + }, + "4926": { + "name": "Guthan's chainskirt 0", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -7, + "dstab": 75, + "dslash": 72, + "dcrush": 73, + "dmagic": -4, + "drange": 82 + } + }, + "4928": { + "name": "Karil's coif 100", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 10 + } + }, + "4929": { + "name": "Karil's coif 75", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 10 + } + }, + "4930": { + "name": "Karil's coif 50", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 10 + } + }, + "4931": { + "name": "Karil's coif 25", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 10 + } + }, + "4932": { + "name": "Karil's coif 0", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 10 + } + }, + "4934": { + "name": "Karil's crossbow 100", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 84, + "aspeed": 4 + } + }, + "4935": { + "name": "Karil's crossbow 75", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 84, + "aspeed": 4 + } + }, + "4936": { + "name": "Karil's crossbow 50", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 84, + "aspeed": 4 + } + }, + "4937": { + "name": "Karil's crossbow 25", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 84, + "aspeed": 4 + } + }, + "4938": { + "name": "Karil's crossbow 0", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "arange": 84, + "aspeed": 4 + } + }, + "4940": { + "name": "Karil's leathertop 100", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 47, + "dslash": 42, + "dcrush": 50, + "dmagic": 65, + "drange": 57 + } + }, + "4941": { + "name": "Karil's leathertop 75", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 47, + "dslash": 42, + "dcrush": 50, + "dmagic": 65, + "drange": 57 + } + }, + "4942": { + "name": "Karil's leathertop 50", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 47, + "dslash": 42, + "dcrush": 50, + "dmagic": 65, + "drange": 57 + } + }, + "4943": { + "name": "Karil's leathertop 25", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 47, + "dslash": 42, + "dcrush": 50, + "dmagic": 65, + "drange": 57 + } + }, + "4944": { + "name": "Karil's leathertop 0", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 47, + "dslash": 42, + "dcrush": 50, + "dmagic": 65, + "drange": 57 + } + }, + "4946": { + "name": "Karil's leatherskirt 100", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 26, + "dslash": 20, + "dcrush": 28, + "dmagic": 35, + "drange": 33 + } + }, + "4947": { + "name": "Karil's leatherskirt 75", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 26, + "dslash": 20, + "dcrush": 28, + "dmagic": 35, + "drange": 33 + } + }, + "4948": { + "name": "Karil's leatherskirt 50", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 26, + "dslash": 20, + "dcrush": 28, + "dmagic": 35, + "drange": 33 + } + }, + "4949": { + "name": "Karil's leatherskirt 25", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 26, + "dslash": 20, + "dcrush": 28, + "dmagic": 35, + "drange": 33 + } + }, + "4950": { + "name": "Karil's leatherskirt 0", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 26, + "dslash": 20, + "dcrush": 28, + "dmagic": 35, + "drange": 33 + } + }, + "4952": { + "name": "Torag's helm 100", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4953": { + "name": "Torag's helm 75", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4954": { + "name": "Torag's helm 50", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4955": { + "name": "Torag's helm 25", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4956": { + "name": "Torag's helm 0", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "dmagic": -1, + "drange": 62 + } + }, + "4958": { + "name": "Torag's hammers 100", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 85, + "amagic": -4, + "str": 72, + "aspeed": 5 + } + }, + "4959": { + "name": "Torag's hammers 75", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 85, + "amagic": -4, + "str": 72, + "aspeed": 5 + } + }, + "4960": { + "name": "Torag's hammers 50", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 85, + "amagic": -4, + "str": 72, + "aspeed": 5 + } + }, + "4961": { + "name": "Torag's hammers 25", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 85, + "amagic": -4, + "str": 72, + "aspeed": 5 + } + }, + "4962": { + "name": "Torag's hammers 0", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 85, + "amagic": -4, + "str": 72, + "aspeed": 5 + } + }, + "4964": { + "name": "Torag's platebody 100", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4965": { + "name": "Torag's platebody 75", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4966": { + "name": "Torag's platebody 50", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4967": { + "name": "Torag's platebody 25", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4968": { + "name": "Torag's platebody 0", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 122, + "dslash": 120, + "dcrush": 107, + "dmagic": -6, + "drange": 132 + } + }, + "4970": { + "name": "Torag's platelegs 100", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4971": { + "name": "Torag's platelegs 75", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4972": { + "name": "Torag's platelegs 50", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4973": { + "name": "Torag's platelegs 25", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4974": { + "name": "Torag's platelegs 0", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "dmagic": -4, + "drange": 92 + } + }, + "4976": { + "name": "Verac's helm 100", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "drange": 56, + "prayer": 3 + } + }, + "4977": { + "name": "Verac's helm 75", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "drange": 56, + "prayer": 3 + } + }, + "4978": { + "name": "Verac's helm 50", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "drange": 56, + "prayer": 3 + } + }, + "4979": { + "name": "Verac's helm 25", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "drange": 56, + "prayer": 3 + } + }, + "4980": { + "name": "Verac's helm 0", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 55, + "dslash": 58, + "dcrush": 54, + "drange": 56, + "prayer": 3 + } + }, + "4982": { + "name": "Verac's flail 100", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 68, + "aslash": -2, + "acrush": 82, + "str": 72, + "prayer": 6, + "aspeed": 5 + } + }, + "4983": { + "name": "Verac's flail 75", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 68, + "aslash": -2, + "acrush": 82, + "str": 72, + "prayer": 6, + "aspeed": 5 + } + }, + "4984": { + "name": "Verac's flail 50", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 68, + "aslash": -2, + "acrush": 82, + "str": 72, + "prayer": 6, + "aspeed": 5 + } + }, + "4985": { + "name": "Verac's flail 25", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 68, + "aslash": -2, + "acrush": 82, + "str": 72, + "prayer": 6, + "aspeed": 5 + } + }, + "4986": { + "name": "Verac's flail 0", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 68, + "aslash": -2, + "acrush": 82, + "str": 72, + "prayer": 6, + "aspeed": 5 + } + }, + "4988": { + "name": "Verac's brassard 100", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": -6, + "arange": -2, + "dstab": 81, + "dslash": 95, + "dcrush": 85, + "drange": 81, + "prayer": 5 + } + }, + "4989": { + "name": "Verac's brassard 75", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": -6, + "arange": -2, + "dstab": 81, + "dslash": 95, + "dcrush": 85, + "drange": 81, + "prayer": 5 + } + }, + "4990": { + "name": "Verac's brassard 50", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": -6, + "arange": -2, + "dstab": 81, + "dslash": 95, + "dcrush": 85, + "drange": 81, + "prayer": 5 + } + }, + "4991": { + "name": "Verac's brassard 25", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": -6, + "arange": -2, + "dstab": 81, + "dslash": 95, + "dcrush": 85, + "drange": 81, + "prayer": 5 + } + }, + "4992": { + "name": "Verac's brassard 0", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": -6, + "arange": -2, + "dstab": 81, + "dslash": 95, + "dcrush": 85, + "drange": 81, + "prayer": 5 + } + }, + "4994": { + "name": "Verac's plateskirt 100", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "drange": 84, + "prayer": 4 + } + }, + "4995": { + "name": "Verac's plateskirt 75", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "drange": 84, + "prayer": 4 + } + }, + "4996": { + "name": "Verac's plateskirt 50", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "drange": 84, + "prayer": 4 + } + }, + "4997": { + "name": "Verac's plateskirt 25", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "drange": 84, + "prayer": 4 + } + }, + "4998": { + "name": "Verac's plateskirt 0", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 85, + "dslash": 82, + "dcrush": 83, + "drange": 84, + "prayer": 4 + } + }, + "5001": { + "name": "Raw cave eel", + "weight": 0.5 + }, + "5002": { + "name": "Burnt cave eel" + }, + "5003": { + "name": "Cave eel", + "weight": 0.5 + }, + "5004": { + "name": "Frog spawn", + "weight": 0.5 + }, + "5008": { + "name": "Brooch", + "quest": true, + "weight": 0.002 + }, + "5009": { + "name": "Goblin symbol book", + "quest": true, + "weight": 1.0 + }, + "5010": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "5011": { + "name": "Silverware", + "quest": true, + "weight": 0.05 + }, + "5012": { + "name": "Peace treaty", + "quest": true, + "weight": 0.028 + }, + "5013": { + "name": "Mining helmet", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "5014": { + "name": "Mining helmet", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "5016": { + "name": "Bone spear", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 11, + "acrush": 11, + "dstab": 1, + "dslash": 1, + "str": 13, + "aspeed": 6 + } + }, + "5018": { + "name": "Bone club", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 16, + "amagic": -4, + "str": 15, + "aspeed": 6 + } + }, + "5020": { + "name": "Minecart ticket", + "weight": 0.001 + }, + "5021": { + "name": "Minecart ticket", + "weight": 0.001 + }, + "5022": { + "name": "Minecart ticket", + "weight": 0.001 + }, + "5023": { + "name": "Minecart ticket", + "weight": 0.001 + }, + "5024": { + "name": "Woven top", + "equipable": true, + "weight": 0.07, + "equipment": { + "slot": 4 + } + }, + "5026": { + "name": "Woven top", + "equipable": true, + "weight": 0.07, + "equipment": { + "slot": 4 + } + }, + "5028": { + "name": "Woven top", + "equipable": true, + "weight": 0.07, + "equipment": { + "slot": 4 + } + }, + "5030": { + "name": "Shirt", + "equipable": true, + "weight": 0.07, + "equipment": { + "slot": 4 + } + }, + "5032": { + "name": "Shirt", + "equipable": true, + "weight": 0.07, + "equipment": { + "slot": 4 + } + }, + "5034": { + "name": "Shirt", + "equipable": true, + "weight": 0.07, + "equipment": { + "slot": 4 + } + }, + "5036": { + "name": "Trousers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "5038": { + "name": "Trousers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "5040": { + "name": "Trousers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "5042": { + "name": "Shorts", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 7 + } + }, + "5044": { + "name": "Shorts", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 7 + } + }, + "5046": { + "name": "Shorts", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 7 + } + }, + "5048": { + "name": "Skirt", + "equipable": true, + "weight": 0.08, + "equipment": { + "slot": 7 + } + }, + "5050": { + "name": "Skirt", + "equipable": true, + "weight": 0.08, + "equipment": { + "slot": 7 + } + }, + "5052": { + "name": "Skirt", + "equipable": true, + "weight": 0.08, + "equipment": { + "slot": 7 + } + }, + "5054": { + "name": "Dwarf", + "weight": 10.0 + }, + "5056": { + "name": "Dwarven battleaxe", + "quest": true, + "weight": 2.0 + }, + "5057": { + "name": "Dwarven battleaxe", + "quest": true, + "weight": 2.0 + }, + "5058": { + "name": "Dwarven battleaxe", + "quest": true, + "weight": 2.0 + }, + "5059": { + "name": "Dwarven battleaxe", + "quest": true, + "weight": 2.0 + }, + "5062": { + "name": "Left boot", + "quest": true, + "weight": 0.5 + }, + "5063": { + "name": "Right boot", + "quest": true, + "weight": 0.5 + }, + "5064": { + "name": "Exquisite boots", + "quest": true, + "weight": 1.0 + }, + "5065": { + "name": "Book on costumes", + "quest": true + }, + "5066": { + "name": "Meeting notes", + "quest": true, + "weight": 0.002 + }, + "5067": { + "name": "Exquisite clothes", + "quest": true, + "weight": 0.05 + }, + "5070": { + "name": "Bird nest" + }, + "5071": { + "name": "Bird nest" + }, + "5072": { + "name": "Bird nest" + }, + "5073": { + "name": "Bird nest" + }, + "5074": { + "name": "Bird nest" + }, + "5075": { + "name": "Bird nest" + }, + "5076": { + "name": "Bird's egg", + "weight": 0.002 + }, + "5077": { + "name": "Bird's egg", + "weight": 0.002 + }, + "5078": { + "name": "Bird's egg", + "weight": 0.002 + }, + "5096": { + "name": "Marigold seed" + }, + "5097": { + "name": "Rosemary seed" + }, + "5098": { + "name": "Nasturtium seed" + }, + "5099": { + "name": "Woad seed" + }, + "5100": { + "name": "Limpwurt seed" + }, + "5101": { + "name": "Redberry seed" + }, + "5102": { + "name": "Cadavaberry seed" + }, + "5103": { + "name": "Dwellberry seed" + }, + "5104": { + "name": "Jangerberry seed" + }, + "5105": { + "name": "Whiteberry seed" + }, + "5106": { + "name": "Poison ivy seed" + }, + "5280": { + "name": "Cactus seed" + }, + "5281": { + "name": "Belladonna seed" + }, + "5282": { + "name": "Mushroom spore" + }, + "5283": { + "name": "Apple tree seed" + }, + "5284": { + "name": "Banana tree seed" + }, + "5285": { + "name": "Orange tree seed" + }, + "5286": { + "name": "Curry tree seed" + }, + "5287": { + "name": "Pineapple seed" + }, + "5288": { + "name": "Papaya tree seed" + }, + "5289": { + "name": "Palm tree seed" + }, + "5290": { + "name": "Calquat tree seed" + }, + "5291": { + "name": "Guam seed" + }, + "5292": { + "name": "Marrentill seed" + }, + "5293": { + "name": "Tarromin seed" + }, + "5294": { + "name": "Harralander seed" + }, + "5295": { + "name": "Ranarr seed" + }, + "5296": { + "name": "Toadflax seed" + }, + "5297": { + "name": "Irit seed" + }, + "5298": { + "name": "Avantoe seed" + }, + "5299": { + "name": "Kwuarm seed" + }, + "5300": { + "name": "Snapdragon seed" + }, + "5301": { + "name": "Cadantine seed" + }, + "5302": { + "name": "Lantadyme seed" + }, + "5303": { + "name": "Dwarf weed seed" + }, + "5304": { + "name": "Torstol seed" + }, + "5305": { + "name": "Barley seed" + }, + "5306": { + "name": "Jute seed" + }, + "5307": { + "name": "Hammerstone seed" + }, + "5308": { + "name": "Asgarnian seed" + }, + "5309": { + "name": "Yanillian seed" + }, + "5310": { + "name": "Krandorian seed" + }, + "5311": { + "name": "Wildblood seed" + }, + "5312": { + "name": "Acorn" + }, + "5313": { + "name": "Willow seed" + }, + "5314": { + "name": "Maple seed" + }, + "5315": { + "name": "Yew seed" + }, + "5316": { + "name": "Magic seed" + }, + "5317": { + "name": "Spirit seed" + }, + "5318": { + "name": "Potato seed" + }, + "5319": { + "name": "Onion seed" + }, + "5320": { + "name": "Sweetcorn seed" + }, + "5321": { + "name": "Watermelon seed" + }, + "5322": { + "name": "Tomato seed" + }, + "5323": { + "name": "Strawberry seed" + }, + "5324": { + "name": "Cabbage seed" + }, + "5325": { + "name": "Gardening trowel", + "weight": 0.056 + }, + "5327": { + "name": "Spade handle", + "weight": 0.907 + }, + "5328": { + "name": "Spade head", + "weight": 0.907 + }, + "5329": { + "name": "Secateurs", + "weight": 0.453 + }, + "5331": { + "name": "Watering can", + "weight": 0.1 + }, + "5333": { + "name": "Watering can(1)", + "weight": 0.2 + }, + "5334": { + "name": "Watering can(2)", + "weight": 0.3 + }, + "5335": { + "name": "Watering can(3)", + "weight": 0.4 + }, + "5336": { + "name": "Watering can(4)", + "weight": 0.5 + }, + "5337": { + "name": "Watering can(5)", + "weight": 0.6 + }, + "5338": { + "name": "Watering can(6)", + "weight": 0.7 + }, + "5339": { + "name": "Watering can(7)", + "weight": 0.8 + }, + "5340": { + "name": "Watering can(8)", + "weight": 0.9 + }, + "5341": { + "name": "Rake", + "weight": 1.36 + }, + "5343": { + "name": "Seed dibber", + "weight": 0.002 + }, + "5345": { + "name": "Gardening boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10 + } + }, + "5347": { + "name": "Rake handle", + "weight": 0.453 + }, + "5348": { + "name": "Rake head", + "weight": 0.907 + }, + "5350": { + "name": "Empty plant pot", + "weight": 0.907 + }, + "5352": { + "name": "Unfired plant pot", + "weight": 0.907 + }, + "5354": { + "name": "Filled plant pot", + "weight": 0.9 + }, + "5358": { + "name": "Oak seedling", + "weight": 0.907 + }, + "5359": { + "name": "Willow seedling", + "weight": 0.907 + }, + "5360": { + "name": "Maple seedling", + "weight": 0.907 + }, + "5361": { + "name": "Yew seedling", + "weight": 0.907 + }, + "5362": { + "name": "Magic seedling", + "weight": 0.907 + }, + "5363": { + "name": "Spirit seedling", + "weight": 0.907 + }, + "5364": { + "name": "Oak seedling (w)", + "weight": 0.907 + }, + "5365": { + "name": "Willow seedling (w)", + "weight": 0.907 + }, + "5366": { + "name": "Maple seedling (w)", + "weight": 0.907 + }, + "5367": { + "name": "Yew seedling (w)", + "weight": 0.907 + }, + "5368": { + "name": "Magic seedling (w)", + "weight": 0.907 + }, + "5369": { + "name": "Spirit seedling (w)", + "weight": 0.907 + }, + "5370": { + "name": "Oak sapling", + "weight": 0.907 + }, + "5371": { + "name": "Willow sapling", + "weight": 0.9 + }, + "5372": { + "name": "Maple sapling", + "weight": 0.907 + }, + "5373": { + "name": "Yew sapling", + "weight": 0.907 + }, + "5374": { + "name": "Magic sapling", + "weight": 0.907 + }, + "5375": { + "name": "Spirit sapling", + "weight": 0.907 + }, + "5376": { + "name": "Basket", + "weight": 0.028 + }, + "5378": { + "name": "Apples(1)", + "weight": 0.056 + }, + "5380": { + "name": "Apples(2)", + "weight": 0.085 + }, + "5382": { + "name": "Apples(3)", + "weight": 0.113 + }, + "5384": { + "name": "Apples(4)", + "weight": 0.141 + }, + "5386": { + "name": "Apples(5)", + "weight": 0.17 + }, + "5388": { + "name": "Oranges(1)", + "weight": 0.056 + }, + "5390": { + "name": "Oranges(2)", + "weight": 0.085 + }, + "5392": { + "name": "Oranges(3)", + "weight": 0.113 + }, + "5394": { + "name": "Oranges(4)", + "weight": 0.141 + }, + "5396": { + "name": "Oranges(5)", + "weight": 0.17 + }, + "5398": { + "name": "Strawberries(1)", + "weight": 0.056 + }, + "5400": { + "name": "Strawberries(2)", + "weight": 0.085 + }, + "5402": { + "name": "Strawberries(3)", + "weight": 0.113 + }, + "5404": { + "name": "Strawberries(4)", + "weight": 0.141 + }, + "5406": { + "name": "Strawberries(5)", + "weight": 0.17 + }, + "5408": { + "name": "Bananas(1)", + "weight": 0.056 + }, + "5410": { + "name": "Bananas(2)", + "weight": 0.085 + }, + "5412": { + "name": "Bananas(3)", + "weight": 0.113 + }, + "5414": { + "name": "Bananas(4)", + "weight": 0.141 + }, + "5416": { + "name": "Bananas(5)", + "weight": 0.17 + }, + "5418": { + "name": "Empty sack", + "weight": 0.453 + }, + "5420": { + "name": "Potatoes(1)", + "weight": 0.907 + }, + "5422": { + "name": "Potatoes(2)", + "weight": 1.36 + }, + "5424": { + "name": "Potatoes(3)", + "weight": 1.814 + }, + "5426": { + "name": "Potatoes(4)", + "weight": 2.267 + }, + "5428": { + "name": "Potatoes(5)", + "weight": 2.721 + }, + "5430": { + "name": "Potatoes(6)", + "weight": 3.175 + }, + "5432": { + "name": "Potatoes(7)", + "weight": 3.628 + }, + "5434": { + "name": "Potatoes(8)", + "weight": 4.082 + }, + "5436": { + "name": "Potatoes(9)", + "weight": 4.535 + }, + "5438": { + "name": "Potatoes(10)", + "weight": 4.989 + }, + "5440": { + "name": "Onions(1)", + "weight": 0.907 + }, + "5442": { + "name": "Onions(2)", + "weight": 1.36 + }, + "5444": { + "name": "Onions(3)", + "weight": 1.814 + }, + "5446": { + "name": "Onions(4)", + "weight": 2.267 + }, + "5448": { + "name": "Onions(5)", + "weight": 2.721 + }, + "5450": { + "name": "Onions(6)", + "weight": 3.175 + }, + "5452": { + "name": "Onions(7)", + "weight": 3.628 + }, + "5454": { + "name": "Onions(8)", + "weight": 4.082 + }, + "5456": { + "name": "Onions(9)", + "weight": 4.535 + }, + "5458": { + "name": "Onions(10)", + "weight": 4.989 + }, + "5460": { + "name": "Cabbages(1)", + "weight": 0.907 + }, + "5462": { + "name": "Cabbages(2)", + "weight": 1.36 + }, + "5464": { + "name": "Cabbages(3)", + "weight": 1.814 + }, + "5466": { + "name": "Cabbages(4)", + "weight": 2.267 + }, + "5468": { + "name": "Cabbages(5)", + "weight": 2.721 + }, + "5470": { + "name": "Cabbages(6)", + "weight": 3.175 + }, + "5472": { + "name": "Cabbages(7)", + "weight": 3.628 + }, + "5474": { + "name": "Cabbages(8)", + "weight": 4.082 + }, + "5476": { + "name": "Cabbages(9)", + "weight": 4.535 + }, + "5478": { + "name": "Cabbages(10)", + "weight": 4.989 + }, + "5480": { + "name": "Apple seedling", + "weight": 0.907 + }, + "5481": { + "name": "Banana seedling", + "weight": 0.907 + }, + "5482": { + "name": "Orange seedling", + "weight": 0.907 + }, + "5483": { + "name": "Curry seedling", + "weight": 0.907 + }, + "5484": { + "name": "Pineapple seedling", + "weight": 0.907 + }, + "5485": { + "name": "Papaya seedling", + "weight": 0.907 + }, + "5486": { + "name": "Palm seedling", + "weight": 0.907 + }, + "5487": { + "name": "Calquat seedling", + "weight": 0.907 + }, + "5488": { + "name": "Apple seedling (w)", + "weight": 0.907 + }, + "5489": { + "name": "Banana seedling (w)", + "weight": 0.907 + }, + "5490": { + "name": "Orange seedling (w)", + "weight": 0.907 + }, + "5491": { + "name": "Curry seedling (w)", + "weight": 0.907 + }, + "5492": { + "name": "Pineapple seedling (w)", + "weight": 0.907 + }, + "5493": { + "name": "Papaya seedling (w)", + "weight": 0.907 + }, + "5494": { + "name": "Palm seedling (w)", + "weight": 0.907 + }, + "5495": { + "name": "Calquat seedling (w)", + "weight": 0.907 + }, + "5496": { + "name": "Apple sapling", + "weight": 0.907 + }, + "5497": { + "name": "Banana sapling", + "weight": 0.907 + }, + "5498": { + "name": "Orange sapling", + "weight": 0.907 + }, + "5499": { + "name": "Curry sapling", + "weight": 0.907 + }, + "5500": { + "name": "Pineapple sapling", + "weight": 0.907 + }, + "5501": { + "name": "Papaya sapling", + "weight": 0.907 + }, + "5502": { + "name": "Palm sapling", + "weight": 0.907 + }, + "5503": { + "name": "Calquat sapling", + "weight": 0.907 + }, + "5504": { + "name": "Strawberry", + "weight": 0.028 + }, + "5506": { + "name": "Old man's message", + "weight": 0.07 + }, + "5507": { + "name": "Strange book", + "weight": 0.07 + }, + "5508": { + "name": "Book of folklore", + "weight": 0.07 + }, + "5509": { + "name": "Small pouch", + "weight": 1.0 + }, + "5510": { + "name": "Medium pouch", + "weight": 1.0 + }, + "5511": { + "name": "Medium pouch", + "weight": 1.0 + }, + "5512": { + "name": "Large pouch", + "weight": 1.0 + }, + "5513": { + "name": "Large pouch", + "weight": 1.0 + }, + "5514": { + "name": "Giant pouch", + "weight": 1.0 + }, + "5515": { + "name": "Giant pouch", + "weight": 1.0 + }, + "5516": { + "name": "Elemental talisman", + "weight": 0.015 + }, + "5518": { + "name": "Scrying orb", + "weight": 0.05 + }, + "5519": { + "name": "Scrying orb", + "weight": 0.05 + }, + "5520": { + "name": "Abyssal book", + "weight": 0.01 + }, + "5521": { + "name": "Binding necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "5523": { + "name": "Tiara mould", + "weight": 1.0 + }, + "5525": { + "name": "Tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5527": { + "name": "Air tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5529": { + "name": "Mind tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5531": { + "name": "Water tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5533": { + "name": "Body tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5535": { + "name": "Earth tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5537": { + "name": "Fire tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5539": { + "name": "Cosmic tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5541": { + "name": "Nature tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5543": { + "name": "Chaos tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5545": { + "name": "Law tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5547": { + "name": "Death tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "5553": { + "name": "Rogue top", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 10, + "dcrush": 10, + "dmagic": 10, + "drange": 10 + } + }, + "5554": { + "name": "Rogue mask", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5 + } + }, + "5555": { + "name": "Rogue trousers", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 7, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "dmagic": 7, + "drange": 7 + } + }, + "5556": { + "name": "Rogue gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": 2 + } + }, + "5557": { + "name": "Rogue boots", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 10, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": 2 + } + }, + "5558": { + "name": "Rogue kit" + }, + "5559": { + "name": "Flash powder" + }, + "5560": { + "name": "Stethoscope", + "weight": 0.453 + }, + "5561": { + "name": "Mystic jewel", + "weight": 0.002 + }, + "5568": { + "name": "Tile", + "weight": 0.453 + }, + "5569": { + "name": "Tiles", + "weight": 0.453 + }, + "5570": { + "name": "Tiles", + "weight": 0.453 + }, + "5571": { + "name": "Tiles", + "weight": 0.453 + }, + "5574": { + "name": "Initiate sallet", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 13, + "dslash": 14, + "dcrush": 11, + "dmagic": -1, + "drange": 13, + "prayer": 3 + } + }, + "5575": { + "name": "Initiate hauberk", + "quest": true, + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 46, + "dslash": 44, + "dcrush": 38, + "dmagic": -6, + "drange": 44, + "prayer": 6 + } + }, + "5576": { + "name": "Initiate cuisse", + "equipable": true, + "weight": 7.711, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22, + "prayer": 5 + } + }, + "5577": { + "name": "Cupric sulfate", + "quest": true, + "weight": 0.056 + }, + "5578": { + "name": "Acetic acid", + "quest": true, + "weight": 0.056 + }, + "5579": { + "name": "Gypsum", + "quest": true, + "weight": 0.056 + }, + "5580": { + "name": "Sodium chloride", + "quest": true, + "weight": 0.056 + }, + "5581": { + "name": "Nitrous oxide", + "quest": true, + "weight": 0.056 + }, + "5582": { + "name": "Vial of liquid", + "quest": true, + "weight": 0.056 + }, + "5583": { + "name": "Tin ore powder", + "quest": true, + "weight": 0.056 + }, + "5584": { + "name": "Cupric ore powder", + "quest": true, + "weight": 0.056 + }, + "5585": { + "name": "Bronze key", + "quest": true, + "weight": 0.01 + }, + "5586": { + "name": "Metal spade", + "quest": true, + "weight": 1.814 + }, + "5587": { + "name": "Metal spade", + "quest": true, + "weight": 1.814 + }, + "5588": { + "name": "Alchemical notes", + "quest": true, + "weight": 0.51 + }, + "5589": { + "name": "??? mixture", + "quest": true, + "weight": 0.056 + }, + "5590": { + "name": "??? mixture", + "quest": true, + "weight": 0.056 + }, + "5591": { + "name": "??? mixture", + "quest": true, + "weight": 0.056 + }, + "5592": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5593": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5594": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5595": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5596": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5597": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5598": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5599": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5600": { + "name": "Tin", + "quest": true, + "weight": 0.1 + }, + "5601": { + "name": "Chisel", + "quest": true, + "weight": 0.453 + }, + "5602": { + "name": "Bronze wire", + "quest": true, + "weight": 0.005 + }, + "5603": { + "name": "Shears", + "quest": true, + "weight": 0.113 + }, + "5604": { + "name": "Magnet", + "quest": true, + "weight": 0.02 + }, + "5605": { + "name": "Knife", + "quest": true, + "weight": 0.02 + }, + "5606": { + "name": "Makeover voucher", + "quest": true, + "weight": 0.005 + }, + "5607": { + "name": "Grain", + "quest": true, + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 1 + } + }, + "5608": { + "name": "Fox", + "quest": true, + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "5609": { + "name": "Chicken", + "quest": true, + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5 + } + }, + "5610": { + "name": "Hourglass", + "quest": true, + "weight": 0.1 + }, + "5615": { + "name": "Bonemeal", + "weight": 1.0 + }, + "5616": { + "name": "Bronze arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "5617": { + "name": "Iron arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "5618": { + "name": "Steel arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "5619": { + "name": "Mithril arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "5620": { + "name": "Adamant arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "5621": { + "name": "Rune arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "5622": { + "name": "Bronze arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "5623": { + "name": "Iron arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "5624": { + "name": "Steel arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "5625": { + "name": "Mithril arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 22 + } + }, + "5626": { + "name": "Adamant arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "5627": { + "name": "Rune arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "5628": { + "name": "Bronze dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 3, + "rstr": 1, + "aspeed": 3 + } + }, + "5629": { + "name": "Iron dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "5630": { + "name": "Steel dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "5631": { + "name": "Black dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 7, + "rstr": 6, + "aspeed": 3 + } + }, + "5632": { + "name": "Mithril dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "5633": { + "name": "Adamant dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "5634": { + "name": "Rune dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "5635": { + "name": "Bronze dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 3, + "rstr": 1, + "aspeed": 3 + } + }, + "5636": { + "name": "Iron dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "5637": { + "name": "Steel dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "5638": { + "name": "Black dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 7, + "rstr": 6, + "aspeed": 3 + } + }, + "5639": { + "name": "Mithril dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "5640": { + "name": "Adamant dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "5641": { + "name": "Rune dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "5642": { + "name": "Bronze javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 25 + } + }, + "5643": { + "name": "Iron javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 42 + } + }, + "5644": { + "name": "Steel javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "5645": { + "name": "Mithril javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 85 + } + }, + "5646": { + "name": "Adamant javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 107 + } + }, + "5647": { + "name": "Rune javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 124 + } + }, + "5648": { + "name": "Bronze javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 25 + } + }, + "5649": { + "name": "Iron javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 42 + } + }, + "5650": { + "name": "Steel javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "5651": { + "name": "Mithril javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 85 + } + }, + "5652": { + "name": "Adamant javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 107 + } + }, + "5653": { + "name": "Rune javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 124 + } + }, + "5654": { + "name": "Bronze knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "5655": { + "name": "Iron knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "5656": { + "name": "Steel knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "5657": { + "name": "Mithril knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "5658": { + "name": "Black knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 10, + "rstr": 8, + "aspeed": 3 + } + }, + "5659": { + "name": "Adamant knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "5660": { + "name": "Rune knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 25, + "rstr": 24, + "aspeed": 3 + } + }, + "5661": { + "name": "Bronze knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 4, + "rstr": 3, + "aspeed": 3 + } + }, + "5662": { + "name": "Iron knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 5, + "rstr": 4, + "aspeed": 3 + } + }, + "5663": { + "name": "Steel knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 8, + "rstr": 7, + "aspeed": 3 + } + }, + "5664": { + "name": "Mithril knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 11, + "rstr": 10, + "aspeed": 3 + } + }, + "5665": { + "name": "Black knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 10, + "rstr": 8, + "aspeed": 3 + } + }, + "5666": { + "name": "Adamant knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 15, + "rstr": 14, + "aspeed": 3 + } + }, + "5667": { + "name": "Rune knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 25, + "rstr": 24, + "aspeed": 3 + } + }, + "5668": { + "name": "Iron dagger(p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "5670": { + "name": "Bronze dagger(p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 2, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 3, + "aspeed": 4 + } + }, + "5672": { + "name": "Steel dagger(p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 4, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "5674": { + "name": "Mithril dagger(p+)", + "equipable": true, + "weight": 0.396, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 10, + "aspeed": 4 + } + }, + "5676": { + "name": "Adamant dagger(p+)", + "equipable": true, + "weight": 0.51, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 8, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 14, + "aspeed": 4 + } + }, + "5678": { + "name": "Rune dagger(p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 25, + "aslash": 12, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 24, + "aspeed": 4 + } + }, + "5680": { + "name": "Dragon dagger(p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 25, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 40, + "aspeed": 4 + } + }, + "5682": { + "name": "Black dagger(p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "5686": { + "name": "Iron dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "5688": { + "name": "Bronze dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 2, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 3, + "aspeed": 4 + } + }, + "5690": { + "name": "Steel dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 4, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "5692": { + "name": "Mithril dagger(p++)", + "equipable": true, + "weight": 0.396, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 10, + "aspeed": 4 + } + }, + "5694": { + "name": "Adamant dagger(p++)", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 8, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 14, + "aspeed": 4 + } + }, + "5696": { + "name": "Rune dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 25, + "aslash": 12, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 24, + "aspeed": 4 + } + }, + "5698": { + "name": "Dragon dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 25, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 40, + "aspeed": 4 + } + }, + "5700": { + "name": "Black dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "aspeed": 4 + } + }, + "5704": { + "name": "Bronze spear(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": 1, + "dslash": 1, + "str": 6, + "aspeed": 5 + } + }, + "5706": { + "name": "Iron spear(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": 1, + "dslash": 1, + "str": 10, + "aspeed": 5 + } + }, + "5708": { + "name": "Steel spear(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "5710": { + "name": "Mithril spear(p+)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": 1, + "dslash": 1, + "str": 18, + "aspeed": 5 + } + }, + "5712": { + "name": "Adamant spear(p+)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": 1, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "5714": { + "name": "Rune spear(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "5716": { + "name": "Dragon spear(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5, + "str": 60, + "aspeed": 5 + } + }, + "5718": { + "name": "Bronze spear(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": 1, + "dslash": 1, + "str": 6, + "aspeed": 5 + } + }, + "5720": { + "name": "Iron spear(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": 1, + "dslash": 1, + "str": 10, + "aspeed": 5 + } + }, + "5722": { + "name": "Steel spear(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "5724": { + "name": "Mithril spear(p++)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": 1, + "dslash": 1, + "str": 18, + "aspeed": 5 + } + }, + "5726": { + "name": "Adamant spear(p++)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": 1, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "5728": { + "name": "Rune spear(p++)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "5730": { + "name": "Dragon spear(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5, + "str": 60, + "aspeed": 5 + } + }, + "5733": { + "name": "Rotten potato", + "weight": 1.814 + }, + "5734": { + "name": "Black spear(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 15, + "acrush": 15, + "dstab": 1, + "dslash": 1, + "str": 16, + "aspeed": 5 + } + }, + "5736": { + "name": "Black spear(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": 15, + "acrush": 15, + "dstab": 1, + "dslash": 1, + "str": 16, + "aspeed": 5 + } + }, + "5739": { + "name": "Asgarnian ale(m)", + "weight": 0.55 + }, + "5741": { + "name": "Mature wmb", + "weight": 0.55 + }, + "5743": { + "name": "Greenman's ale(m)", + "weight": 0.55 + }, + "5745": { + "name": "Dragon bitter(m)" + }, + "5747": { + "name": "Dwarven stout(m)", + "weight": 0.55 + }, + "5749": { + "name": "Moonlight mead(m)", + "weight": 0.55 + }, + "5751": { + "name": "Axeman's folly", + "weight": 0.55 + }, + "5753": { + "name": "Axeman's folly(m)", + "weight": 0.55 + }, + "5755": { + "name": "Chef's delight", + "weight": 0.55 + }, + "5757": { + "name": "Chef's delight(m)", + "weight": 0.55 + }, + "5759": { + "name": "Slayer's respite", + "weight": 0.55 + }, + "5761": { + "name": "Slayer's respite(m)", + "weight": 0.55 + }, + "5763": { + "name": "Cider", + "weight": 0.55 + }, + "5765": { + "name": "Mature cider", + "weight": 0.55 + }, + "5767": { + "name": "Ale yeast", + "weight": 2.834 + }, + "5769": { + "name": "Calquat keg", + "weight": 0.028 + }, + "5771": { + "name": "Dwarven stout(1)", + "weight": 0.028 + }, + "5773": { + "name": "Dwarven stout(2)", + "weight": 0.028 + }, + "5775": { + "name": "Dwarven stout(3)", + "weight": 0.028 + }, + "5777": { + "name": "Dwarven stout(4)", + "weight": 0.028 + }, + "5779": { + "name": "Asgarnian ale(1)" + }, + "5781": { + "name": "Asgarnian ale(2)", + "weight": 0.028 + }, + "5783": { + "name": "Asgarnian ale(3)", + "weight": 0.028 + }, + "5785": { + "name": "Asgarnian ale(4)", + "weight": 0.028 + }, + "5787": { + "name": "Greenmans ale(1)", + "weight": 0.028 + }, + "5789": { + "name": "Greenmans ale(2)", + "weight": 0.028 + }, + "5791": { + "name": "Greenmans ale(3)", + "weight": 0.028 + }, + "5793": { + "name": "Greenmans ale(4)", + "weight": 0.028 + }, + "5795": { + "name": "Mind bomb(1)", + "weight": 0.028 + }, + "5797": { + "name": "Mind bomb(2)", + "weight": 0.028 + }, + "5799": { + "name": "Mind bomb(3)", + "weight": 0.028 + }, + "5801": { + "name": "Mind bomb(4)", + "weight": 0.028 + }, + "5803": { + "name": "Dragon bitter(1)", + "weight": 0.028 + }, + "5805": { + "name": "Dragon bitter(2)", + "weight": 0.028 + }, + "5807": { + "name": "Dragon bitter(3)", + "weight": 0.028 + }, + "5809": { + "name": "Dragon bitter(4)", + "weight": 0.028 + }, + "5811": { + "name": "Moonlight mead(1)", + "weight": 0.028 + }, + "5813": { + "name": "Moonlight mead(2)" + }, + "5815": { + "name": "Moonlight mead(3)", + "weight": 0.028 + }, + "5817": { + "name": "Moonlight mead(4)", + "weight": 0.028 + }, + "5819": { + "name": "Axeman's folly(1)", + "weight": 0.028 + }, + "5821": { + "name": "Axeman's folly(2)", + "weight": 0.028 + }, + "5823": { + "name": "Axeman's folly(3)", + "weight": 0.028 + }, + "5825": { + "name": "Axeman's folly(4)", + "weight": 0.028 + }, + "5827": { + "name": "Chef's delight(1)", + "weight": 0.028 + }, + "5829": { + "name": "Chef's delight(2)", + "weight": 0.028 + }, + "5831": { + "name": "Chef's delight(3)", + "weight": 0.028 + }, + "5833": { + "name": "Chef's delight(4)", + "weight": 0.028 + }, + "5835": { + "name": "Slayer's respite(1)", + "weight": 0.028 + }, + "5837": { + "name": "Slayer's respite(2)", + "weight": 0.028 + }, + "5839": { + "name": "Slayer's respite(3)", + "weight": 0.028 + }, + "5841": { + "name": "Slayer's respite(4)", + "weight": 0.028 + }, + "5843": { + "name": "Cider(1)", + "weight": 0.028 + }, + "5845": { + "name": "Cider(2)", + "weight": 0.028 + }, + "5847": { + "name": "Cider(3)" + }, + "5849": { + "name": "Cider(4)", + "weight": 0.028 + }, + "5851": { + "name": "Dwarven stout(m1)", + "weight": 0.028 + }, + "5853": { + "name": "Dwarven stout(m2)", + "weight": 0.028 + }, + "5855": { + "name": "Dwarven stout(m3)", + "weight": 0.028 + }, + "5857": { + "name": "Dwarven stout(m4)", + "weight": 0.028 + }, + "5859": { + "name": "Asgarnian ale(m1)", + "weight": 0.028 + }, + "5861": { + "name": "Asgarnian ale(m2)", + "weight": 0.028 + }, + "5863": { + "name": "Asgarnian ale(m3)", + "weight": 0.028 + }, + "5865": { + "name": "Asgarnian ale(m4)", + "weight": 0.028 + }, + "5867": { + "name": "Greenmans ale(m1)", + "weight": 0.028 + }, + "5869": { + "name": "Greenmans ale(m2)", + "weight": 0.028 + }, + "5871": { + "name": "Greenmans ale(m3)", + "weight": 0.028 + }, + "5873": { + "name": "Greenmans ale(m4)", + "weight": 0.028 + }, + "5875": { + "name": "Mind bomb(m1)", + "weight": 0.028 + }, + "5877": { + "name": "Mind bomb(m2)", + "weight": 0.028 + }, + "5879": { + "name": "Mind bomb(m3)", + "weight": 0.028 + }, + "5881": { + "name": "Mind bomb(m4)" + }, + "5883": { + "name": "Dragon bitter(m1)", + "weight": 0.028 + }, + "5885": { + "name": "Dragon bitter(m2)", + "weight": 0.028 + }, + "5887": { + "name": "Dragon bitter(m3)", + "weight": 0.028 + }, + "5889": { + "name": "Dragon bitter(m4)", + "weight": 0.028 + }, + "5891": { + "name": "Moonlight mead(m1)", + "weight": 0.028 + }, + "5893": { + "name": "Moonlight mead(m2)", + "weight": 0.028 + }, + "5895": { + "name": "Moonlight mead(m3)", + "weight": 0.028 + }, + "5897": { + "name": "Moonlight mead(m4)", + "weight": 0.028 + }, + "5899": { + "name": "Axeman's folly(m1)", + "weight": 0.028 + }, + "5901": { + "name": "Axeman's folly(m2)", + "weight": 0.028 + }, + "5903": { + "name": "Axeman's folly(m3)", + "weight": 0.028 + }, + "5905": { + "name": "Axeman's folly(m4)", + "weight": 0.028 + }, + "5907": { + "name": "Chef's delight(m1)", + "weight": 0.028 + }, + "5909": { + "name": "Chef's delight(m2)", + "weight": 0.028 + }, + "5911": { + "name": "Chef's delight(m3)", + "weight": 0.028 + }, + "5913": { + "name": "Chef's delight(m4)", + "weight": 0.028 + }, + "5915": { + "name": "Slayer's respite(m1)" + }, + "5917": { + "name": "Slayer's respite(m2)", + "weight": 0.028 + }, + "5919": { + "name": "Slayer's respite(m3)", + "weight": 0.028 + }, + "5921": { + "name": "Slayer's respite(m4)", + "weight": 0.028 + }, + "5923": { + "name": "Cider(m1)", + "weight": 0.028 + }, + "5925": { + "name": "Cider(m2)", + "weight": 0.028 + }, + "5927": { + "name": "Cider(m3)", + "weight": 0.028 + }, + "5929": { + "name": "Cider(m4)", + "weight": 0.028 + }, + "5931": { + "name": "Jute fibre", + "weight": 0.226 + }, + "5933": { + "name": "Willow branch", + "weight": 0.907 + }, + "5935": { + "name": "Coconut milk", + "weight": 0.035 + }, + "5936": { + "name": "Weapon poison+ (unf)", + "weight": 0.035 + }, + "5937": { + "name": "Weapon poison(+)", + "weight": 0.035 + }, + "5939": { + "name": "Weapon poison++ (unf)", + "weight": 0.035 + }, + "5940": { + "name": "Weapon poison(++)", + "weight": 0.035 + }, + "5942": { + "name": "Antidote+ (unf)", + "weight": 0.035 + }, + "5943": { + "name": "Antidote+(4)", + "weight": 0.035 + }, + "5945": { + "name": "Antidote+(3)", + "weight": 0.03 + }, + "5947": { + "name": "Antidote+(2)", + "weight": 0.025 + }, + "5949": { + "name": "Antidote+(1)", + "weight": 0.02 + }, + "5951": { + "name": "Antidote++ (unf)", + "weight": 0.035 + }, + "5952": { + "name": "Antidote++(4)", + "weight": 0.035 + }, + "5954": { + "name": "Antidote++(3)", + "weight": 0.035 + }, + "5956": { + "name": "Antidote++(2)", + "weight": 0.035 + }, + "5958": { + "name": "Antidote++(1)", + "weight": 0.035 + }, + "5960": { + "name": "Tomatoes(1)", + "weight": 0.056 + }, + "5962": { + "name": "Tomatoes(2)", + "weight": 0.085 + }, + "5964": { + "name": "Tomatoes(3)", + "weight": 0.113 + }, + "5966": { + "name": "Tomatoes(4)", + "weight": 0.141 + }, + "5968": { + "name": "Tomatoes(5)", + "weight": 0.17 + }, + "5970": { + "name": "Curry leaf", + "weight": 0.028 + }, + "5972": { + "name": "Papaya fruit", + "weight": 0.028 + }, + "5974": { + "name": "Coconut", + "weight": 0.028 + }, + "5976": { + "name": "Half coconut", + "weight": 0.028 + }, + "5978": { + "name": "Coconut shell", + "weight": 0.028 + }, + "5980": { + "name": "Calquat fruit", + "weight": 0.028 + }, + "5982": { + "name": "Watermelon", + "weight": 0.113 + }, + "5984": { + "name": "Watermelon slice", + "weight": 0.028 + }, + "5986": { + "name": "Sweetcorn", + "weight": 0.028 + }, + "5988": { + "name": "Cooked sweetcorn", + "weight": 0.028 + }, + "5990": { + "name": "Burnt sweetcorn" + }, + "5992": { + "name": "Apple mush", + "weight": 1.1 + }, + "5994": { + "name": "Hammerstone hops", + "weight": 0.028 + }, + "5996": { + "name": "Asgarnian hops", + "weight": 0.028 + }, + "5998": { + "name": "Yanillian hops", + "weight": 0.028 + }, + "6000": { + "name": "Krandorian hops" + }, + "6002": { + "name": "Wildblood hops", + "weight": 0.028 + }, + "6004": { + "name": "Mushroom", + "weight": 0.028 + }, + "6006": { + "name": "Barley", + "weight": 0.028 + }, + "6008": { + "name": "Barley malt", + "weight": 0.028 + }, + "6010": { + "name": "Marigolds", + "weight": 0.028 + }, + "6012": { + "name": "Nasturtiums", + "weight": 0.028 + }, + "6014": { + "name": "Rosemary", + "weight": 0.028 + }, + "6016": { + "name": "Cactus spine", + "weight": 0.028 + }, + "6018": { + "name": "Poison ivy berries", + "weight": 0.007 + }, + "6020": { + "name": "Leaves", + "weight": 0.028 + }, + "6022": { + "name": "Leaves", + "weight": 0.028 + }, + "6024": { + "name": "Leaves", + "weight": 0.028 + }, + "6026": { + "name": "Leaves", + "weight": 0.028 + }, + "6028": { + "name": "Leaves", + "weight": 0.028 + }, + "6030": { + "name": "Leaves", + "weight": 0.028 + }, + "6032": { + "name": "Compost", + "weight": 3.0 + }, + "6034": { + "name": "Supercompost", + "weight": 3.0 + }, + "6036": { + "name": "Plant cure", + "weight": 0.035 + }, + "6038": { + "name": "Magic string", + "weight": 0.014 + }, + "6040": { + "name": "Amulet of nature", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "6041": { + "name": "Pre-nature amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "6043": { + "name": "Oak roots", + "weight": 0.001 + }, + "6045": { + "name": "Willow roots", + "weight": 0.001 + }, + "6047": { + "name": "Maple roots", + "weight": 0.001 + }, + "6049": { + "name": "Yew roots", + "weight": 0.001 + }, + "6051": { + "name": "Magic roots" + }, + "6055": { + "name": "Weeds" + }, + "6057": { + "name": "Hay sack", + "weight": 0.113 + }, + "6058": { + "name": "Hay sack", + "weight": 0.113 + }, + "6059": { + "name": "Scarecrow", + "weight": 0.113 + }, + "6061": { + "name": "Bronze bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "6062": { + "name": "Bronze bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 10 + } + }, + "6064": { + "name": "Bloody mourner top", + "quest": true, + "weight": 2.721 + }, + "6065": { + "name": "Mourner top", + "quest": true, + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4 + } + }, + "6066": { + "name": "Mourner trousers", + "quest": true, + "weight": 2.267 + }, + "6067": { + "name": "Mourner trousers", + "quest": true, + "weight": 2.267 + }, + "6068": { + "name": "Mourner gloves", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "6069": { + "name": "Mourner boots", + "quest": true, + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "6070": { + "name": "Mourner cloak", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 1 + } + }, + "6071": { + "name": "Mourner letter", + "quest": true, + "weight": 0.01 + }, + "6072": { + "name": "Tegid's soap", + "quest": true, + "weight": 0.113 + }, + "6073": { + "name": "Prifddinas' history", + "quest": true, + "weight": 0.51 + }, + "6075": { + "name": "Eastern discovery", + "weight": 0.51 + }, + "6077": { + "name": "Eastern settlement", + "quest": true, + "weight": 0.51 + }, + "6079": { + "name": "The great divide", + "weight": 0.51 + }, + "6081": { + "name": "Broken device", + "quest": true, + "weight": 4.0 + }, + "6082": { + "name": "Fixed device", + "quest": true, + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "6083": { + "name": "Tarnished key", + "quest": true, + "weight": 0.01 + }, + "6085": { + "name": "Red dye bellows", + "quest": true + }, + "6086": { + "name": "Blue dye bellows", + "quest": true, + "weight": 0.538 + }, + "6087": { + "name": "Yellow dye bellows", + "quest": true, + "weight": 0.538 + }, + "6088": { + "name": "Green dye bellows", + "quest": true, + "weight": 0.538 + }, + "6089": { + "name": "Blue toad", + "quest": true, + "weight": 0.75 + }, + "6090": { + "name": "Red toad", + "quest": true, + "weight": 0.75 + }, + "6091": { + "name": "Yellow toad", + "quest": true, + "weight": 0.75 + }, + "6092": { + "name": "Green toad", + "quest": true, + "weight": 0.75 + }, + "6093": { + "name": "Rotten apples", + "quest": true, + "weight": 15.0 + }, + "6094": { + "name": "Apple barrel", + "weight": 15.0 + }, + "6095": { + "name": "Naphtha apple mix", + "quest": true, + "weight": 32.0 + }, + "6096": { + "name": "Toxic naphtha", + "quest": true, + "weight": 32.0 + }, + "6097": { + "name": "Sieve", + "weight": 0.001 + }, + "6098": { + "name": "Toxic powder", + "quest": true, + "weight": 0.056 + }, + "6099": { + "name": "Teleport crystal (4)", + "weight": 0.001 + }, + "6100": { + "name": "Teleport crystal (3)", + "weight": 0.001 + }, + "6101": { + "name": "Teleport crystal (2)", + "weight": 0.001 + }, + "6102": { + "name": "Teleport crystal (1)" + }, + "6103": { + "name": "Tiny elf crystal", + "weight": 0.001 + }, + "6104": { + "name": "New key", + "quest": true, + "weight": 0.01 + }, + "6106": { + "name": "Ghostly boots", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 10, + "amagic": 2, + "dmagic": 2 + } + }, + "6107": { + "name": "Ghostly robe", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 4, + "amagic": 5, + "dmagic": 5 + } + }, + "6108": { + "name": "Ghostly robe", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4 + } + }, + "6109": { + "name": "Ghostly hood", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "6110": { + "name": "Ghostly gloves", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 9, + "amagic": 2, + "dmagic": 2 + } + }, + "6111": { + "name": "Ghostly cloak", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 1, + "amagic": 5, + "dmagic": 5 + } + }, + "6112": { + "name": "Kelda seed", + "quest": true + }, + "6113": { + "name": "Kelda hops", + "quest": true, + "weight": 0.028 + }, + "6118": { + "name": "Kelda stout", + "quest": true, + "weight": 0.55 + }, + "6119": { + "name": "Square stone", + "quest": true, + "weight": 1.0 + }, + "6120": { + "name": "Square stone", + "quest": true, + "weight": 1.0 + }, + "6121": { + "name": "Letter", + "quest": true, + "weight": 0.001 + }, + "6122": { + "name": "A chair", + "quest": true, + "equipable": true, + "weight": 0.001 + }, + "6123": { + "name": "Beer glass", + "quest": true, + "equipable": true, + "weight": 0.001 + }, + "6125": { + "name": "Enchanted lyre(2)", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "6126": { + "name": "Enchanted lyre(3)", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "6127": { + "name": "Enchanted lyre(4)", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "6128": { + "name": "Rock-shell helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "6129": { + "name": "Rock-shell plate", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "6130": { + "name": "Rock-shell legs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "6131": { + "name": "Spined helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "astab": -6, + "aslash": -6, + "acrush": -6, + "amagic": -6, + "arange": 6, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6 + } + }, + "6133": { + "name": "Spined body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 15, + "dstab": 40, + "dslash": 32, + "dcrush": 45, + "dmagic": 20, + "drange": 40 + } + }, + "6135": { + "name": "Spined chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 8, + "dstab": 22, + "dslash": 16, + "dcrush": 24, + "dmagic": 8, + "drange": 22 + } + }, + "6137": { + "name": "Skeletal helm", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 0, + "amagic": 2, + "arange": -2, + "dstab": 10, + "dslash": 9, + "dcrush": 11, + "dmagic": 3 + } + }, + "6139": { + "name": "Skeletal top", + "equipable": true, + "weight": 4.989, + "equipment": { + "slot": 4, + "amagic": 8, + "arange": -10, + "dstab": 35, + "dslash": 25, + "dcrush": 42, + "dmagic": 15 + } + }, + "6141": { + "name": "Skeletal bottoms", + "equipable": true, + "weight": 4.082, + "equipment": { + "slot": 7, + "amagic": 6, + "arange": -7, + "dstab": 22, + "dslash": 20, + "dcrush": 24, + "dmagic": 10 + } + }, + "6143": { + "name": "Spined boots", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "6145": { + "name": "Rock-shell boots", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "6147": { + "name": "Skeletal boots", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "6149": { + "name": "Spined gloves", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "6151": { + "name": "Rock-shell gloves", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "6153": { + "name": "Skeletal gloves", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "6155": { + "name": "Dagannoth hide", + "weight": 3.175 + }, + "6157": { + "name": "Rock-shell chunk", + "weight": 3.175 + }, + "6159": { + "name": "Rock-shell shard", + "weight": 3.175 + }, + "6161": { + "name": "Rock-shell splinter", + "weight": 3.175 + }, + "6163": { + "name": "Skull piece", + "weight": 3.175 + }, + "6165": { + "name": "Ribcage piece", + "weight": 3.175 + }, + "6167": { + "name": "Fibula piece", + "weight": 3.175 + }, + "6169": { + "name": "Circular hide", + "weight": 3.175 + }, + "6171": { + "name": "Flattened hide", + "weight": 3.175 + }, + "6173": { + "name": "Stretched hide", + "weight": 3.175 + }, + "6178": { + "name": "Raw pheasant", + "weight": 10.0 + }, + "6179": { + "name": "Raw pheasant", + "weight": 10.0 + }, + "6180": { + "name": "Lederhosen top", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 4 + } + }, + "6181": { + "name": "Lederhosen shorts", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 7 + } + }, + "6182": { + "name": "Lederhosen hat", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0 + } + }, + "6183": { + "name": "Frog token", + "weight": 0.01 + }, + "6184": { + "name": "Prince tunic", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4 + } + }, + "6185": { + "name": "Prince leggings", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 7 + } + }, + "6186": { + "name": "Princess blouse", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4 + } + }, + "6187": { + "name": "Princess skirt", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7 + } + }, + "6188": { + "name": "Frog mask", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "6199": { + "name": "Mystery box", + "weight": 1.0 + }, + "6200": { + "name": "Raw fishlike thing", + "weight": 0.7 + }, + "6202": { + "name": "Fishlike thing", + "weight": 0.7 + }, + "6204": { + "name": "Raw fishlike thing", + "weight": 0.7 + }, + "6206": { + "name": "Fishlike thing", + "weight": 0.7 + }, + "6209": { + "name": "Small fishing net", + "weight": 4.535 + }, + "6211": { + "name": "Teak pyre logs", + "weight": 1.36 + }, + "6213": { + "name": "Mahogany pyre log", + "weight": 1.36 + }, + "6215": { + "name": "Broodoo shield (10)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6217": { + "name": "Broodoo shield (9)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6219": { + "name": "Broodoo shield (8)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6221": { + "name": "Broodoo shield (7)", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6223": { + "name": "Broodoo shield (6)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6225": { + "name": "Broodoo shield (5)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6227": { + "name": "Broodoo shield (4)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6229": { + "name": "Broodoo shield (3)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6231": { + "name": "Broodoo shield (2)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6233": { + "name": "Broodoo shield (1)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6235": { + "name": "Broodoo shield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6237": { + "name": "Broodoo shield (10)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6239": { + "name": "Broodoo shield (9)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6241": { + "name": "Broodoo shield (8)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6243": { + "name": "Broodoo shield (7)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6245": { + "name": "Broodoo shield (6)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6247": { + "name": "Broodoo shield (5)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6249": { + "name": "Broodoo shield (4)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6251": { + "name": "Broodoo shield (3)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6253": { + "name": "Broodoo shield (2)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6255": { + "name": "Broodoo shield (1)", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6257": { + "name": "Broodoo shield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6259": { + "name": "Broodoo shield (10)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6261": { + "name": "Broodoo shield (9)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6263": { + "name": "Broodoo shield (8)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6265": { + "name": "Broodoo shield (7)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6267": { + "name": "Broodoo shield (6)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6269": { + "name": "Broodoo shield (5)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6271": { + "name": "Broodoo shield (4)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6273": { + "name": "Broodoo shield (3)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6275": { + "name": "Broodoo shield (2)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6277": { + "name": "Broodoo shield (1)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6279": { + "name": "Broodoo shield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": 3, + "arange": -7, + "dstab": 10, + "dslash": 10, + "dcrush": 15, + "dmagic": 5, + "prayer": 5 + } + }, + "6281": { + "name": "Thatch spar light", + "weight": 0.1 + }, + "6283": { + "name": "Thatch spar med", + "weight": 0.1 + }, + "6285": { + "name": "Thatch spar dense", + "weight": 0.1 + }, + "6287": { + "name": "Snake hide", + "weight": 0.5 + }, + "6289": { + "name": "Snakeskin", + "weight": 0.5 + }, + "6291": { + "name": "Spider carcass", + "weight": 0.8 + }, + "6293": { + "name": "Spider on stick", + "weight": 0.9 + }, + "6295": { + "name": "Spider on shaft", + "weight": 0.9 + }, + "6297": { + "name": "Spider on stick", + "weight": 0.9 + }, + "6299": { + "name": "Spider on shaft", + "weight": 0.9 + }, + "6301": { + "name": "Burnt spider" + }, + "6303": { + "name": "Spider on shaft" + }, + "6305": { + "name": "Skewer stick" + }, + "6306": { + "name": "Trading sticks" + }, + "6311": { + "name": "Gout tuber", + "weight": 0.2 + }, + "6313": { + "name": "Opal machete", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "aslash": 8, + "acrush": -2, + "dslash": 1, + "dcrush": 1, + "str": 4, + "aspeed": 5 + } + }, + "6315": { + "name": "Jade machete", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "aslash": 11, + "acrush": -2, + "dslash": 1, + "dcrush": 1, + "str": 6, + "aspeed": 4 + } + }, + "6317": { + "name": "Red topaz machete", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "aslash": 16, + "acrush": -2, + "dslash": 1, + "dcrush": 1, + "drange": 1, + "str": 10, + "aspeed": 4 + } + }, + "6319": { + "name": "Proboscis" + }, + "6322": { + "name": "Snakeskin body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -5, + "arange": 12, + "dstab": 25, + "dslash": 28, + "dcrush": 32, + "dmagic": 15, + "drange": 35 + } + }, + "6324": { + "name": "Snakeskin chaps", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 7, + "amagic": -5, + "arange": 6, + "dstab": 8, + "dslash": 8, + "dcrush": 10, + "dmagic": 4, + "drange": 10 + } + }, + "6326": { + "name": "Snakeskin bandana", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": 4, + "dstab": 2, + "dslash": 4, + "dcrush": 4, + "dmagic": 2, + "drange": 2 + } + }, + "6328": { + "name": "Snakeskin boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 3, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 1 + } + }, + "6330": { + "name": "Snakeskin vambraces", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -5, + "arange": 6, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 1 + } + }, + "6332": { + "name": "Mahogany logs", + "weight": 1.36 + }, + "6333": { + "name": "Teak logs", + "equipable": true, + "weight": 1.36 + }, + "6335": { + "name": "Tribal mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "6337": { + "name": "Tribal mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "6339": { + "name": "Tribal mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "6341": { + "name": "Tribal top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "6343": { + "name": "Villager robe", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7 + } + }, + "6345": { + "name": "Villager hat", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0 + } + }, + "6347": { + "name": "Villager armband", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 9 + } + }, + "6349": { + "name": "Villager sandals", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 10 + } + }, + "6351": { + "name": "Tribal top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "6353": { + "name": "Villager robe", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7 + } + }, + "6355": { + "name": "Villager hat", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0 + } + }, + "6357": { + "name": "Villager sandals", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 10 + } + }, + "6359": { + "name": "Villager armband", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 9 + } + }, + "6361": { + "name": "Tribal top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "6363": { + "name": "Villager robe", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7 + } + }, + "6365": { + "name": "Villager hat", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0 + } + }, + "6367": { + "name": "Villager sandals", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 10 + } + }, + "6369": { + "name": "Villager armband", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 9 + } + }, + "6371": { + "name": "Tribal top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "6373": { + "name": "Villager robe", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7 + } + }, + "6375": { + "name": "Villager hat", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0 + } + }, + "6377": { + "name": "Villager sandals", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 10 + } + }, + "6379": { + "name": "Villager armband", + "equipable": true, + "weight": 0.68, + "equipment": { + "slot": 9 + } + }, + "6382": { + "name": "Fez", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 0 + } + }, + "6384": { + "name": "Desert top", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 4 + } + }, + "6386": { + "name": "Desert robes", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6388": { + "name": "Desert top", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 4 + } + }, + "6390": { + "name": "Desert legs", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6392": { + "name": "Menaphite purple hat", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 0 + } + }, + "6394": { + "name": "Menaphite purple top", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 4 + } + }, + "6396": { + "name": "Menaphite purple robe", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6398": { + "name": "Menaphite purple kilt", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6400": { + "name": "Menaphite red hat", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 0 + } + }, + "6402": { + "name": "Menaphite red top", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 4 + } + }, + "6404": { + "name": "Menaphite red robe", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6406": { + "name": "Menaphite red kilt", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6408": { + "name": "Oak blackjack(o)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "acrush": 4, + "str": 4, + "aspeed": 4 + } + }, + "6410": { + "name": "Oak blackjack(d)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "dcrush": 4, + "str": 4, + "aspeed": 4 + } + }, + "6412": { + "name": "Willow blackjack(o)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "acrush": 8, + "str": 8, + "aspeed": 4 + } + }, + "6414": { + "name": "Willow blackjack(d)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "dcrush": 8, + "str": 8, + "aspeed": 4 + } + }, + "6416": { + "name": "Maple blackjack", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "str": 20, + "aspeed": 4 + } + }, + "6418": { + "name": "Maple blackjack(o)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "acrush": 24, + "str": 20, + "aspeed": 4 + } + }, + "6420": { + "name": "Maple blackjack(d)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "dcrush": 24, + "str": 20, + "aspeed": 4 + } + }, + "6448": { + "name": "Spadeful of coke", + "weight": 1.814 + }, + "6453": { + "name": "White rose seed", + "quest": true + }, + "6454": { + "name": "Red rose seed", + "quest": true + }, + "6455": { + "name": "Pink rose seed", + "quest": true + }, + "6456": { + "name": "Vine seed", + "quest": true + }, + "6457": { + "name": "Delphinium seed", + "quest": true + }, + "6458": { + "name": "Orchid seed", + "quest": true + }, + "6459": { + "name": "Orchid seed", + "quest": true + }, + "6460": { + "name": "Snowdrop seed", + "quest": true + }, + "6461": { + "name": "White tree shoot", + "quest": true, + "weight": 0.001 + }, + "6462": { + "name": "White tree shoot", + "quest": true, + "weight": 0.001 + }, + "6463": { + "name": "White tree shoot (w)", + "quest": true, + "weight": 0.907 + }, + "6464": { + "name": "White tree sapling", + "quest": true, + "weight": 0.907 + }, + "6465": { + "name": "Ring of charos(a)", + "quest": true, + "equipable": true, + "weight": 0.005 + }, + "6466": { + "name": "Rune shards", + "quest": true, + "weight": 0.453 + }, + "6467": { + "name": "Rune dust", + "quest": true, + "weight": 0.002 + }, + "6468": { + "name": "Plant cure", + "quest": true, + "weight": 0.035 + }, + "6469": { + "name": "White tree fruit", + "quest": true, + "weight": 0.028 + }, + "6470": { + "name": "Compost potion(4)", + "weight": 0.035 + }, + "6472": { + "name": "Compost potion(3)", + "weight": 0.03 + }, + "6474": { + "name": "Compost potion(2)", + "weight": 0.025 + }, + "6476": { + "name": "Compost potion(1)", + "weight": 0.02 + }, + "6478": { + "name": "Trolley", + "quest": true, + "weight": 0.08 + }, + "6479": { + "name": "List", + "quest": true, + "weight": 0.001 + }, + "6522": { + "name": "Toktz-xil-ul", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 69, + "rstr": 49, + "aspeed": 4 + } + }, + "6523": { + "name": "Toktz-xil-ak", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 47, + "aslash": 38, + "acrush": -2, + "dstab": 2, + "dslash": 3, + "str": 49, + "aspeed": 4 + } + }, + "6524": { + "name": "Toktz-ket-xil", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -12, + "arange": -8, + "dstab": 40, + "dslash": 42, + "dcrush": 38, + "drange": 65, + "str": 5 + } + }, + "6525": { + "name": "Toktz-xil-ek", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 16, + "aslash": 48, + "str": 39, + "aspeed": 4 + } + }, + "6526": { + "name": "Toktz-mej-tal", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 15, + "aslash": -1, + "acrush": 55, + "amagic": 15, + "dstab": 10, + "dslash": 15, + "dcrush": 5, + "dmagic": 15, + "str": 55, + "prayer": 5, + "aspeed": 6 + } + }, + "6527": { + "name": "Tzhaar-ket-em", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 62, + "str": 56, + "aspeed": 5 + } + }, + "6528": { + "name": "Tzhaar-ket-om", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "acrush": 80, + "amagic": -4, + "str": 85, + "aspeed": 7 + } + }, + "6529": { + "name": "Tokkul" + }, + "6541": { + "name": "Mouse toy", + "quest": true, + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "6542": { + "name": "Present", + "quest": true, + "weight": 2.0 + }, + "6543": { + "name": "Antique lamp", + "quest": true + }, + "6544": { + "name": "Catspeak amulet(e)", + "quest": true, + "equipable": true, + "weight": 1.3, + "equipment": { + "slot": 2 + } + }, + "6545": { + "name": "Chores", + "quest": true, + "weight": 0.005 + }, + "6546": { + "name": "Recipe", + "quest": true, + "weight": 0.005 + }, + "6547": { + "name": "Doctors hat", + "quest": true, + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0 + } + }, + "6548": { + "name": "Nurse hat", + "quest": true, + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 0 + } + }, + "6561": { + "name": "Ahab's beer", + "weight": 0.55 + }, + "6562": { + "name": "Mud battlestaff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "6563": { + "name": "Mystic mud staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "6568": { + "name": "Obsidian cape", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "6570": { + "name": "Fire cape", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 1, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 11, + "dslash": 11, + "dcrush": 11, + "dmagic": 11, + "drange": 11, + "str": 4, + "prayer": 2 + } + }, + "6571": { + "name": "Uncut onyx", + "weight": 0.003 + }, + "6573": { + "name": "Onyx", + "weight": 0.002 + }, + "6575": { + "name": "Onyx ring", + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12 + } + }, + "6577": { + "name": "Onyx necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "6579": { + "name": "Onyx amulet (u)", + "weight": 0.004 + }, + "6581": { + "name": "Onyx amulet", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "6583": { + "name": "Ring of stone", + "weight": 0.006 + }, + "6585": { + "name": "Amulet of fury", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 15, + "dslash": 15, + "dcrush": 15, + "dmagic": 15, + "drange": 15, + "str": 8, + "prayer": 5 + } + }, + "6587": { + "name": "White claws", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 14, + "acrush": -4, + "dstab": 4, + "dslash": 7, + "dcrush": 2, + "str": 14, + "prayer": 1, + "aspeed": 4 + } + }, + "6589": { + "name": "White battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 20, + "acrush": 15, + "drange": -1, + "str": 24, + "prayer": 1, + "aspeed": 6 + } + }, + "6591": { + "name": "White dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "prayer": 1, + "aspeed": 4 + } + }, + "6593": { + "name": "White dagger(p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "prayer": 1, + "aspeed": 4 + } + }, + "6595": { + "name": "White dagger(p+)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "prayer": 1, + "aspeed": 4 + } + }, + "6597": { + "name": "White dagger(p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 5, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 7, + "prayer": 1, + "aspeed": 4 + } + }, + "6599": { + "name": "White halberd", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 19, + "aslash": 25, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 3, + "str": 20, + "prayer": 1, + "aspeed": 7 + } + }, + "6601": { + "name": "White mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": -2, + "acrush": 16, + "str": 13, + "prayer": 3, + "aspeed": 5 + } + }, + "6603": { + "name": "White magic staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 7, + "prayer": 1, + "aspeed": 5 + } + }, + "6605": { + "name": "White sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 14, + "aslash": 10, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 12, + "prayer": 1, + "aspeed": 4 + } + }, + "6607": { + "name": "White longsword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 13, + "aslash": 18, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 16, + "prayer": 1, + "aspeed": 5 + } + }, + "6609": { + "name": "White 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 27, + "acrush": 21, + "amagic": -4, + "drange": -1, + "str": 26, + "prayer": 1, + "aspeed": 7 + } + }, + "6611": { + "name": "White scimitar", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 19, + "acrush": -2, + "dslash": 1, + "str": 14, + "prayer": 1, + "aspeed": 4 + } + }, + "6613": { + "name": "White warhammer", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 22, + "amagic": -4, + "str": 19, + "prayer": 1, + "aspeed": 6 + } + }, + "6615": { + "name": "White chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 22, + "dslash": 32, + "dcrush": 39, + "dmagic": -3, + "drange": 24, + "prayer": 1 + } + }, + "6617": { + "name": "White platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40, + "prayer": 1 + } + }, + "6619": { + "name": "White boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 9, + "prayer": 1 + } + }, + "6621": { + "name": "White med helm", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9, + "prayer": 1 + } + }, + "6623": { + "name": "White full helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12, + "prayer": 1 + } + }, + "6625": { + "name": "White platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20, + "prayer": 1 + } + }, + "6627": { + "name": "White plateskirt", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 21, + "dslash": 20, + "dcrush": 19, + "dmagic": -4, + "drange": 20, + "prayer": 1 + } + }, + "6629": { + "name": "White gloves", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2, + "prayer": 1 + } + }, + "6631": { + "name": "White sq shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 15, + "dslash": 16, + "dcrush": 14, + "drange": 15, + "prayer": 1 + } + }, + "6633": { + "name": "White kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18, + "prayer": 1 + } + }, + "6635": { + "name": "Commorb", + "quest": true, + "weight": 0.001 + }, + "6636": { + "name": "Solus's hat", + "quest": true, + "weight": 0.001 + }, + "6638": { + "name": "Colour wheel", + "quest": true, + "weight": 0.001 + }, + "6639": { + "name": "Hand mirror", + "quest": true, + "weight": 0.01 + }, + "6640": { + "name": "Red crystal", + "quest": true, + "weight": 0.015 + }, + "6641": { + "name": "Yellow crystal", + "quest": true, + "weight": 0.015 + }, + "6642": { + "name": "Green crystal", + "quest": true, + "weight": 0.015 + }, + "6643": { + "name": "Cyan crystal", + "quest": true, + "weight": 0.015 + }, + "6644": { + "name": "Blue crystal", + "quest": true, + "weight": 0.015 + }, + "6645": { + "name": "Magenta crystal", + "quest": true, + "weight": 0.015 + }, + "6646": { + "name": "Fractured crystal", + "quest": true + }, + "6647": { + "name": "Fractured crystal", + "quest": true + }, + "6648": { + "name": "Item list", + "quest": true, + "weight": 0.028 + }, + "6649": { + "name": "Edern's journal", + "quest": true, + "weight": 0.226 + }, + "6650": { + "name": "Blackened crystal", + "quest": true, + "weight": 0.015 + }, + "6651": { + "name": "Newly made crystal", + "quest": true, + "weight": 0.015 + }, + "6652": { + "name": "Newly made crystal", + "quest": true, + "weight": 0.015 + }, + "6653": { + "name": "Crystal trinket", + "quest": true, + "weight": 0.01 + }, + "6654": { + "name": "Camo top", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4 + } + }, + "6655": { + "name": "Camo bottoms", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 7 + } + }, + "6656": { + "name": "Camo helmet", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0 + } + }, + "6662": { + "name": "Broken fishing rod", + "weight": 0.907 + }, + "6663": { + "name": "Forlorn boot" + }, + "6664": { + "name": "Fishing explosive" + }, + "6665": { + "name": "Mudskipper hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "6666": { + "name": "Flippers", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "astab": -2, + "aslash": -2, + "acrush": -2, + "dslash": 1, + "dcrush": 1 + } + }, + "6667": { + "name": "Empty fishbowl", + "weight": 1.3 + }, + "6668": { + "name": "Fishbowl", + "weight": 1.3 + }, + "6669": { + "name": "Fishbowl", + "weight": 1.3 + }, + "6673": { + "name": "Fishbowl and net", + "quest": true, + "weight": 2.267 + }, + "6674": { + "name": "Tiny net", + "weight": 0.02 + }, + "6675": { + "name": "An empty box", + "weight": 0.028 + }, + "6677": { + "name": "Guam in a box", + "weight": 0.028 + }, + "6678": { + "name": "Guam in a box", + "weight": 0.028 + }, + "6679": { + "name": "Seaweed in a box", + "weight": 0.028 + }, + "6680": { + "name": "Seaweed in a box", + "weight": 0.028 + }, + "6681": { + "name": "Ground guam", + "weight": 0.056 + }, + "6683": { + "name": "Ground seaweed", + "weight": 0.056 + }, + "6685": { + "name": "Saradomin brew(4)", + "weight": 0.035 + }, + "6687": { + "name": "Saradomin brew(3)", + "weight": 0.03 + }, + "6689": { + "name": "Saradomin brew(2)", + "weight": 0.025 + }, + "6691": { + "name": "Saradomin brew(1)", + "weight": 0.02 + }, + "6693": { + "name": "Crushed nest", + "weight": 0.002 + }, + "6696": { + "name": "Ice cooler" + }, + "6697": { + "name": "Pat of butter", + "weight": 0.2 + }, + "6699": { + "name": "Burnt potato" + }, + "6701": { + "name": "Baked potato", + "weight": 0.5 + }, + "6703": { + "name": "Potato with butter", + "weight": 0.5 + }, + "6705": { + "name": "Potato with cheese", + "weight": 0.5 + }, + "6707": { + "name": "Camulet", + "quest": true, + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2 + } + }, + "6710": { + "name": "Blindweed seed" + }, + "6711": { + "name": "Blindweed", + "quest": true, + "weight": 0.007 + }, + "6712": { + "name": "Bucket of water", + "quest": true, + "weight": 3.0 + }, + "6713": { + "name": "Wrench", + "quest": true, + "weight": 0.005 + }, + "6714": { + "name": "Holy wrench", + "quest": true, + "equipable": true + }, + "6715": { + "name": "Sluglings", + "quest": true, + "weight": 3.0 + }, + "6716": { + "name": "Karamthulhu", + "quest": true, + "weight": 0.001 + }, + "6718": { + "name": "Fever spider body", + "quest": true, + "weight": 0.8 + }, + "6719": { + "name": "Unsanitary swill", + "quest": true, + "weight": 0.007 + }, + "6720": { + "name": "Slayer gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "dstab": 4, + "dslash": 5, + "dcrush": 3 + } + }, + "6721": { + "name": "Rusty scimitar", + "weight": 2.267 + }, + "6722": { + "name": "Zombie head", + "weight": 2.721 + }, + "6724": { + "name": "Seercull", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 69, + "aspeed": 5 + } + }, + "6728": { + "name": "Bonemeal", + "weight": 1.0 + }, + "6729": { + "name": "Dagannoth bones", + "weight": 1.5 + }, + "6731": { + "name": "Seers ring", + "equipable": true, + "equipment": { + "slot": 12, + "amagic": 6, + "dmagic": 6 + } + }, + "6733": { + "name": "Archers ring", + "equipable": true, + "weight": 0.004, + "equipment": { + "slot": 12, + "arange": 4, + "drange": 4 + } + }, + "6735": { + "name": "Warrior ring", + "equipable": true, + "weight": 0.004, + "equipment": { + "slot": 12, + "aslash": 4, + "dslash": 4 + } + }, + "6737": { + "name": "Berserker ring", + "equipable": true, + "weight": 0.004, + "equipment": { + "slot": 12, + "dcrush": 4, + "str": 4 + } + }, + "6739": { + "name": "Dragon axe", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 38, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "6741": { + "name": "Broken axe", + "weight": 0.907 + }, + "6745": { + "name": "Silverlight", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 14, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "dmagic": 1, + "str": 12, + "aspeed": 5 + } + }, + "6746": { + "name": "Darklight", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 16, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "dmagic": 2, + "str": 13, + "aspeed": 5 + } + }, + "6747": { + "name": "Demonic sigil mould", + "quest": true, + "weight": 0.453 + }, + "6748": { + "name": "Demonic sigil", + "quest": true, + "weight": 1.8 + }, + "6749": { + "name": "Demonic tome", + "quest": true, + "weight": 0.453 + }, + "6750": { + "name": "Black desert shirt", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4 + } + }, + "6752": { + "name": "Black desert robe", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "6754": { + "name": "Enchanted key", + "quest": true, + "weight": 0.01 + }, + "6755": { + "name": "Journal", + "quest": true, + "weight": 0.02 + }, + "6756": { + "name": "Letter", + "quest": true, + "weight": 0.005 + }, + "6757": { + "name": "Letter", + "quest": true, + "weight": 0.005 + }, + "6758": { + "name": "Scroll", + "quest": true, + "weight": 0.005 + }, + "6759": { + "name": "Chest", + "quest": true, + "weight": 0.03 + }, + "6760": { + "name": "Guthix mjolnir", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "acrush": 11, + "str": 14, + "aspeed": 6 + } + }, + "6762": { + "name": "Saradomin mjolnir", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "acrush": 11, + "str": 14, + "aspeed": 6 + } + }, + "6764": { + "name": "Zamorak mjolnir", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "acrush": 11, + "str": 14, + "aspeed": 6 + } + }, + "6766": { + "name": "Cat antipoison", + "quest": true, + "weight": 0.035 + }, + "6767": { + "name": "Book", + "weight": 0.04 + }, + "6768": { + "name": "Poisoned cheese", + "quest": true, + "weight": 0.2 + }, + "6769": { + "name": "Music scroll", + "quest": true, + "weight": 0.02 + }, + "6770": { + "name": "Directions", + "quest": true, + "weight": 0.02 + }, + "6771": { + "name": "Pot of weeds", + "quest": true, + "weight": 0.6 + }, + "6772": { + "name": "Smouldering pot", + "quest": true, + "weight": 0.5 + }, + "6773": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6774": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6775": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6776": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6777": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6778": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6779": { + "name": "Rat pole", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "6785": { + "name": "Statuette", + "quest": true, + "weight": 0.001 + }, + "6786": { + "name": "Robe of elidinis", + "quest": true, + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 4 + } + }, + "6787": { + "name": "Robe of elidinis", + "quest": true, + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 7 + } + }, + "6788": { + "name": "Torn robe", + "quest": true, + "weight": 0.005 + }, + "6789": { + "name": "Torn robe", + "quest": true, + "weight": 0.005 + }, + "6790": { + "name": "Shoes", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 10 + } + }, + "6791": { + "name": "Sole", + "quest": true, + "weight": 0.001 + }, + "6792": { + "name": "Ancestral key", + "quest": true, + "weight": 0.01 + }, + "6793": { + "name": "Ballad", + "quest": true, + "weight": 0.005 + }, + "6794": { + "name": "Choc-ice", + "weight": 0.001 + }, + "6796": { + "name": "Lamp", + "quest": true, + "weight": 0.1 + }, + "6798": { + "name": "Earth warrior champion scroll", + "weight": 0.001 + }, + "6799": { + "name": "Ghoul champion scroll" + }, + "6800": { + "name": "Giant champion scroll", + "weight": 0.001 + }, + "6801": { + "name": "Goblin champion scroll", + "weight": 0.001 + }, + "6802": { + "name": "Hobgoblin champion scroll", + "weight": 0.001 + }, + "6803": { + "name": "Imp champion scroll", + "weight": 0.001 + }, + "6804": { + "name": "Jogre champion scroll", + "weight": 0.001 + }, + "6805": { + "name": "Lesser demon champion scroll", + "weight": 0.001 + }, + "6806": { + "name": "Skeleton champion scroll", + "weight": 0.001 + }, + "6807": { + "name": "Zombie champion scroll", + "weight": 0.001 + }, + "6808": { + "name": "Leon's champion scroll", + "weight": 0.001 + }, + "6809": { + "name": "Granite legs", + "equipable": true, + "weight": 15.875, + "equipment": { + "slot": 7, + "amagic": -31, + "arange": -18, + "dstab": 43, + "dslash": 45, + "dcrush": 41, + "dmagic": -4, + "drange": 68 + } + }, + "6810": { + "name": "Bonemeal", + "weight": 1.0 + }, + "6812": { + "name": "Wyvern bones", + "weight": 0.5 + }, + "6814": { + "name": "Fur", + "weight": 3.0 + }, + "6817": { + "name": "Slender blade", + "quest": true, + "weight": 3.175 + }, + "6818": { + "name": "Bow-sword", + "quest": true, + "weight": 3.175 + }, + "6819": { + "name": "Large pouch", + "quest": true, + "weight": 1.0 + }, + "6820": { + "name": "Relic", + "quest": true, + "weight": 0.001 + }, + "6821": { + "name": "Orb", + "quest": true, + "weight": 1.0 + }, + "6822": { + "name": "Star bauble", + "weight": 0.2 + }, + "6823": { + "name": "Star bauble", + "weight": 0.2 + }, + "6824": { + "name": "Star bauble", + "weight": 0.2 + }, + "6825": { + "name": "Star bauble", + "weight": 0.2 + }, + "6826": { + "name": "Star bauble", + "weight": 0.2 + }, + "6827": { + "name": "Star bauble", + "weight": 0.2 + }, + "6828": { + "name": "Box bauble", + "weight": 0.2 + }, + "6829": { + "name": "Box bauble", + "weight": 0.2 + }, + "6830": { + "name": "Box bauble", + "weight": 0.2 + }, + "6831": { + "name": "Box bauble", + "weight": 0.2 + }, + "6832": { + "name": "Box bauble", + "weight": 0.2 + }, + "6833": { + "name": "Box bauble", + "weight": 0.2 + }, + "6834": { + "name": "Diamond bauble", + "weight": 0.2 + }, + "6835": { + "name": "Diamond bauble", + "weight": 0.2 + }, + "6836": { + "name": "Diamond bauble", + "weight": 0.2 + }, + "6837": { + "name": "Diamond bauble", + "weight": 0.2 + }, + "6838": { + "name": "Diamond bauble", + "weight": 0.2 + }, + "6839": { + "name": "Diamond bauble", + "weight": 0.2 + }, + "6840": { + "name": "Tree bauble", + "weight": 0.2 + }, + "6841": { + "name": "Tree bauble", + "weight": 0.2 + }, + "6842": { + "name": "Tree bauble", + "weight": 0.2 + }, + "6843": { + "name": "Tree bauble", + "weight": 0.2 + }, + "6844": { + "name": "Tree bauble", + "weight": 0.2 + }, + "6845": { + "name": "Tree bauble", + "weight": 0.2 + }, + "6846": { + "name": "Bell bauble", + "weight": 0.2 + }, + "6847": { + "name": "Bell bauble", + "weight": 0.2 + }, + "6848": { + "name": "Bell bauble", + "weight": 0.2 + }, + "6849": { + "name": "Bell bauble", + "weight": 0.2 + }, + "6850": { + "name": "Bell bauble", + "weight": 0.2 + }, + "6851": { + "name": "Bell bauble", + "weight": 0.2 + }, + "6852": { + "name": "Puppet box", + "weight": 0.907 + }, + "6853": { + "name": "Bauble box", + "weight": 1.0 + }, + "6854": { + "name": "Puppet box", + "weight": 0.907 + }, + "6855": { + "name": "Bauble box", + "weight": 1.0 + }, + "6856": { + "name": "Bobble hat", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 0 + } + }, + "6857": { + "name": "Bobble scarf", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 2 + } + }, + "6858": { + "name": "Jester hat", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 0 + } + }, + "6859": { + "name": "Jester scarf", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 2 + } + }, + "6860": { + "name": "Tri-jester hat", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 0 + } + }, + "6861": { + "name": "Tri-jester scarf", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 2 + } + }, + "6862": { + "name": "Woolly hat", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 0 + } + }, + "6863": { + "name": "Woolly scarf", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 2 + } + }, + "6864": { + "name": "Marionette handle", + "weight": 0.2 + }, + "6865": { + "name": "Blue marionette" + }, + "6866": { + "name": "Green marionette" + }, + "6867": { + "name": "Red marionette" + }, + "6868": { + "name": "Blue marionette" + }, + "6869": { + "name": "Green marionette" + }, + "6870": { + "name": "Red marionette" + }, + "6871": { + "name": "Red marionette" + }, + "6872": { + "name": "Red marionette" + }, + "6873": { + "name": "Red marionette" + }, + "6874": { + "name": "Red marionette" + }, + "6875": { + "name": "Blue marionette" + }, + "6876": { + "name": "Blue marionette" + }, + "6877": { + "name": "Blue marionette" + }, + "6878": { + "name": "Blue marionette" + }, + "6879": { + "name": "Green marionette" + }, + "6880": { + "name": "Green marionette" + }, + "6881": { + "name": "Green marionette" + }, + "6882": { + "name": "Green marionette" + }, + "6883": { + "name": "Peach", + "weight": 0.01 + }, + "6885": { + "name": "Progress hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "6886": { + "name": "Progress hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "6887": { + "name": "Progress hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "6889": { + "name": "Mage's book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "amagic": 15, + "dmagic": 15 + } + }, + "6891": { + "name": "Arena book", + "weight": 1.0 + }, + "6893": { + "name": "Leather boots", + "weight": 0.34 + }, + "6894": { + "name": "Adamant kiteshield", + "weight": 5.896 + }, + "6895": { + "name": "Adamant med helm", + "weight": 2.267 + }, + "6896": { + "name": "Emerald", + "weight": 0.002 + }, + "6897": { + "name": "Rune longsword", + "weight": 1.814 + }, + "6898": { + "name": "Cylinder", + "weight": 0.001 + }, + "6899": { + "name": "Cube", + "weight": 0.001 + }, + "6900": { + "name": "Icosahedron", + "weight": 0.001 + }, + "6901": { + "name": "Pentamid", + "weight": 0.001 + }, + "6902": { + "name": "Orb", + "weight": 0.001 + }, + "6903": { + "name": "Dragonstone", + "weight": 0.002 + }, + "6904": { + "name": "Animals' bones", + "weight": 0.001 + }, + "6905": { + "name": "Animals' bones", + "weight": 0.001 + }, + "6906": { + "name": "Animals' bones", + "weight": 0.001 + }, + "6907": { + "name": "Animals' bones", + "weight": 0.001 + }, + "6908": { + "name": "Beginner wand", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 3, + "amagic": 5, + "dmagic": 5, + "aspeed": 4 + } + }, + "6910": { + "name": "Apprentice wand", + "equipable": true, + "weight": 0.255, + "equipment": { + "slot": 3, + "amagic": 10, + "dmagic": 10, + "aspeed": 4 + } + }, + "6912": { + "name": "Teacher wand", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 3, + "amagic": 15, + "dmagic": 15, + "aspeed": 4 + } + }, + "6914": { + "name": "Master wand", + "equipable": true, + "weight": 0.198, + "equipment": { + "slot": 3, + "amagic": 20, + "dmagic": 20, + "aspeed": 4 + } + }, + "6916": { + "name": "Infinity top", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 4, + "amagic": 22, + "dmagic": 22 + } + }, + "6918": { + "name": "Infinity hat", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 6, + "dmagic": 6 + } + }, + "6920": { + "name": "Infinity boots", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 10, + "amagic": 5, + "dmagic": 5 + } + }, + "6922": { + "name": "Infinity gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "amagic": 5, + "dmagic": 5 + } + }, + "6924": { + "name": "Infinity bottoms", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 7, + "amagic": 17, + "dmagic": 17 + } + }, + "6945": { + "name": "Sandy hand", + "quest": true, + "weight": 0.5 + }, + "6946": { + "name": "Beer soaked hand", + "quest": true, + "weight": 0.5 + }, + "6947": { + "name": "Bert's rota", + "quest": true, + "weight": 0.02 + }, + "6948": { + "name": "Sandy's rota", + "quest": true, + "weight": 0.02 + }, + "6949": { + "name": "A magic scroll", + "quest": true, + "weight": 0.02 + }, + "6950": { + "name": "Magical orb", + "quest": true, + "weight": 0.02 + }, + "6951": { + "name": "Magical orb (a)", + "quest": true, + "weight": 0.02 + }, + "6952": { + "name": "Truth serum", + "quest": true + }, + "6953": { + "name": "Bottled water", + "quest": true, + "weight": 0.05 + }, + "6954": { + "name": "Redberry juice", + "quest": true, + "weight": 0.05 + }, + "6955": { + "name": "Pink dye", + "quest": true, + "weight": 0.05 + }, + "6956": { + "name": "Rose tinted lens", + "quest": true, + "weight": 0.05 + }, + "6957": { + "name": "Wizard's head", + "quest": true, + "weight": 3.628 + }, + "6958": { + "name": "Sand", + "quest": true, + "weight": 0.001 + }, + "6959": { + "name": "Pink cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "6961": { + "name": "Baguette", + "weight": 0.02 + }, + "6962": { + "name": "Triangle sandwich", + "weight": 0.02 + }, + "6963": { + "name": "Roll", + "weight": 0.02 + }, + "6965": { + "name": "Square sandwich", + "weight": 0.02 + }, + "6966": { + "name": "Prison key", + "weight": 0.01 + }, + "6970": { + "name": "Pyramid top", + "weight": 11.339 + }, + "6979": { + "name": "Granite (500g)", + "quest": true, + "weight": 0.5 + }, + "6985": { + "name": "Sandstone (20)", + "quest": true, + "weight": 20.0 + }, + "6986": { + "name": "Sandstone (32)", + "quest": true, + "weight": 32.0 + }, + "6987": { + "name": "Sandstone body", + "quest": true, + "weight": 30.0 + }, + "6988": { + "name": "Sandstone base", + "quest": true, + "weight": 23.0 + }, + "6989": { + "name": "Stone head", + "quest": true, + "weight": 0.5 + }, + "6990": { + "name": "Stone head", + "quest": true, + "weight": 0.5 + }, + "6991": { + "name": "Stone head", + "quest": true, + "weight": 0.5 + }, + "6992": { + "name": "Stone head", + "quest": true, + "weight": 0.5 + }, + "6993": { + "name": "Z sigil", + "quest": true, + "weight": 0.5 + }, + "6994": { + "name": "M sigil", + "quest": true, + "weight": 0.5 + }, + "6995": { + "name": "R sigil", + "weight": 0.5 + }, + "6996": { + "name": "K sigil", + "quest": true, + "weight": 0.5 + }, + "6997": { + "name": "Stone left arm", + "quest": true, + "weight": 9.0 + }, + "6998": { + "name": "Stone right arm", + "quest": true, + "weight": 9.0 + }, + "6999": { + "name": "Stone left leg", + "quest": true, + "weight": 9.0 + }, + "7000": { + "name": "Stone right leg", + "quest": true, + "weight": 9.0 + }, + "7001": { + "name": "Camel mould (p)", + "quest": true, + "weight": 0.5 + }, + "7002": { + "name": "Stone head", + "quest": true, + "weight": 0.5 + }, + "7003": { + "name": "Camel mask", + "quest": true, + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "7051": { + "name": "Unlit bug lantern", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 5 + } + }, + "7053": { + "name": "Lit bug lantern", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 5 + } + }, + "7054": { + "name": "Chilli potato", + "weight": 0.5 + }, + "7056": { + "name": "Egg potato", + "weight": 0.5 + }, + "7058": { + "name": "Mushroom potato", + "weight": 0.5 + }, + "7060": { + "name": "Tuna potato", + "weight": 0.5 + }, + "7062": { + "name": "Chilli con carne", + "weight": 0.5 + }, + "7064": { + "name": "Egg and tomato", + "weight": 0.5 + }, + "7066": { + "name": "Mushroom & onion", + "weight": 0.5 + }, + "7068": { + "name": "Tuna and corn", + "weight": 0.5 + }, + "7070": { + "name": "Minced meat", + "weight": 0.5 + }, + "7072": { + "name": "Spicy sauce", + "weight": 0.5 + }, + "7074": { + "name": "Chopped garlic", + "weight": 0.5 + }, + "7076": { + "name": "Uncooked egg", + "weight": 0.5 + }, + "7078": { + "name": "Scrambled egg", + "weight": 0.5 + }, + "7080": { + "name": "Sliced mushrooms", + "weight": 0.5 + }, + "7082": { + "name": "Fried mushrooms", + "weight": 0.5 + }, + "7084": { + "name": "Fried onions", + "weight": 0.5 + }, + "7086": { + "name": "Chopped tuna", + "weight": 0.5 + }, + "7088": { + "name": "Sweetcorn" + }, + "7090": { + "name": "Burnt egg" + }, + "7092": { + "name": "Burnt onion" + }, + "7094": { + "name": "Burnt mushroom" + }, + "7108": { + "name": "Gunpowder", + "quest": true, + "weight": 0.001 + }, + "7109": { + "name": "Fuse", + "quest": true, + "weight": 0.007 + }, + "7110": { + "name": "Stripy pirate shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "7112": { + "name": "Pirate bandana", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "7114": { + "name": "Pirate boots", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 10 + } + }, + "7116": { + "name": "Pirate leggings", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "7118": { + "name": "Canister", + "quest": true + }, + "7119": { + "name": "Cannon ball", + "quest": true + }, + "7120": { + "name": "Ramrod", + "quest": true, + "weight": 2.0 + }, + "7121": { + "name": "Repair plank", + "quest": true + }, + "7122": { + "name": "Stripy pirate shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "7124": { + "name": "Pirate bandana", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "7126": { + "name": "Pirate leggings", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "7128": { + "name": "Stripy pirate shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "7130": { + "name": "Pirate bandana", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "7132": { + "name": "Pirate leggings", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "7134": { + "name": "Stripy pirate shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "7136": { + "name": "Pirate bandana", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "7138": { + "name": "Pirate leggings", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "7140": { + "name": "Lucky cutlass", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 20, + "amagic": -5, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "str": 25, + "aspeed": 4 + } + }, + "7141": { + "name": "Harry's cutlass", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 3, + "aslash": 14, + "amagic": -5, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "str": 22, + "aspeed": 4 + } + }, + "7142": { + "name": "Rapier", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 45, + "aslash": 7, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "7143": { + "name": "Plunder", + "quest": true, + "weight": 0.005 + }, + "7144": { + "name": "Book o' piracy", + "quest": true, + "weight": 0.5 + }, + "7145": { + "name": "Cannon barrel", + "quest": true, + "weight": 32.0 + }, + "7146": { + "name": "Broken cannon", + "quest": true, + "weight": 32.0 + }, + "7148": { + "name": "Repair plank", + "quest": true + }, + "7149": { + "name": "Canister", + "quest": true + }, + "7150": { + "name": "Tacks", + "quest": true + }, + "7157": { + "name": "Braindeath 'rum'", + "weight": 0.907 + }, + "7158": { + "name": "Dragon 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 92, + "acrush": 80, + "amagic": -4, + "drange": -1, + "str": 93, + "aspeed": 7 + } + }, + "7159": { + "name": "Insulated boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "dstab": 1, + "dslash": 1, + "drange": 1 + } + }, + "7162": { + "name": "Pie recipe book", + "weight": 0.001 + }, + "7164": { + "name": "Part mud pie", + "weight": 0.001 + }, + "7166": { + "name": "Part mud pie", + "weight": 0.001 + }, + "7168": { + "name": "Raw mud pie", + "weight": 0.001 + }, + "7170": { + "name": "Mud pie", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "7172": { + "name": "Part garden pie", + "weight": 0.001 + }, + "7174": { + "name": "Part garden pie", + "weight": 0.001 + }, + "7176": { + "name": "Raw garden pie", + "weight": 0.001 + }, + "7178": { + "name": "Garden pie", + "weight": 0.001 + }, + "7180": { + "name": "Half a garden pie", + "weight": 0.001 + }, + "7182": { + "name": "Part fish pie", + "weight": 0.001 + }, + "7184": { + "name": "Part fish pie", + "weight": 0.001 + }, + "7186": { + "name": "Raw fish pie", + "weight": 0.001 + }, + "7188": { + "name": "Fish pie", + "weight": 0.001 + }, + "7190": { + "name": "Half a fish pie" + }, + "7192": { + "name": "Part admiral pie", + "weight": 0.001 + }, + "7194": { + "name": "Part admiral pie", + "weight": 0.001 + }, + "7196": { + "name": "Raw admiral pie", + "weight": 0.001 + }, + "7198": { + "name": "Admiral pie", + "weight": 0.001 + }, + "7200": { + "name": "Half an admiral pie", + "weight": 0.001 + }, + "7202": { + "name": "Part wild pie", + "weight": 0.001 + }, + "7204": { + "name": "Part wild pie", + "weight": 0.001 + }, + "7206": { + "name": "Raw wild pie", + "weight": 0.001 + }, + "7208": { + "name": "Wild pie", + "weight": 0.001 + }, + "7210": { + "name": "Half a wild pie", + "weight": 0.001 + }, + "7212": { + "name": "Part summer pie 1", + "weight": 0.5 + }, + "7214": { + "name": "Part summer pie 2", + "weight": 0.5 + }, + "7216": { + "name": "Raw summer pie", + "weight": 0.001 + }, + "7218": { + "name": "Summer pie", + "weight": 0.001 + }, + "7220": { + "name": "Half a summer pie", + "weight": 0.001 + }, + "7222": { + "name": "Burnt rabbit" + }, + "7223": { + "name": "Roast rabbit", + "weight": 0.3 + }, + "7224": { + "name": "Skewered rabbit" + }, + "7225": { + "name": "Iron spit", + "weight": 1.5 + }, + "7226": { + "name": "Burnt chompy" + }, + "7228": { + "name": "Cooked chompy", + "weight": 10.0 + }, + "7230": { + "name": "Skewered chompy", + "weight": 2.5 + }, + "7236": { + "name": "Clue scroll (easy)" + }, + "7238": { + "name": "Clue scroll (easy)" + }, + "7239": { + "name": "Clue scroll (hard)" + }, + "7241": { + "name": "Clue scroll (hard)" + }, + "7243": { + "name": "Clue scroll (hard)" + }, + "7245": { + "name": "Clue scroll (hard)" + }, + "7247": { + "name": "Clue scroll (hard)" + }, + "7248": { + "name": "Clue scroll (hard)" + }, + "7249": { + "name": "Clue scroll (hard)" + }, + "7250": { + "name": "Clue scroll (hard)" + }, + "7251": { + "name": "Clue scroll (hard)" + }, + "7252": { + "name": "Clue scroll (hard)" + }, + "7253": { + "name": "Clue scroll (hard)" + }, + "7254": { + "name": "Clue scroll (hard)" + }, + "7255": { + "name": "Clue scroll (hard)" + }, + "7256": { + "name": "Clue scroll (hard)" + }, + "7258": { + "name": "Clue scroll (hard)" + }, + "7260": { + "name": "Clue scroll (hard)" + }, + "7262": { + "name": "Clue scroll (hard)" + }, + "7264": { + "name": "Clue scroll (hard)" + }, + "7266": { + "name": "Clue scroll (hard)" + }, + "7268": { + "name": "Clue scroll (hard)" + }, + "7269": { + "name": "Challenge scroll (hard)" + }, + "7270": { + "name": "Clue scroll (hard)" + }, + "7271": { + "name": "Challenge scroll (hard)" + }, + "7272": { + "name": "Clue scroll (hard)" + }, + "7273": { + "name": "Challenge scroll (hard)" + }, + "7274": { + "name": "Clue scroll (medium)" + }, + "7275": { + "name": "Challenge scroll (medium)" + }, + "7276": { + "name": "Clue scroll (medium)" + }, + "7277": { + "name": "Challenge scroll (medium)" + }, + "7278": { + "name": "Clue scroll (medium)" + }, + "7279": { + "name": "Challenge scroll (medium)" + }, + "7280": { + "name": "Clue scroll (medium)" + }, + "7281": { + "name": "Challenge scroll (medium)" + }, + "7282": { + "name": "Clue scroll (medium)" + }, + "7283": { + "name": "Challenge scroll (medium)" + }, + "7284": { + "name": "Clue scroll (medium)" + }, + "7285": { + "name": "Challenge scroll (medium)" + }, + "7286": { + "name": "Clue scroll (medium)" + }, + "7288": { + "name": "Clue scroll (medium)" + }, + "7290": { + "name": "Clue scroll (medium)" + }, + "7292": { + "name": "Clue scroll (medium)" + }, + "7294": { + "name": "Clue scroll (medium)" + }, + "7296": { + "name": "Clue scroll (medium)" + }, + "7297": { + "name": "Key (medium)" + }, + "7298": { + "name": "Clue scroll (medium)" + }, + "7299": { + "name": "Key (medium)" + }, + "7300": { + "name": "Clue scroll (medium)" + }, + "7301": { + "name": "Clue scroll (medium)" + }, + "7302": { + "name": "Key (medium)" + }, + "7303": { + "name": "Clue scroll (medium)" + }, + "7304": { + "name": "Clue scroll (medium)" + }, + "7305": { + "name": "Clue scroll (medium)" + }, + "7307": { + "name": "Clue scroll (medium)" + }, + "7309": { + "name": "Clue scroll (medium)" + }, + "7311": { + "name": "Clue scroll (medium)" + }, + "7313": { + "name": "Clue scroll (medium)" + }, + "7315": { + "name": "Clue scroll (medium)" + }, + "7317": { + "name": "Clue scroll (medium)" + }, + "7319": { + "name": "Red boater", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "7321": { + "name": "Orange boater", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "7323": { + "name": "Green boater", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "7325": { + "name": "Blue boater", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "7327": { + "name": "Black boater", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "7329": { + "name": "Red firelighter" + }, + "7330": { + "name": "Green firelighter" + }, + "7331": { + "name": "Blue firelighter" + }, + "7332": { + "name": "Black shield (h1)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "7334": { + "name": "Adamant shield (h1)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "7336": { + "name": "Rune shield (h1)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "7338": { + "name": "Black shield (h2)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "7340": { + "name": "Adamant shield (h2)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "7342": { + "name": "Rune shield (h2)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "7344": { + "name": "Black shield (h3)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "7346": { + "name": "Adamant shield (h3)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "7348": { + "name": "Rune shield (h3)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "7350": { + "name": "Black shield (h4)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "7352": { + "name": "Adamant shield (h4)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "7354": { + "name": "Rune shield (h4)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "7356": { + "name": "Black shield (h5)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 17, + "dslash": 19, + "dcrush": 18, + "dmagic": -1, + "drange": 18 + } + }, + "7358": { + "name": "Adamant shield (h5)", + "equipable": true, + "weight": 5.896, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "7360": { + "name": "Rune shield (h5)", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "7362": { + "name": "Studded body (g)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 4, + "amagic": -4, + "arange": 8, + "dstab": 18, + "dslash": 25, + "dcrush": 22, + "dmagic": 8, + "drange": 25 + } + }, + "7364": { + "name": "Studded body (t)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 4, + "amagic": -4, + "arange": 8, + "dstab": 18, + "dslash": 25, + "dcrush": 22, + "dmagic": 8, + "drange": 25 + } + }, + "7366": { + "name": "Studded chaps (g)", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -5, + "arange": 6, + "dstab": 15, + "dslash": 16, + "dcrush": 17, + "dmagic": 6, + "drange": 16 + } + }, + "7368": { + "name": "Studded chaps (t)", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 7, + "amagic": -5, + "arange": 6, + "dstab": 15, + "dslash": 16, + "dcrush": 17, + "dmagic": 6, + "drange": 16 + } + }, + "7370": { + "name": "Green d'hide body (g)", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 15, + "dstab": 40, + "dslash": 32, + "dcrush": 45, + "dmagic": 20, + "drange": 40 + } + }, + "7372": { + "name": "Green d'hide body (t)", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 15, + "dstab": 40, + "dslash": 32, + "dcrush": 45, + "dmagic": 20, + "drange": 40 + } + }, + "7374": { + "name": "Blue d'hide body (g)", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 20, + "dstab": 45, + "dslash": 37, + "dcrush": 50, + "dmagic": 30, + "drange": 45 + } + }, + "7376": { + "name": "Blue d'hide body (t)", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 20, + "dstab": 45, + "dslash": 37, + "dcrush": 50, + "dmagic": 30, + "drange": 45 + } + }, + "7378": { + "name": "Green d'hide chaps (g)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 8, + "dstab": 22, + "dslash": 16, + "dcrush": 24, + "dmagic": 8, + "drange": 22 + } + }, + "7380": { + "name": "Green d'hide chaps (t)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 8, + "dstab": 22, + "dslash": 16, + "dcrush": 24, + "dmagic": 8, + "drange": 22 + } + }, + "7382": { + "name": "Blue d'hide chaps (g)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 11, + "dstab": 25, + "dslash": 19, + "dcrush": 27, + "dmagic": 14, + "drange": 25 + } + }, + "7384": { + "name": "Blue d'hide chaps (t)", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 11, + "dstab": 25, + "dslash": 19, + "dcrush": 27, + "dmagic": 14, + "drange": 25 + } + }, + "7386": { + "name": "Blue skirt (g)", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "7388": { + "name": "Blue skirt (t)", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "7390": { + "name": "Blue wizard robe (g)", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "amagic": 3, + "dmagic": 3 + } + }, + "7392": { + "name": "Blue wizard robe (t)", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "amagic": 3, + "dmagic": 3 + } + }, + "7394": { + "name": "Blue wizard hat (g)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "7396": { + "name": "Blue wizard hat (t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "7398": { + "name": "Enchanted robe", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "7399": { + "name": "Enchanted top", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "7400": { + "name": "Enchanted hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "7404": { + "name": "Red logs", + "weight": 2.0 + }, + "7405": { + "name": "Green logs", + "weight": 2.0 + }, + "7406": { + "name": "Blue logs", + "weight": 2.0 + }, + "7408": { + "name": "Draynor skull", + "quest": true, + "weight": 0.08 + }, + "7409": { + "name": "Magic secateurs", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 9, + "acrush": -5, + "amagic": 1, + "dslash": 1, + "dmagic": 1, + "str": 1, + "aspeed": 5 + } + }, + "7410": { + "name": "Queen's secateurs", + "quest": true, + "weight": 0.453 + }, + "7411": { + "name": "Symptoms list", + "quest": true, + "weight": 0.01 + }, + "7413": { + "name": "Bird nest" + }, + "7414": { + "name": "Paddle", + "equipable": true, + "weight": 0.02 + }, + "7416": { + "name": "Mole claw", + "weight": 0.001 + }, + "7418": { + "name": "Mole skin", + "weight": 0.001 + }, + "7421": { + "name": "Fungicide spray 10", + "weight": 2.0 + }, + "7422": { + "name": "Fungicide spray 9", + "weight": 2.0 + }, + "7423": { + "name": "Fungicide spray 8", + "weight": 2.0 + }, + "7424": { + "name": "Fungicide spray 7", + "weight": 2.0 + }, + "7425": { + "name": "Fungicide spray 6", + "weight": 2.0 + }, + "7426": { + "name": "Fungicide spray 5", + "weight": 2.0 + }, + "7427": { + "name": "Fungicide spray 4", + "weight": 2.0 + }, + "7428": { + "name": "Fungicide spray 3", + "weight": 2.0 + }, + "7429": { + "name": "Fungicide spray 2", + "weight": 2.0 + }, + "7430": { + "name": "Fungicide spray 1", + "weight": 2.0 + }, + "7431": { + "name": "Fungicide spray 0", + "weight": 2.0 + }, + "7432": { + "name": "Fungicide", + "weight": 0.1 + }, + "7433": { + "name": "Wooden spoon", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 5, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 7, + "aspeed": 5 + } + }, + "7435": { + "name": "Egg whisk", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "7437": { + "name": "Spork", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 8, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 12, + "aspeed": 4 + } + }, + "7439": { + "name": "Spatula", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 27, + "acrush": 21, + "amagic": -4, + "drange": -1, + "str": 26, + "aspeed": 7 + } + }, + "7441": { + "name": "Frying pan", + "equipable": true, + "weight": 1.587, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 25, + "amagic": -4, + "str": 20, + "aspeed": 6 + } + }, + "7443": { + "name": "Skewer", + "equipable": true, + "weight": 2.041, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": 29, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 31, + "aspeed": 5 + } + }, + "7445": { + "name": "Rolling pin", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": -2, + "acrush": 39, + "str": 36, + "prayer": 4, + "aspeed": 5 + } + }, + "7447": { + "name": "Kitchen knife", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 25, + "aslash": 12, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 24, + "aspeed": 4 + } + }, + "7449": { + "name": "Meat tenderiser", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 53, + "amagic": -4, + "str": 48, + "aspeed": 6 + } + }, + "7451": { + "name": "Cleaver", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "7453": { + "name": "Hardleather gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1 + } + }, + "7454": { + "name": "Bronze gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "amagic": 1, + "arange": 2, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 1, + "drange": 2, + "str": 2 + } + }, + "7455": { + "name": "Iron gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 3, + "aslash": 3, + "acrush": 3, + "amagic": 2, + "arange": 3, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 2, + "drange": 3, + "str": 3 + } + }, + "7456": { + "name": "Steel gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 2, + "arange": 4, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 2, + "drange": 4, + "str": 4 + } + }, + "7457": { + "name": "Black gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 5, + "aslash": 5, + "acrush": 5, + "amagic": 3, + "arange": 5, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 5 + } + }, + "7458": { + "name": "Mithril gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 6, + "aslash": 6, + "acrush": 6, + "amagic": 3, + "arange": 6, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 3, + "drange": 6, + "str": 6 + } + }, + "7459": { + "name": "Adamant gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 4, + "arange": 7, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "dmagic": 4, + "drange": 7, + "str": 7 + } + }, + "7460": { + "name": "Rune gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 8, + "aslash": 8, + "acrush": 8, + "amagic": 4, + "arange": 8, + "dstab": 8, + "dslash": 8, + "dcrush": 8, + "dmagic": 4, + "drange": 8, + "str": 8 + } + }, + "7461": { + "name": "Dragon gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 9, + "aslash": 9, + "acrush": 9, + "amagic": 5, + "arange": 9, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 5, + "drange": 9, + "str": 9 + } + }, + "7462": { + "name": "Barrows gloves", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9, + "astab": 12, + "aslash": 12, + "acrush": 12, + "amagic": 6, + "arange": 12, + "dstab": 12, + "dslash": 12, + "dcrush": 12, + "dmagic": 6, + "drange": 12, + "str": 12 + } + }, + "7463": { + "name": "Cornflour", + "quest": true + }, + "7464": { + "name": "Book on chickens", + "weight": 0.07 + }, + "7465": { + "name": "Vanilla pod", + "quest": true, + "weight": 0.003 + }, + "7466": { + "name": "Cornflour", + "quest": true + }, + "7468": { + "name": "Pot of cornflour", + "quest": true, + "weight": 1.36 + }, + "7470": { + "name": "Cornflour mixture", + "quest": true, + "weight": 1.36 + }, + "7471": { + "name": "Milky mixture", + "quest": true, + "weight": 1.36 + }, + "7472": { + "name": "Cinnamon", + "quest": true, + "weight": 0.003 + }, + "7473": { + "name": "Brulee", + "quest": true, + "weight": 0.3 + }, + "7474": { + "name": "Brulee", + "quest": true, + "weight": 0.3 + }, + "7475": { + "name": "Brulee", + "quest": true, + "weight": 0.3 + }, + "7476": { + "name": "Brulee supreme", + "quest": true, + "weight": 0.3 + }, + "7477": { + "name": "Evil chicken's egg", + "quest": true, + "weight": 0.08 + }, + "7478": { + "name": "Dragon token", + "quest": true, + "weight": 0.01 + }, + "7479": { + "name": "Spicy stew", + "quest": true, + "weight": 1.5 + }, + "7480": { + "name": "Red spice (4)", + "quest": true, + "weight": 0.001 + }, + "7481": { + "name": "Red spice (3)", + "quest": true, + "weight": 0.001 + }, + "7482": { + "name": "Red spice (2)", + "quest": true, + "weight": 0.001 + }, + "7483": { + "name": "Red spice (1)", + "quest": true, + "weight": 0.001 + }, + "7484": { + "name": "Orange spice (4)", + "quest": true, + "weight": 0.001 + }, + "7485": { + "name": "Orange spice (3)", + "quest": true, + "weight": 0.001 + }, + "7486": { + "name": "Orange spice (2)", + "quest": true, + "weight": 0.001 + }, + "7487": { + "name": "Orange spice (1)", + "quest": true, + "weight": 0.001 + }, + "7488": { + "name": "Brown spice (4)", + "quest": true, + "weight": 0.001 + }, + "7489": { + "name": "Brown spice (3)", + "quest": true, + "weight": 0.001 + }, + "7490": { + "name": "Brown spice (2)", + "quest": true, + "weight": 0.001 + }, + "7491": { + "name": "Brown spice (1)", + "quest": true, + "weight": 0.001 + }, + "7492": { + "name": "Yellow spice (4)", + "quest": true, + "weight": 0.001 + }, + "7493": { + "name": "Yellow spice (3)", + "quest": true, + "weight": 0.001 + }, + "7494": { + "name": "Yellow spice (2)", + "quest": true, + "weight": 0.001 + }, + "7495": { + "name": "Yellow spice (1)", + "quest": true, + "weight": 0.001 + }, + "7496": { + "name": "Empty spice shaker", + "quest": true + }, + "7497": { + "name": "Dirty blast", + "quest": true, + "weight": 0.5 + }, + "7498": { + "name": "Antique lamp", + "quest": true + }, + "7508": { + "name": "Asgoldian ale", + "quest": true, + "weight": 0.55 + }, + "7509": { + "name": "Dwarven rock cake", + "quest": true, + "weight": 0.453 + }, + "7510": { + "name": "Dwarven rock cake", + "quest": true, + "weight": 0.453 + }, + "7511": { + "name": "Slop of compromise", + "quest": true, + "weight": 0.001 + }, + "7512": { + "name": "Soggy bread", + "quest": true, + "weight": 0.001 + }, + "7513": { + "name": "Spicy maggots", + "quest": true + }, + "7514": { + "name": "Dyed orange", + "quest": true, + "weight": 0.001 + }, + "7515": { + "name": "Breadcrumbs", + "quest": true, + "weight": 0.907 + }, + "7516": { + "name": "Kelp", + "quest": true, + "weight": 0.907 + }, + "7517": { + "name": "Ground kelp", + "quest": true, + "weight": 0.056 + }, + "7518": { + "name": "Crab meat", + "quest": true, + "weight": 0.907 + }, + "7520": { + "name": "Burnt crab meat", + "quest": true, + "weight": 0.907 + }, + "7521": { + "name": "Cooked crab meat", + "quest": true + }, + "7523": { + "name": "Cooked crab meat", + "quest": true + }, + "7524": { + "name": "Cooked crab meat", + "quest": true + }, + "7525": { + "name": "Cooked crab meat", + "quest": true + }, + "7526": { + "name": "Cooked crab meat", + "quest": true + }, + "7527": { + "name": "Ground crab meat", + "quest": true, + "weight": 0.907 + }, + "7528": { + "name": "Ground cod", + "quest": true, + "weight": 0.907 + }, + "7529": { + "name": "Raw fishcake", + "quest": true, + "weight": 0.907 + }, + "7530": { + "name": "Cooked fishcake", + "quest": true + }, + "7531": { + "name": "Burnt fishcake", + "quest": true, + "weight": 0.907 + }, + "7532": { + "name": "Mudskipper hide", + "quest": true, + "weight": 0.907 + }, + "7533": { + "name": "Rock", + "quest": true, + "weight": 1.0 + }, + "7534": { + "name": "Fishbowl helmet", + "quest": true, + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 0 + } + }, + "7535": { + "name": "Diving apparatus", + "quest": true, + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 1 + } + }, + "7536": { + "name": "Fresh crab claw", + "weight": 0.907 + }, + "7537": { + "name": "Crab claw", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 9, + "dstab": 3, + "dslash": 4, + "dcrush": 2, + "str": 1 + } + }, + "7538": { + "name": "Fresh crab shell", + "quest": true, + "weight": 0.907 + }, + "7539": { + "name": "Crab helmet", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 5, + "dslash": 4, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "7540": { + "name": "Broken crab claw", + "weight": 0.005 + }, + "7541": { + "name": "Broken crab shell", + "weight": 0.005 + }, + "7542": { + "name": "Cake of guidance", + "quest": true, + "weight": 0.3 + }, + "7543": { + "name": "Raw guide cake", + "quest": true, + "weight": 0.5 + }, + "7544": { + "name": "Enchanted egg", + "quest": true, + "weight": 0.02 + }, + "7545": { + "name": "Enchanted milk", + "quest": true, + "weight": 2.2 + }, + "7546": { + "name": "Enchanted flour", + "quest": true, + "weight": 1.36 + }, + "7564": { + "name": "Balloon toad", + "quest": true, + "weight": 4.0 + }, + "7565": { + "name": "Balloon toad", + "quest": true, + "weight": 4.0 + }, + "7566": { + "name": "Raw jubbly", + "quest": true, + "weight": 10.0 + }, + "7568": { + "name": "Cooked jubbly", + "quest": true, + "weight": 10.0 + }, + "7570": { + "name": "Burnt jubbly", + "quest": true, + "weight": 8.0 + }, + "7572": { + "name": "Red banana", + "quest": true, + "weight": 0.028 + }, + "7573": { + "name": "Tchiki monkey nuts", + "quest": true, + "weight": 0.01 + }, + "7574": { + "name": "Sliced red banana", + "quest": true, + "weight": 0.008 + }, + "7575": { + "name": "Tchiki nut paste", + "quest": true, + "weight": 0.008 + }, + "7576": { + "name": "Snake corpse", + "quest": true, + "weight": 3.0 + }, + "7577": { + "name": "Raw stuffed snake", + "quest": true, + "weight": 3.0 + }, + "7578": { + "name": "Odd stuffed snake", + "quest": true, + "weight": 3.0 + }, + "7579": { + "name": "Stuffed snake", + "quest": true, + "weight": 3.0 + }, + "7580": { + "name": "Snake over-cooked", + "quest": true, + "weight": 0.004 + }, + "7587": { + "name": "Coffin" + }, + "7588": { + "name": "Coffin" + }, + "7589": { + "name": "Coffin" + }, + "7590": { + "name": "Coffin" + }, + "7591": { + "name": "Coffin" + }, + "7592": { + "name": "Zombie shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "7593": { + "name": "Zombie trousers", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "7594": { + "name": "Zombie mask", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "7595": { + "name": "Zombie gloves", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 9 + } + }, + "7596": { + "name": "Zombie boots", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 10 + } + }, + "7622": { + "name": "Bucket of rubble", + "quest": true, + "weight": 2.5 + }, + "7624": { + "name": "Bucket of rubble", + "quest": true, + "weight": 2.5 + }, + "7626": { + "name": "Bucket of rubble", + "quest": true, + "weight": 2.5 + }, + "7628": { + "name": "Plaster fragment", + "quest": true, + "weight": 1.0 + }, + "7629": { + "name": "Dusty scroll", + "quest": true, + "weight": 0.02 + }, + "7630": { + "name": "Crate", + "quest": true, + "weight": 10.0 + }, + "7632": { + "name": "Temple library key", + "quest": true + }, + "7633": { + "name": "Ancient book", + "quest": true, + "weight": 0.01 + }, + "7634": { + "name": "Battered tome", + "quest": true, + "weight": 0.51 + }, + "7635": { + "name": "Leather book", + "quest": true, + "weight": 0.51 + }, + "7636": { + "name": "Rod dust", + "weight": 0.05 + }, + "7637": { + "name": "Silvthrill rod", + "quest": true, + "weight": 0.001 + }, + "7638": { + "name": "Silvthrill rod", + "quest": true, + "weight": 0.001 + }, + "7639": { + "name": "Rod of ivandis (10)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7640": { + "name": "Rod of ivandis (9)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7641": { + "name": "Rod of ivandis (8)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7642": { + "name": "Rod of ivandis (7)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7643": { + "name": "Rod of ivandis (6)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7644": { + "name": "Rod of ivandis (5)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7645": { + "name": "Rod of ivandis (4)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7646": { + "name": "Rod of ivandis (3)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7647": { + "name": "Rod of ivandis (2)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7648": { + "name": "Rod of ivandis (1)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "7649": { + "name": "Rod clay mould", + "quest": true + }, + "7650": { + "name": "Silver dust", + "weight": 0.15 + }, + "7652": { + "name": "Guthix balance (unf)" + }, + "7654": { + "name": "Guthix balance (unf)" + }, + "7656": { + "name": "Guthix balance (unf)" + }, + "7658": { + "name": "Guthix balance (unf)" + }, + "7660": { + "name": "Guthix balance(4)", + "weight": 0.035 + }, + "7662": { + "name": "Guthix balance(3)", + "weight": 0.03 + }, + "7664": { + "name": "Guthix balance(2)", + "weight": 0.025 + }, + "7666": { + "name": "Guthix balance(1)", + "weight": 0.02 + }, + "7668": { + "name": "Gadderhammer", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 35, + "amagic": -4, + "str": 35, + "aspeed": 5 + } + }, + "7671": { + "name": "Boxing gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 2, + "aspeed": 4 + } + }, + "7673": { + "name": "Boxing gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 2, + "aspeed": 4 + } + }, + "7675": { + "name": "Wooden sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 3, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 5, + "aspeed": 4 + } + }, + "7676": { + "name": "Wooden shield", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 5 + } + }, + "7677": { + "name": "Treasure stone", + "weight": 1.814 + }, + "7678": { + "name": "Prize key", + "weight": 0.01 + }, + "7679": { + "name": "Pugel", + "weight": 1.36 + }, + "7681": { + "name": "Game book", + "weight": 1.0 + }, + "7688": { + "name": "Kettle", + "weight": 0.001 + }, + "7690": { + "name": "Full kettle", + "weight": 0.001 + }, + "7691": { + "name": "Hot kettle", + "weight": 0.001 + }, + "7692": { + "name": "Pot of tea (4)", + "weight": 1.5 + }, + "7694": { + "name": "Pot of tea (3)", + "weight": 1.5 + }, + "7696": { + "name": "Pot of tea (2)", + "weight": 1.5 + }, + "7698": { + "name": "Pot of tea (1)", + "weight": 1.5 + }, + "7700": { + "name": "Teapot with leaves", + "weight": 1.5 + }, + "7702": { + "name": "Teapot", + "weight": 0.453 + }, + "7704": { + "name": "Pot of tea (4)", + "weight": 1.5 + }, + "7706": { + "name": "Pot of tea (3)", + "weight": 1.5 + }, + "7708": { + "name": "Pot of tea (2)", + "weight": 1.5 + }, + "7710": { + "name": "Pot of tea (1)", + "weight": 1.5 + }, + "7712": { + "name": "Teapot with leaves", + "weight": 1.5 + }, + "7714": { + "name": "Teapot", + "weight": 0.453 + }, + "7716": { + "name": "Pot of tea (4)", + "weight": 1.5 + }, + "7718": { + "name": "Pot of tea (3)", + "weight": 1.5 + }, + "7720": { + "name": "Pot of tea (2)", + "weight": 1.5 + }, + "7722": { + "name": "Pot of tea (1)", + "weight": 1.5 + }, + "7724": { + "name": "Teapot with leaves", + "weight": 1.5 + }, + "7726": { + "name": "Teapot", + "weight": 0.453 + }, + "7728": { + "name": "Empty cup", + "weight": 0.05 + }, + "7730": { + "name": "Cup of tea", + "weight": 0.15 + }, + "7731": { + "name": "Cup of tea", + "weight": 0.15 + }, + "7732": { + "name": "Porcelain cup", + "weight": 0.05 + }, + "7733": { + "name": "Cup of tea", + "weight": 0.15 + }, + "7734": { + "name": "Cup of tea", + "weight": 0.15 + }, + "7735": { + "name": "Porcelain cup", + "weight": 0.05 + }, + "7736": { + "name": "Cup of tea", + "weight": 0.15 + }, + "7737": { + "name": "Cup of tea", + "weight": 0.15 + }, + "7738": { + "name": "Tea leaves", + "weight": 0.01 + }, + "7759": { + "name": "Toy soldier", + "weight": 1.0 + }, + "7761": { + "name": "Toy soldier (wound)", + "weight": 1.0 + }, + "7763": { + "name": "Toy doll", + "weight": 1.0 + }, + "7765": { + "name": "Toy doll (wound)", + "weight": 1.0 + }, + "7767": { + "name": "Toy mouse", + "weight": 1.0 + }, + "7769": { + "name": "Toy mouse (wound)", + "weight": 1.0 + }, + "7771": { + "name": "Toy cat", + "weight": 1.0 + }, + "7773": { + "name": "Branch", + "weight": 0.5 + }, + "7774": { + "name": "Reward token" + }, + "7775": { + "name": "Reward token" + }, + "7776": { + "name": "Reward token" + }, + "7777": { + "name": "Long vine", + "weight": 1.36 + }, + "7778": { + "name": "Short vine", + "weight": 0.453 + }, + "7779": { + "name": "Fishing tome", + "weight": 1.0 + }, + "7780": { + "name": "Fishing tome", + "weight": 1.0 + }, + "7781": { + "name": "Fishing tome", + "weight": 1.0 + }, + "7782": { + "name": "Agility tome", + "weight": 1.0 + }, + "7783": { + "name": "Agility tome", + "weight": 1.0 + }, + "7784": { + "name": "Agility tome", + "weight": 1.0 + }, + "7785": { + "name": "Thieving tome", + "weight": 1.0 + }, + "7786": { + "name": "Thieving tome", + "weight": 1.0 + }, + "7787": { + "name": "Thieving tome", + "weight": 1.0 + }, + "7788": { + "name": "Slayer tome", + "weight": 1.0 + }, + "7789": { + "name": "Slayer tome", + "weight": 1.0 + }, + "7790": { + "name": "Slayer tome", + "weight": 1.0 + }, + "7791": { + "name": "Mining tome", + "weight": 1.0 + }, + "7792": { + "name": "Mining tome", + "weight": 1.0 + }, + "7793": { + "name": "Mining tome", + "weight": 1.0 + }, + "7794": { + "name": "Firemaking tome", + "weight": 1.0 + }, + "7795": { + "name": "Firemaking tome", + "weight": 1.0 + }, + "7796": { + "name": "Firemaking tome", + "weight": 1.0 + }, + "7797": { + "name": "Woodcutting tome", + "weight": 1.0 + }, + "7798": { + "name": "Woodcutting tome", + "weight": 1.0 + }, + "7799": { + "name": "Woodcutting tome", + "weight": 1.0 + }, + "7800": { + "name": "Snail shell", + "weight": 7.0 + }, + "7801": { + "name": "Snake hide", + "weight": 1.0 + }, + "7803": { + "name": "Yin yang amulet", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 2 + } + }, + "7806": { + "name": "Anger sword", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dslash": 2, + "dcrush": 1, + "aspeed": 4 + } + }, + "7807": { + "name": "Anger battleaxe", + "quest": true, + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": 2, + "acrush": 2, + "drange": -1, + "aspeed": 6 + } + }, + "7808": { + "name": "Anger mace", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": 2, + "acrush": 2, + "prayer": 1, + "aspeed": 5 + } + }, + "7809": { + "name": "Anger spear", + "quest": true, + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": 2, + "acrush": 2, + "dstab": 1, + "dslash": 1, + "aspeed": 5 + } + }, + "7810": { + "name": "Jug of vinegar", + "quest": true, + "weight": 1.0 + }, + "7811": { + "name": "Pot of vinegar", + "quest": true, + "weight": 1.36 + }, + "7812": { + "name": "Goblin skull", + "quest": true, + "weight": 0.003 + }, + "7813": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7814": { + "name": "Goblin skull", + "quest": true, + "weight": 0.003 + }, + "7815": { + "name": "Bear ribs", + "quest": true, + "weight": 0.003 + }, + "7816": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7817": { + "name": "Bear ribs", + "quest": true, + "weight": 0.003 + }, + "7818": { + "name": "Ram skull", + "quest": true, + "weight": 0.003 + }, + "7819": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7820": { + "name": "Ram skull", + "quest": true, + "weight": 0.003 + }, + "7821": { + "name": "Unicorn bone", + "quest": true, + "weight": 0.003 + }, + "7822": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7823": { + "name": "Unicorn bone", + "quest": true, + "weight": 0.003 + }, + "7824": { + "name": "Giant rat bone", + "quest": true, + "weight": 0.003 + }, + "7825": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7826": { + "name": "Giant rat bone", + "quest": true, + "weight": 0.003 + }, + "7827": { + "name": "Giant bat wing", + "quest": true, + "weight": 0.907 + }, + "7828": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7829": { + "name": "Giant bat wing", + "quest": true, + "weight": 0.907 + }, + "7830": { + "name": "Wolf bone", + "quest": true, + "weight": 0.907 + }, + "7831": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7832": { + "name": "Wolf bone", + "quest": true, + "weight": 0.907 + }, + "7833": { + "name": "Bat wing", + "quest": true, + "weight": 0.907 + }, + "7834": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7835": { + "name": "Bat wing", + "quest": true, + "weight": 0.907 + }, + "7836": { + "name": "Rat bone", + "quest": true, + "weight": 0.4 + }, + "7837": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7838": { + "name": "Rat bone", + "quest": true, + "weight": 0.4 + }, + "7839": { + "name": "Baby dragon bone", + "quest": true, + "weight": 0.907 + }, + "7840": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7841": { + "name": "Baby dragon bone", + "quest": true, + "weight": 0.907 + }, + "7842": { + "name": "Ogre ribs", + "quest": true, + "weight": 0.907 + }, + "7843": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7844": { + "name": "Ogre ribs", + "quest": true, + "weight": 0.907 + }, + "7845": { + "name": "Jogre bone", + "quest": true, + "weight": 0.907 + }, + "7846": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7847": { + "name": "Jogre bone", + "quest": true, + "weight": 0.907 + }, + "7848": { + "name": "Zogre bone", + "quest": true, + "weight": 0.907 + }, + "7849": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7850": { + "name": "Zogre bone", + "quest": true, + "weight": 0.907 + }, + "7851": { + "name": "Mogre bone", + "quest": true, + "weight": 0.907 + }, + "7852": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7853": { + "name": "Mogre bone", + "quest": true, + "weight": 0.907 + }, + "7854": { + "name": "Monkey paw", + "quest": true, + "weight": 0.003 + }, + "7855": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7856": { + "name": "Monkey paw", + "quest": true, + "weight": 0.003 + }, + "7857": { + "name": "Dagannoth ribs", + "quest": true, + "weight": 0.907 + }, + "7858": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7859": { + "name": "Dagannoth ribs", + "quest": true, + "weight": 0.907 + }, + "7860": { + "name": "Snake spine", + "quest": true, + "weight": 0.907 + }, + "7861": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7862": { + "name": "Snake spine", + "quest": true, + "weight": 0.907 + }, + "7863": { + "name": "Zombie bone", + "quest": true, + "weight": 0.907 + }, + "7864": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7865": { + "name": "Zombie bone", + "quest": true, + "weight": 0.907 + }, + "7866": { + "name": "Werewolf bone", + "quest": true, + "weight": 0.907 + }, + "7867": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7868": { + "name": "Werewolf bone", + "quest": true, + "weight": 0.907 + }, + "7869": { + "name": "Moss giant bone", + "quest": true, + "weight": 0.003 + }, + "7870": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7871": { + "name": "Moss giant bone", + "quest": true, + "weight": 0.003 + }, + "7872": { + "name": "Fire giant bone", + "quest": true, + "weight": 0.907 + }, + "7873": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7874": { + "name": "Fire giant bone", + "quest": true, + "weight": 0.907 + }, + "7875": { + "name": "Ice giant ribs", + "quest": true, + "weight": 0.907 + }, + "7876": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7877": { + "name": "Ice giant ribs", + "quest": true, + "weight": 0.907 + }, + "7878": { + "name": "Terrorbird wing", + "quest": true, + "weight": 0.907 + }, + "7879": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7880": { + "name": "Terrorbird wing", + "quest": true, + "weight": 0.907 + }, + "7881": { + "name": "Ghoul bone", + "quest": true, + "weight": 0.907 + }, + "7882": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7883": { + "name": "Ghoul bone", + "quest": true, + "weight": 0.907 + }, + "7884": { + "name": "Troll bone", + "quest": true, + "weight": 0.907 + }, + "7885": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7886": { + "name": "Troll bone", + "quest": true, + "weight": 0.907 + }, + "7887": { + "name": "Seagull wing", + "quest": true, + "weight": 0.9 + }, + "7888": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7889": { + "name": "Seagull wing", + "quest": true, + "weight": 0.9 + }, + "7890": { + "name": "Undead cow ribs", + "quest": true, + "weight": 0.907 + }, + "7891": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7892": { + "name": "Undead cow ribs", + "quest": true, + "weight": 0.907 + }, + "7893": { + "name": "Experiment bone", + "quest": true, + "weight": 0.907 + }, + "7894": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7895": { + "name": "Experiment bone", + "quest": true, + "weight": 0.907 + }, + "7896": { + "name": "Rabbit bone", + "quest": true, + "weight": 0.907 + }, + "7897": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7898": { + "name": "Rabbit bone", + "quest": true, + "weight": 0.907 + }, + "7899": { + "name": "Basilisk bone", + "quest": true, + "weight": 0.907 + }, + "7900": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7901": { + "name": "Basilisk bone", + "quest": true, + "weight": 0.907 + }, + "7902": { + "name": "Desert lizard bone", + "quest": true, + "weight": 0.907 + }, + "7903": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7904": { + "name": "Desert lizard bone", + "quest": true, + "weight": 0.907 + }, + "7905": { + "name": "Cave goblin skull", + "quest": true, + "weight": 0.907 + }, + "7906": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7907": { + "name": "Cave goblin skull", + "quest": true, + "weight": 0.907 + }, + "7908": { + "name": "Big frog leg", + "quest": true, + "weight": 0.907 + }, + "7909": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7910": { + "name": "Big frog leg", + "quest": true, + "weight": 0.907 + }, + "7911": { + "name": "Vulture wing", + "quest": true, + "weight": 0.907 + }, + "7912": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7913": { + "name": "Vulture wing", + "quest": true, + "weight": 0.907 + }, + "7914": { + "name": "Jackal bone", + "quest": true, + "weight": 0.003 + }, + "7915": { + "name": "Bone in vinegar", + "quest": true, + "weight": 1.36 + }, + "7916": { + "name": "Jackal bone", + "quest": true, + "weight": 0.003 + }, + "7917": { + "name": "Ram skull helm", + "quest": true, + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "drange": 19 + } + }, + "7918": { + "name": "Bonesack", + "quest": true, + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 1, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4 + } + }, + "7919": { + "name": "Bottle of wine", + "weight": 1.0 + }, + "7921": { + "name": "Empty wine bottle", + "weight": 1.0 + }, + "7922": { + "name": "Al kharid flyer", + "weight": 0.001 + }, + "7927": { + "name": "Easter ring", + "weight": 0.001 + }, + "7928": { + "name": "Easter egg", + "weight": 0.15 + }, + "7929": { + "name": "Easter egg", + "weight": 0.15 + }, + "7930": { + "name": "Easter egg", + "weight": 0.15 + }, + "7931": { + "name": "Easter egg", + "weight": 0.15 + }, + "7932": { + "name": "Easter egg", + "weight": 0.15 + }, + "7933": { + "name": "Easter egg", + "weight": 0.15 + }, + "7934": { + "name": "Field ration", + "weight": 0.001 + }, + "7936": { + "name": "Pure essence", + "weight": 0.002 + }, + "7938": { + "name": "Dark essence fragments" + }, + "7939": { + "name": "Tortoise shell", + "weight": 6.803 + }, + "7941": { + "name": "Iron sheet", + "quest": true, + "weight": 1.814 + }, + "7942": { + "name": "Fresh monkfish", + "quest": true, + "weight": 0.45 + }, + "7943": { + "name": "Fresh monkfish", + "quest": true, + "weight": 0.45 + }, + "7944": { + "name": "Raw monkfish", + "weight": 0.45 + }, + "7946": { + "name": "Monkfish", + "weight": 0.4 + }, + "7948": { + "name": "Burnt monkfish" + }, + "7950": { + "name": "Bone seeds", + "quest": true, + "weight": 0.001 + }, + "7951": { + "name": "Herman's book", + "quest": true, + "weight": 0.07 + }, + "7954": { + "name": "Burnt shrimp" + }, + "7956": { + "name": "Casket", + "quest": true, + "weight": 5.0 + }, + "7957": { + "name": "White apron", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 4 + } + }, + "7958": { + "name": "Mining prop", + "quest": true, + "weight": 0.01 + }, + "7959": { + "name": "Heavy box", + "quest": true, + "weight": 0.01 + }, + "7960": { + "name": "Empty box", + "weight": 0.01 + }, + "7961": { + "name": "Burnt diary", + "quest": true + }, + "7962": { + "name": "Burnt diary", + "quest": true + }, + "7963": { + "name": "Burnt diary", + "quest": true + }, + "7964": { + "name": "Burnt diary", + "quest": true + }, + "7965": { + "name": "Burnt diary", + "quest": true + }, + "7966": { + "name": "Letter", + "quest": true, + "weight": 0.01 + }, + "7967": { + "name": "Engine", + "quest": true, + "weight": 1.0 + }, + "7968": { + "name": "Scroll", + "quest": true, + "weight": 0.01 + }, + "7969": { + "name": "Pulley beam", + "quest": true, + "weight": 0.01 + }, + "7970": { + "name": "Long pulley beam", + "quest": true, + "weight": 0.01 + }, + "7971": { + "name": "Longer pulley beam", + "quest": true, + "weight": 0.01 + }, + "7972": { + "name": "Lift manual", + "quest": true + }, + "7973": { + "name": "Beam", + "quest": true, + "weight": 0.01 + }, + "7975": { + "name": "Crawling hand", + "weight": 10.0 + }, + "7976": { + "name": "Cockatrice head", + "weight": 10.0 + }, + "7977": { + "name": "Basilisk head", + "weight": 10.0 + }, + "7978": { + "name": "Kurask head", + "weight": 10.0 + }, + "7979": { + "name": "Abyssal head", + "weight": 10.0 + }, + "7980": { + "name": "Kbd heads", + "weight": 10.0 + }, + "7981": { + "name": "Kq head", + "weight": 10.0 + }, + "7982": { + "name": "Stuffed crawling hand", + "weight": 10.0 + }, + "7983": { + "name": "Stuffed cockatrice head", + "weight": 10.0 + }, + "7984": { + "name": "Stuffed basilisk head", + "weight": 10.0 + }, + "7985": { + "name": "Stuffed kurask head", + "weight": 10.0 + }, + "7986": { + "name": "Stuffed abyssal head", + "weight": 10.0 + }, + "7987": { + "name": "Stuffed kbd heads", + "weight": 10.0 + }, + "7988": { + "name": "Stuffed kq head", + "weight": 10.0 + }, + "7989": { + "name": "Big bass" + }, + "7990": { + "name": "Stuffed big bass", + "weight": 0.35 + }, + "7991": { + "name": "Big swordfish", + "weight": 0.5 + }, + "7992": { + "name": "Stuffed big swordfish", + "weight": 0.45 + }, + "7993": { + "name": "Big shark", + "weight": 0.7 + }, + "7994": { + "name": "Stuffed big shark", + "weight": 0.65 + }, + "7995": { + "name": "Arthur portrait", + "weight": 1.0 + }, + "7996": { + "name": "Elena portrait", + "weight": 1.0 + }, + "7997": { + "name": "Keldagrim portrait", + "weight": 1.0 + }, + "7998": { + "name": "Misc. portrait", + "weight": 1.0 + }, + "7999": { + "name": "Desert painting", + "weight": 1.0 + }, + "8000": { + "name": "Isafdar painting", + "weight": 1.0 + }, + "8001": { + "name": "Karamja painting", + "weight": 1.0 + }, + "8002": { + "name": "Lumbridge painting", + "weight": 1.0 + }, + "8003": { + "name": "Morytania painting", + "weight": 1.0 + }, + "8004": { + "name": "Small map", + "weight": 1.0 + }, + "8005": { + "name": "Medium map", + "weight": 1.0 + }, + "8006": { + "name": "Large map", + "weight": 1.0 + }, + "8007": { + "name": "Varrock teleport" + }, + "8008": { + "name": "Lumbridge teleport" + }, + "8009": { + "name": "Falador teleport" + }, + "8010": { + "name": "Camelot teleport" + }, + "8011": { + "name": "Ardougne teleport" + }, + "8012": { + "name": "Watchtower teleport" + }, + "8013": { + "name": "Teleport to house" + }, + "8014": { + "name": "Bones to bananas" + }, + "8015": { + "name": "Bones to peaches" + }, + "8016": { + "name": "Enchant sapphire or opal" + }, + "8017": { + "name": "Enchant emerald or jade" + }, + "8018": { + "name": "Enchant ruby or topaz" + }, + "8019": { + "name": "Enchant diamond" + }, + "8020": { + "name": "Enchant dragonstone" + }, + "8021": { + "name": "Enchant onyx" + }, + "8022": { + "name": "Telekinetic grab" + }, + "8417": { + "name": "Bagged dead tree", + "weight": 10.0 + }, + "8419": { + "name": "Bagged nice tree", + "weight": 10.0 + }, + "8421": { + "name": "Bagged oak tree", + "weight": 10.0 + }, + "8423": { + "name": "Bagged willow tree", + "weight": 10.0 + }, + "8425": { + "name": "Bagged maple tree", + "weight": 10.0 + }, + "8427": { + "name": "Bagged yew tree", + "weight": 10.0 + }, + "8429": { + "name": "Bagged magic tree", + "weight": 10.0 + }, + "8431": { + "name": "Bagged plant 1", + "weight": 10.0 + }, + "8433": { + "name": "Bagged plant 2", + "weight": 10.0 + }, + "8435": { + "name": "Bagged plant 3", + "weight": 10.0 + }, + "8437": { + "name": "Thorny hedge", + "weight": 10.0 + }, + "8439": { + "name": "Nice hedge", + "weight": 10.0 + }, + "8441": { + "name": "Small box hedge", + "weight": 10.0 + }, + "8443": { + "name": "Topiary hedge", + "weight": 10.0 + }, + "8445": { + "name": "Fancy hedge", + "weight": 10.0 + }, + "8447": { + "name": "Tall fancy hedge", + "weight": 10.0 + }, + "8449": { + "name": "Tall box hedge", + "weight": 10.0 + }, + "8451": { + "name": "Bagged flower", + "weight": 10.0 + }, + "8453": { + "name": "Bagged daffodils", + "weight": 10.0 + }, + "8455": { + "name": "Bagged bluebells", + "weight": 10.0 + }, + "8457": { + "name": "Bagged sunflower", + "weight": 10.0 + }, + "8459": { + "name": "Bagged marigolds", + "weight": 10.0 + }, + "8461": { + "name": "Bagged roses", + "weight": 10.0 + }, + "8463": { + "name": "Construction guide", + "weight": 1.0 + }, + "8464": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8466": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8468": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8470": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8472": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8474": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8476": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8478": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8480": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8482": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8484": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8486": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8488": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8490": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8492": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8494": { + "name": "Rune heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "8496": { + "name": "Crude chair", + "weight": 1.0 + }, + "8498": { + "name": "Wooden chair", + "weight": 1.0 + }, + "8500": { + "name": "Rocking chair", + "weight": 1.0 + }, + "8502": { + "name": "Oak chair", + "weight": 1.0 + }, + "8504": { + "name": "Oak armchair", + "weight": 1.0 + }, + "8506": { + "name": "Teak armchair", + "weight": 1.0 + }, + "8508": { + "name": "Mahogany armchair", + "weight": 1.0 + }, + "8510": { + "name": "Bookcase", + "weight": 1.0 + }, + "8512": { + "name": "Oak bookcase", + "weight": 1.0 + }, + "8514": { + "name": "Mahogany bookcase", + "weight": 1.0 + }, + "8516": { + "name": "Beer barrel", + "weight": 1.0 + }, + "8518": { + "name": "Cider barrel", + "weight": 1.0 + }, + "8520": { + "name": "Asgarnian ale", + "weight": 1.0 + }, + "8522": { + "name": "Greenman's ale", + "weight": 1.0 + }, + "8524": { + "name": "Dragon bitter", + "weight": 1.0 + }, + "8526": { + "name": "Chef's delight", + "weight": 1.0 + }, + "8528": { + "name": "Kitchen table", + "weight": 1.0 + }, + "8530": { + "name": "Oak kitchen table", + "weight": 1.0 + }, + "8532": { + "name": "Teak kitchen table", + "weight": 1.0 + }, + "8534": { + "name": "Oak lectern", + "weight": 1.0 + }, + "8536": { + "name": "Eagle lectern", + "weight": 1.0 + }, + "8538": { + "name": "Demon lectern", + "weight": 1.0 + }, + "8540": { + "name": "Teak eagle lectern", + "weight": 1.0 + }, + "8542": { + "name": "Teak demon lectern", + "weight": 1.0 + }, + "8544": { + "name": "Mahogany eagle", + "weight": 1.0 + }, + "8546": { + "name": "Mahogany demon", + "weight": 1.0 + }, + "8548": { + "name": "Wood dining table", + "weight": 1.0 + }, + "8550": { + "name": "Oak dining table", + "weight": 1.0 + }, + "8552": { + "name": "Carved oak table", + "weight": 1.0 + }, + "8554": { + "name": "Teak table", + "weight": 1.0 + }, + "8556": { + "name": "Carved teak table", + "weight": 1.0 + }, + "8558": { + "name": "Mahogany table", + "weight": 1.0 + }, + "8560": { + "name": "Opulent table", + "weight": 1.0 + }, + "8562": { + "name": "Wooden bench", + "weight": 1.0 + }, + "8564": { + "name": "Oak bench", + "weight": 1.0 + }, + "8566": { + "name": "Carved oak bench", + "weight": 1.0 + }, + "8568": { + "name": "Teak dining bench", + "weight": 1.0 + }, + "8570": { + "name": "Carved teak bench", + "weight": 1.0 + }, + "8572": { + "name": "Mahogany bench", + "weight": 1.0 + }, + "8574": { + "name": "Gilded bench", + "weight": 1.0 + }, + "8576": { + "name": "Wooden bed", + "weight": 1.0 + }, + "8578": { + "name": "Oak bed", + "weight": 1.0 + }, + "8580": { + "name": "Large oak bed", + "weight": 1.0 + }, + "8582": { + "name": "Teak bed", + "weight": 1.0 + }, + "8584": { + "name": "Large teak bed", + "weight": 1.0 + }, + "8586": { + "name": "Four-poster bed", + "weight": 1.0 + }, + "8588": { + "name": "Gilded four-poster", + "weight": 1.0 + }, + "8590": { + "name": "Oak clock", + "weight": 1.0 + }, + "8592": { + "name": "Teak clock", + "weight": 1.0 + }, + "8594": { + "name": "Gilded clock", + "weight": 1.0 + }, + "8596": { + "name": "Shaving stand", + "weight": 1.0 + }, + "8598": { + "name": "Oak shaving stand", + "weight": 1.0 + }, + "8600": { + "name": "Oak dresser", + "weight": 1.0 + }, + "8602": { + "name": "Teak dresser", + "weight": 1.0 + }, + "8604": { + "name": "Fancy teak dresser", + "weight": 1.0 + }, + "8606": { + "name": "Mahogany dresser", + "weight": 1.0 + }, + "8608": { + "name": "Gilded dresser", + "weight": 1.0 + }, + "8610": { + "name": "Shoe box", + "weight": 1.0 + }, + "8612": { + "name": "Oak drawers", + "weight": 1.0 + }, + "8614": { + "name": "Oak wardrobe", + "weight": 1.0 + }, + "8616": { + "name": "Teak drawers", + "weight": 1.0 + }, + "8618": { + "name": "Teak wardrobe", + "weight": 1.0 + }, + "8620": { + "name": "Mahogany wardrobe", + "weight": 1.0 + }, + "8622": { + "name": "Gilded wardrobe", + "weight": 1.0 + }, + "8624": { + "name": "Crystal ball", + "weight": 1.0 + }, + "8626": { + "name": "Elemental sphere", + "weight": 1.0 + }, + "8628": { + "name": "Crystal of power", + "weight": 1.0 + }, + "8630": { + "name": "Globe", + "weight": 1.0 + }, + "8632": { + "name": "Ornamental globe", + "weight": 1.0 + }, + "8634": { + "name": "Lunar globe", + "weight": 1.0 + }, + "8636": { + "name": "Celestial globe", + "weight": 1.0 + }, + "8638": { + "name": "Armillary sphere", + "weight": 1.0 + }, + "8640": { + "name": "Small orrery", + "weight": 1.0 + }, + "8642": { + "name": "Large orrery", + "weight": 1.0 + }, + "8644": { + "name": "Wooden telescope", + "weight": 1.0 + }, + "8646": { + "name": "Teak telescope", + "weight": 1.0 + }, + "8648": { + "name": "Mahogany telescope", + "weight": 1.0 + }, + "8650": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8652": { + "name": "Banner", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8654": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8656": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8658": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8660": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8662": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8664": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8666": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8668": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8670": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8672": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8674": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8676": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8678": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8680": { + "name": "Banner", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8682": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8684": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8686": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8688": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8690": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8692": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8694": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8696": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8698": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8700": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8702": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8704": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8706": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8708": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8710": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8712": { + "name": "Steel heraldic helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "8714": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8716": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8718": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8720": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8722": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8724": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8726": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8728": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8730": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8732": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8734": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8736": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8738": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8740": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8742": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8744": { + "name": "Rune kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46 + } + }, + "8746": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8748": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8750": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8752": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8754": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8756": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8758": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8760": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8762": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8764": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8766": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8768": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8770": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8772": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8774": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8776": { + "name": "Steel kiteshield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "8778": { + "name": "Oak plank", + "weight": 0.8 + }, + "8780": { + "name": "Teak plank", + "weight": 0.8 + }, + "8782": { + "name": "Mahogany plank", + "weight": 0.8 + }, + "8784": { + "name": "Gold leaf", + "weight": 1.0 + }, + "8786": { + "name": "Marble block", + "weight": 13.607 + }, + "8788": { + "name": "Magic stone", + "weight": 1.0 + }, + "8790": { + "name": "Bolt of cloth", + "weight": 1.0 + }, + "8792": { + "name": "Clockwork", + "weight": 1.0 + }, + "8794": { + "name": "Saw", + "weight": 1.0 + }, + "8837": { + "name": "Timber beam" + }, + "8839": { + "name": "Void knight top", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "dstab": 45, + "dslash": 45, + "dcrush": 45, + "dmagic": 45, + "drange": 45 + } + }, + "8840": { + "name": "Void knight robe", + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "dstab": 30, + "dslash": 30, + "dcrush": 30, + "dmagic": 30, + "drange": 30 + } + }, + "8841": { + "name": "Void knight mace", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 22, + "acrush": 41, + "amagic": 8, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": 2, + "str": 38, + "prayer": 6, + "aspeed": 5 + } + }, + "8842": { + "name": "Void knight gloves", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 4, + "drange": 6 + } + }, + "8844": { + "name": "Bronze defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 3, + "aslash": 2, + "acrush": 1, + "amagic": -3, + "arange": -2, + "dstab": 3, + "dslash": 2, + "dcrush": 1, + "dmagic": -3, + "drange": -2 + } + }, + "8845": { + "name": "Iron defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 5, + "aslash": 4, + "acrush": 3, + "amagic": -3, + "arange": -2, + "dstab": 5, + "dslash": 4, + "dcrush": 3, + "dmagic": -3, + "drange": -2 + } + }, + "8846": { + "name": "Steel defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 7, + "aslash": 6, + "acrush": 5, + "amagic": -3, + "arange": -2, + "dstab": 7, + "dslash": 6, + "dcrush": 5, + "dmagic": -3, + "drange": -2, + "str": 1 + } + }, + "8847": { + "name": "Black defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 9, + "aslash": 8, + "acrush": 7, + "amagic": -3, + "arange": -2, + "dstab": 9, + "dslash": 8, + "dcrush": 7, + "dmagic": -3, + "drange": -2, + "str": 2 + } + }, + "8848": { + "name": "Mithril defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 10, + "aslash": 9, + "acrush": 8, + "amagic": -3, + "arange": -2, + "dstab": 10, + "dslash": 9, + "dcrush": 8, + "dmagic": -3, + "drange": -2, + "str": 3 + } + }, + "8849": { + "name": "Adamant defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 13, + "aslash": 12, + "acrush": 11, + "amagic": -3, + "arange": -2, + "dstab": 13, + "dslash": 12, + "dcrush": 11, + "dmagic": -3, + "drange": -2, + "str": 4 + } + }, + "8850": { + "name": "Rune defender", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 5, + "astab": 20, + "aslash": 19, + "acrush": 18, + "amagic": -3, + "arange": -2, + "dstab": 20, + "dslash": 19, + "dcrush": 18, + "dmagic": -3, + "drange": -2, + "str": 5 + } + }, + "8851": { + "name": "Warrior guild token" + }, + "8856": { + "name": "Defensive shield", + "equipable": true, + "weight": 3.6, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "drange": 7 + } + }, + "8858": { + "name": "18lb shot", + "weight": 8.164 + }, + "8859": { + "name": "22lb shot", + "weight": 9.979 + }, + "8860": { + "name": "One barrel", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 0 + } + }, + "8861": { + "name": "Two barrels", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 0 + } + }, + "8862": { + "name": "Three barrels", + "equipable": true, + "weight": 13.607, + "equipment": { + "slot": 0 + } + }, + "8863": { + "name": "Four barrels", + "equipable": true, + "weight": 18.143, + "equipment": { + "slot": 0 + } + }, + "8864": { + "name": "Five barrels", + "equipable": true, + "weight": 22.679, + "equipment": { + "slot": 0 + } + }, + "8865": { + "name": "Ground ashes", + "weight": 0.056 + }, + "8866": { + "name": "Steel key", + "weight": 0.01 + }, + "8867": { + "name": "Bronze key", + "weight": 0.01 + }, + "8868": { + "name": "Silver key", + "weight": 0.01 + }, + "8869": { + "name": "Iron key", + "weight": 0.01 + }, + "8870": { + "name": "Zanik", + "quest": true, + "weight": 30.0 + }, + "8871": { + "name": "Crate with zanik", + "quest": true, + "equipable": true, + "weight": 32.0, + "equipment": { + "slot": 3 + } + }, + "8872": { + "name": "Bone dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "8874": { + "name": "Bone dagger (p)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "8876": { + "name": "Bone dagger (p+)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "8878": { + "name": "Bone dagger (p++)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 3, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 4, + "aspeed": 4 + } + }, + "8880": { + "name": "Dorgeshuun crossbow", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "arange": 42, + "aspeed": 5 + } + }, + "8882": { + "name": "Bone bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "8887": { + "name": "Zanik", + "quest": true, + "weight": 30.0 + }, + "8890": { + "name": "Coins" + }, + "8901": { + "name": "Black mask (10)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8903": { + "name": "Black mask (9)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8905": { + "name": "Black mask (8)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8907": { + "name": "Black mask (7)", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8909": { + "name": "Black mask (6)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8911": { + "name": "Black mask (5)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8913": { + "name": "Black mask (4)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8915": { + "name": "Black mask (3)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8917": { + "name": "Black mask (2)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8919": { + "name": "Black mask (1)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8921": { + "name": "Black mask", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "8923": { + "name": "Witchwood icon", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2, + "amagic": 1, + "prayer": 1 + } + }, + "8924": { + "name": "Bandana eyepatch", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 0 + } + }, + "8925": { + "name": "Bandana eyepatch", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 0 + } + }, + "8926": { + "name": "Bandana eyepatch", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 0 + } + }, + "8927": { + "name": "Bandana eyepatch", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 0 + } + }, + "8928": { + "name": "Hat eyepatch", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 0 + } + }, + "8929": { + "name": "Crabclaw hook", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "dstab": 3, + "dslash": 5, + "dcrush": 3, + "str": 1 + } + }, + "8930": { + "name": "Pipe section", + "weight": 0.003 + }, + "8932": { + "name": "Lumber patch", + "weight": 0.003 + }, + "8934": { + "name": "Scrapey tree logs", + "weight": 0.003 + }, + "8936": { + "name": "Blue flowers", + "weight": 0.003 + }, + "8938": { + "name": "Red flowers", + "weight": 0.003 + }, + "8940": { + "name": "Rum", + "weight": 0.003 + }, + "8941": { + "name": "Rum", + "weight": 0.003 + }, + "8942": { + "name": "Monkey", + "weight": 0.003 + }, + "8943": { + "name": "Blue monkey" + }, + "8944": { + "name": "Blue monkey" + }, + "8945": { + "name": "Blue monkey" + }, + "8946": { + "name": "Red monkey" + }, + "8947": { + "name": "Red monkey" + }, + "8948": { + "name": "Red monkey" + }, + "8949": { + "name": "Pirate bandana", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8950": { + "name": "Pirate hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8951": { + "name": "Pieces of eight" + }, + "8952": { + "name": "Blue naval shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "8953": { + "name": "Green naval shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "8954": { + "name": "Red naval shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "8955": { + "name": "Brown naval shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "8956": { + "name": "Black naval shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "8957": { + "name": "Purple naval shirt", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 4 + } + }, + "8958": { + "name": "Grey naval shirt", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "8959": { + "name": "Blue tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8960": { + "name": "Green tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8961": { + "name": "Red tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8962": { + "name": "Brown tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8963": { + "name": "Black tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8964": { + "name": "Purple tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8965": { + "name": "Grey tricorn hat", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "8966": { + "name": "Cutthroat flag", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8967": { + "name": "Guilded smile flag", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8968": { + "name": "Bronze fist flag", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8969": { + "name": "Lucky shot flag", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8970": { + "name": "Treasure flag", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8971": { + "name": "Phasmatys flag", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "8972": { + "name": "Bowl of red water", + "weight": 0.003 + }, + "8974": { + "name": "Bowl of blue water", + "weight": 0.003 + }, + "8976": { + "name": "Bitternut", + "weight": 0.003 + }, + "8977": { + "name": "Scrapey bark", + "weight": 0.003 + }, + "8979": { + "name": "Bridge section", + "weight": 0.003 + }, + "8981": { + "name": "Sweetgrubs", + "weight": 0.003 + }, + "8988": { + "name": "The stuff", + "weight": 0.001 + }, + "8989": { + "name": "Brewin' guide", + "weight": 0.001 + }, + "8990": { + "name": "Brewin' guide", + "weight": 0.001 + }, + "8991": { + "name": "Blue navy slacks", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "8992": { + "name": "Green navy slacks", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "8993": { + "name": "Red navy slacks", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "8994": { + "name": "Brown navy slacks", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "8995": { + "name": "Black navy slacks", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "8996": { + "name": "Purple navy slacks", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "8997": { + "name": "Grey navy slacks", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 7 + } + }, + "9003": { + "name": "Security book", + "weight": 0.01 + }, + "9004": { + "name": "Stronghold notes", + "weight": 0.01 + }, + "9005": { + "name": "Fancy boots", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 1, + "dslash": 2, + "dcrush": 3 + } + }, + "9006": { + "name": "Fighting boots", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 1, + "dslash": 2, + "dcrush": 3 + } + }, + "9007": { + "name": "Right skull half", + "weight": 0.08 + }, + "9008": { + "name": "Left skull half", + "weight": 0.08 + }, + "9009": { + "name": "Strange skull", + "weight": 1.2 + }, + "9010": { + "name": "Top of sceptre", + "weight": 1.814 + }, + "9011": { + "name": "Bottom of sceptre", + "weight": 1.814 + }, + "9012": { + "name": "Runed sceptre", + "weight": 3.628 + }, + "9013": { + "name": "Skull sceptre", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "9016": { + "name": "Gorak claws", + "quest": true, + "weight": 0.001 + }, + "9017": { + "name": "Star flower", + "quest": true, + "weight": 0.001 + }, + "9018": { + "name": "Gorak claw powder", + "quest": true, + "weight": 0.001 + }, + "9019": { + "name": "Magic essence (unf)", + "quest": true, + "weight": 0.001 + }, + "9020": { + "name": "Queen's secateurs", + "quest": true, + "weight": 0.453 + }, + "9021": { + "name": "Magic essence(4)", + "quest": true, + "weight": 0.035 + }, + "9022": { + "name": "Magic essence(3)", + "quest": true, + "weight": 0.03 + }, + "9023": { + "name": "Magic essence(2)", + "quest": true, + "weight": 0.025 + }, + "9024": { + "name": "Magic essence(1)", + "quest": true, + "weight": 0.02 + }, + "9025": { + "name": "Nuff's certificate", + "quest": true, + "weight": 0.01 + }, + "9026": { + "name": "Ivory comb" + }, + "9028": { + "name": "Golden scarab", + "weight": 0.01 + }, + "9030": { + "name": "Stone scarab", + "weight": 0.01 + }, + "9032": { + "name": "Pottery scarab", + "weight": 0.01 + }, + "9034": { + "name": "Golden statuette", + "weight": 0.1 + }, + "9036": { + "name": "Pottery statuette", + "weight": 0.1 + }, + "9038": { + "name": "Stone statuette", + "weight": 0.1 + }, + "9040": { + "name": "Gold seal", + "weight": 0.01 + }, + "9042": { + "name": "Stone seal", + "weight": 0.01 + }, + "9044": { + "name": "Pharaoh's sceptre (3)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "9046": { + "name": "Pharaoh's sceptre (2)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "9048": { + "name": "Pharaoh's sceptre (1)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "9050": { + "name": "Pharaoh's sceptre", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "9052": { + "name": "Locust meat", + "weight": 0.003 + }, + "9054": { + "name": "Red goblin mail", + "weight": 3.628 + }, + "9055": { + "name": "Black goblin mail", + "weight": 3.628 + }, + "9056": { + "name": "Yellow goblin mail", + "weight": 3.628 + }, + "9057": { + "name": "Green goblin mail", + "weight": 3.628 + }, + "9058": { + "name": "Purple goblin mail", + "weight": 3.628 + }, + "9059": { + "name": "Pink goblin mail", + "weight": 3.628 + }, + "9064": { + "name": "Emerald lantern", + "quest": true, + "weight": 1.3 + }, + "9065": { + "name": "Emerald lantern", + "quest": true, + "weight": 1.3 + }, + "9066": { + "name": "Emerald lens", + "quest": true, + "weight": 0.028 + }, + "9067": { + "name": "Dream log", + "quest": true, + "weight": 1.36 + }, + "9068": { + "name": "Moonclan helm", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": -5, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": -5 + } + }, + "9069": { + "name": "Moonclan hat", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": -5, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": -5 + } + }, + "9070": { + "name": "Moonclan armour", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 5, + "arange": -10, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": -10 + } + }, + "9071": { + "name": "Moonclan skirt", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 7, + "amagic": 5, + "arange": -7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": -7 + } + }, + "9072": { + "name": "Moonclan gloves", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 9, + "amagic": 2, + "arange": -5, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": -5 + } + }, + "9073": { + "name": "Moonclan boots", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 10, + "amagic": 2, + "arange": -5, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": -5 + } + }, + "9074": { + "name": "Moonclan cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "amagic": 2, + "arange": -2, + "dslash": 1, + "dcrush": 1, + "dmagic": 2, + "drange": -2 + } + }, + "9075": { + "name": "Astral rune" + }, + "9076": { + "name": "Lunar ore", + "quest": true, + "weight": 2.267 + }, + "9077": { + "name": "Lunar bar", + "quest": true, + "weight": 1.8 + }, + "9078": { + "name": "Moonclan manual", + "weight": 0.51 + }, + "9079": { + "name": "Suqah tooth", + "quest": true, + "weight": 0.01 + }, + "9080": { + "name": "Suqah hide", + "quest": true, + "weight": 3.175 + }, + "9081": { + "name": "Suqah leather", + "quest": true, + "weight": 3.175 + }, + "9082": { + "name": "Ground tooth", + "quest": true, + "weight": 0.007 + }, + "9083": { + "name": "Seal of passage", + "quest": true, + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 2 + } + }, + "9084": { + "name": "Lunar staff", + "quest": true, + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 3, + "aslash": 2, + "acrush": 16, + "amagic": 13, + "dstab": 2, + "dslash": 3, + "dcrush": 2, + "dmagic": 13, + "drange": 1, + "str": 15, + "prayer": 3, + "aspeed": 5 + } + }, + "9085": { + "name": "Empty vial", + "quest": true, + "weight": 0.5 + }, + "9086": { + "name": "Vial of water", + "quest": true, + "weight": 0.5 + }, + "9087": { + "name": "Waking sleep vial", + "quest": true, + "weight": 0.5 + }, + "9088": { + "name": "Guam vial", + "quest": true, + "weight": 0.5 + }, + "9089": { + "name": "Marr vial", + "quest": true, + "weight": 0.5 + }, + "9090": { + "name": "Guam-marr vial", + "quest": true, + "weight": 0.5 + }, + "9091": { + "name": "Lunar staff - pt1", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 10, + "aspeed": 4 + } + }, + "9092": { + "name": "Lunar staff - pt2", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 10, + "aspeed": 4 + } + }, + "9093": { + "name": "Lunar staff - pt3", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": -1, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 10, + "aspeed": 4 + } + }, + "9094": { + "name": "Kindling", + "quest": true + }, + "9095": { + "name": "Soaked kindling", + "quest": true, + "weight": 0.5 + }, + "9096": { + "name": "Lunar helm", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": -2, + "dstab": 8, + "dslash": 7, + "dcrush": 10, + "dmagic": 2 + } + }, + "9097": { + "name": "Lunar torso", + "quest": true, + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 10, + "arange": -10, + "dstab": 34, + "dslash": 22, + "dcrush": 40, + "dmagic": 12 + } + }, + "9098": { + "name": "Lunar legs", + "quest": true, + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 7, + "amagic": 7, + "arange": -7, + "dstab": 20, + "dslash": 19, + "dcrush": 23, + "dmagic": 9 + } + }, + "9099": { + "name": "Lunar gloves", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 9, + "amagic": 4, + "arange": -1, + "dstab": 2, + "dslash": 1, + "dcrush": 1, + "dmagic": 2 + } + }, + "9100": { + "name": "Lunar boots", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 10, + "amagic": 2, + "arange": -1, + "dstab": 1, + "dslash": 2, + "dcrush": 2, + "dmagic": 2 + } + }, + "9101": { + "name": "Lunar cape", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "9102": { + "name": "Lunar amulet", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "amagic": 1, + "dmagic": 1 + } + }, + "9103": { + "name": "A special tiara", + "quest": true, + "weight": 0.01 + }, + "9104": { + "name": "Lunar ring", + "quest": true, + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12, + "amagic": 2, + "dmagic": 2 + } + }, + "9106": { + "name": "Astral tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "9139": { + "name": "Blurite bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 28 + } + }, + "9140": { + "name": "Iron bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 46 + } + }, + "9141": { + "name": "Steel bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "9142": { + "name": "Mithril bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 82 + } + }, + "9143": { + "name": "Adamant bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 100 + } + }, + "9144": { + "name": "Runite bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 115 + } + }, + "9145": { + "name": "Silver bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 36 + } + }, + "9174": { + "name": "Bronze crossbow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 18, + "aspeed": 6 + } + }, + "9176": { + "name": "Blurite crossbow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 30, + "aspeed": 6 + } + }, + "9177": { + "name": "Iron crossbow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 42, + "aspeed": 6 + } + }, + "9179": { + "name": "Steel crossbow", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "arange": 54, + "aspeed": 6 + } + }, + "9181": { + "name": "Mith crossbow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 66, + "aspeed": 6 + } + }, + "9183": { + "name": "Adamant crossbow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 78, + "aspeed": 6 + } + }, + "9185": { + "name": "Rune crossbow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 90, + "aspeed": 6 + } + }, + "9187": { + "name": "Jade bolt tips" + }, + "9188": { + "name": "Topaz bolt tips" + }, + "9189": { + "name": "Sapphire bolt tips" + }, + "9190": { + "name": "Emerald bolt tips" + }, + "9191": { + "name": "Ruby bolt tips" + }, + "9192": { + "name": "Diamond bolt tips" + }, + "9193": { + "name": "Dragonstone bolt tips" + }, + "9194": { + "name": "Onyx bolt tips" + }, + "9236": { + "name": "Opal bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 14 + } + }, + "9237": { + "name": "Jade bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 30 + } + }, + "9238": { + "name": "Pearl bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 48 + } + }, + "9239": { + "name": "Topaz bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 66 + } + }, + "9240": { + "name": "Sapphire bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 83 + } + }, + "9241": { + "name": "Emerald bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 85 + } + }, + "9242": { + "name": "Ruby bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 103 + } + }, + "9243": { + "name": "Diamond bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 105 + } + }, + "9244": { + "name": "Dragonstone bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 117 + } + }, + "9245": { + "name": "Onyx bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 120 + } + }, + "9286": { + "name": "Blurite bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 28 + } + }, + "9287": { + "name": "Iron bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 46 + } + }, + "9288": { + "name": "Steel bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "9289": { + "name": "Mithril bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 82 + } + }, + "9290": { + "name": "Adamant bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 100 + } + }, + "9291": { + "name": "Runite bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 115 + } + }, + "9292": { + "name": "Silver bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 36 + } + }, + "9293": { + "name": "Blurite bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 28 + } + }, + "9294": { + "name": "Iron bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 46 + } + }, + "9295": { + "name": "Steel bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "9296": { + "name": "Mithril bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 82 + } + }, + "9297": { + "name": "Adamant bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 100 + } + }, + "9298": { + "name": "Runite bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 115 + } + }, + "9299": { + "name": "Silver bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 36 + } + }, + "9300": { + "name": "Blurite bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 28 + } + }, + "9301": { + "name": "Iron bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 46 + } + }, + "9302": { + "name": "Steel bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 64 + } + }, + "9303": { + "name": "Mithril bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 82 + } + }, + "9304": { + "name": "Adamant bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 100 + } + }, + "9305": { + "name": "Runite bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 115 + } + }, + "9306": { + "name": "Silver bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 36 + } + }, + "9335": { + "name": "Jade bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 30 + } + }, + "9336": { + "name": "Topaz bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 66 + } + }, + "9337": { + "name": "Sapphire bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 83 + } + }, + "9338": { + "name": "Emerald bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 85 + } + }, + "9339": { + "name": "Ruby bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 103 + } + }, + "9340": { + "name": "Diamond bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 105 + } + }, + "9341": { + "name": "Dragonstone bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 117 + } + }, + "9342": { + "name": "Onyx bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 120 + } + }, + "9375": { + "name": "Bronze bolts (unf)" + }, + "9376": { + "name": "Blurite bolts (unf)" + }, + "9377": { + "name": "Iron bolts (unf)" + }, + "9378": { + "name": "Steel bolts (unf)" + }, + "9379": { + "name": "Mithril bolts (unf)" + }, + "9380": { + "name": "Adamant bolts(unf)" + }, + "9381": { + "name": "Runite bolts (unf)" + }, + "9382": { + "name": "Silver bolts (unf)" + }, + "9416": { + "name": "Mith grapple tip", + "weight": 0.001 + }, + "9418": { + "name": "Mith grapple", + "weight": 0.001 + }, + "9419": { + "name": "Mith grapple", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 13 + } + }, + "9420": { + "name": "Bronze limbs", + "weight": 1.0 + }, + "9422": { + "name": "Blurite limbs", + "weight": 1.0 + }, + "9423": { + "name": "Iron limbs", + "weight": 1.0 + }, + "9425": { + "name": "Steel limbs", + "weight": 2.0 + }, + "9427": { + "name": "Mithril limbs", + "weight": 2.0 + }, + "9429": { + "name": "Adamantite limbs", + "weight": 3.0 + }, + "9431": { + "name": "Runite limbs", + "weight": 3.0 + }, + "9433": { + "name": "Bolt pouch", + "weight": 1.0 + }, + "9434": { + "name": "Bolt mould", + "weight": 0.4 + }, + "9436": { + "name": "Sinew", + "weight": 0.002 + }, + "9438": { + "name": "Crossbow string", + "weight": 0.002 + }, + "9440": { + "name": "Wooden stock", + "weight": 3.0 + }, + "9442": { + "name": "Oak stock", + "weight": 3.0 + }, + "9444": { + "name": "Willow stock", + "weight": 3.0 + }, + "9446": { + "name": "Teak stock", + "weight": 3.0 + }, + "9448": { + "name": "Maple stock", + "weight": 3.0 + }, + "9450": { + "name": "Mahogany stock", + "weight": 3.0 + }, + "9452": { + "name": "Yew stock", + "weight": 3.0 + }, + "9454": { + "name": "Bronze crossbow (u)", + "weight": 8.0 + }, + "9456": { + "name": "Blurite crossbow (u)", + "weight": 8.0 + }, + "9457": { + "name": "Iron crossbow (u)", + "weight": 8.0 + }, + "9459": { + "name": "Steel crossbow (u)", + "weight": 8.0 + }, + "9461": { + "name": "Mithril crossbow (u)", + "weight": 8.0 + }, + "9463": { + "name": "Adamant crossbow (u)", + "weight": 8.0 + }, + "9465": { + "name": "Runite crossbow (u)", + "weight": 8.0 + }, + "9467": { + "name": "Blurite bar", + "weight": 1.814 + }, + "9468": { + "name": "Sawdust", + "weight": 0.5 + }, + "9469": { + "name": "Grand seed pod" + }, + "9470": { + "name": "Gnome scarf", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "9472": { + "name": "Gnome goggles", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "9474": { + "name": "Reward token", + "weight": 0.001 + }, + "9475": { + "name": "Mint cake", + "weight": 0.1 + }, + "9477": { + "name": "Aluft aloft box", + "weight": 0.1 + }, + "9478": { + "name": "Half made batta", + "weight": 0.25 + }, + "9479": { + "name": "Unfinished batta", + "weight": 0.25 + }, + "9480": { + "name": "Half made batta", + "weight": 0.25 + }, + "9482": { + "name": "Half made batta", + "weight": 0.25 + }, + "9483": { + "name": "Half made batta", + "weight": 0.25 + }, + "9485": { + "name": "Half made batta", + "weight": 0.25 + }, + "9558": { + "name": "Half made bowl", + "weight": 0.275 + }, + "9559": { + "name": "Half made bowl", + "weight": 0.275 + }, + "9560": { + "name": "Unfinished bowl", + "weight": 0.3 + }, + "9561": { + "name": "Half made bowl", + "weight": 0.275 + }, + "9562": { + "name": "Unfinished bowl", + "weight": 0.3 + }, + "9563": { + "name": "Half made bowl", + "weight": 0.275 + }, + "9564": { + "name": "Unfinished bowl", + "weight": 0.3 + }, + "9566": { + "name": "Mixed blizzard", + "weight": 0.15 + }, + "9567": { + "name": "Mixed sgg", + "weight": 0.15 + }, + "9568": { + "name": "Mixed blast", + "weight": 0.15 + }, + "9569": { + "name": "Mixed punch", + "weight": 0.15 + }, + "9570": { + "name": "Mixed special" + }, + "9571": { + "name": "Mixed saturday", + "weight": 0.15 + }, + "9572": { + "name": "Mixed saturday", + "weight": 0.15 + }, + "9573": { + "name": "Mixed saturday", + "weight": 0.15 + }, + "9574": { + "name": "Mixed dragon", + "weight": 0.15 + }, + "9575": { + "name": "Mixed dragon", + "weight": 0.15 + }, + "9576": { + "name": "Mixed dragon", + "weight": 0.15 + }, + "9577": { + "name": "Half made crunchy", + "weight": 0.35 + }, + "9578": { + "name": "Unfinished crunchy", + "weight": 0.35 + }, + "9579": { + "name": "Half made crunchy", + "weight": 0.35 + }, + "9580": { + "name": "Unfinished crunchy", + "weight": 0.3 + }, + "9581": { + "name": "Half made crunchy", + "weight": 0.35 + }, + "9582": { + "name": "Unfinished crunchy", + "weight": 0.3 + }, + "9583": { + "name": "Half made crunchy", + "weight": 0.35 + }, + "9584": { + "name": "Unfinished crunchy" + }, + "9589": { + "name": "Dossier", + "quest": true, + "weight": 0.003 + }, + "9591": { + "name": "Broken cauldron" + }, + "9592": { + "name": "Magic glue", + "quest": true, + "weight": 2.5 + }, + "9593": { + "name": "Weird gloop", + "quest": true, + "weight": 2.5 + }, + "9594": { + "name": "Ground mud runes" + }, + "9595": { + "name": "Hazelmere's book", + "weight": 0.51 + }, + "9597": { + "name": "A red circle", + "quest": true + }, + "9598": { + "name": "A red triangle", + "quest": true + }, + "9599": { + "name": "A red square", + "quest": true + }, + "9600": { + "name": "A red pentagon", + "quest": true + }, + "9601": { + "name": "An orange circle", + "quest": true + }, + "9602": { + "name": "An orange triangle", + "quest": true + }, + "9603": { + "name": "An orange square", + "quest": true + }, + "9604": { + "name": "Orange pentagon", + "quest": true + }, + "9605": { + "name": "A yellow circle", + "quest": true + }, + "9606": { + "name": "A yellow triangle", + "quest": true + }, + "9607": { + "name": "A yellow square", + "quest": true + }, + "9608": { + "name": "A yellow pentagon", + "quest": true + }, + "9609": { + "name": "A green circle", + "quest": true + }, + "9610": { + "name": "A green triangle", + "quest": true + }, + "9611": { + "name": "A green square", + "quest": true + }, + "9612": { + "name": "A green pentagon", + "quest": true + }, + "9613": { + "name": "A blue circle", + "quest": true + }, + "9614": { + "name": "A blue triangle", + "quest": true + }, + "9615": { + "name": "A blue square", + "quest": true + }, + "9616": { + "name": "A blue pentagon", + "quest": true + }, + "9617": { + "name": "An indigo circle", + "quest": true + }, + "9618": { + "name": "An indigo triangle", + "quest": true + }, + "9619": { + "name": "An indigo square", + "quest": true + }, + "9620": { + "name": "An indigo pentagon", + "quest": true + }, + "9621": { + "name": "A violet circle", + "quest": true + }, + "9622": { + "name": "A violet triangle", + "quest": true + }, + "9623": { + "name": "A violet square", + "quest": true + }, + "9624": { + "name": "A violet pentagon", + "quest": true + }, + "9625": { + "name": "Crystal saw", + "quest": true, + "weight": 1.0 + }, + "9626": { + "name": "Small crystal seed", + "quest": true, + "weight": 0.01 + }, + "9627": { + "name": "A handwritten book", + "quest": true, + "weight": 0.51 + }, + "9629": { + "name": "Tyras helm", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "9632": { + "name": "Daeyalt ore" + }, + "9633": { + "name": "Message", + "quest": true, + "weight": 0.02 + }, + "9634": { + "name": "Vyrewatch top", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "9636": { + "name": "Vyrewatch legs", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "9638": { + "name": "Vyrewatch shoes", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 10, + "dslash": 2, + "dcrush": 2 + } + }, + "9640": { + "name": "Citizen top", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 4, + "dslash": 2, + "dcrush": 2 + } + }, + "9642": { + "name": "Citizen trousers", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dslash": 2, + "dcrush": 2 + } + }, + "9644": { + "name": "Citizen shoes", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 10, + "dslash": 2, + "dcrush": 2 + } + }, + "9646": { + "name": "Castle sketch 1", + "quest": true, + "weight": 0.02 + }, + "9647": { + "name": "Castle sketch 2", + "quest": true, + "weight": 0.02 + }, + "9648": { + "name": "Castle sketch 3", + "quest": true, + "weight": 0.02 + }, + "9649": { + "name": "Message", + "quest": true, + "weight": 0.001 + }, + "9650": { + "name": "Blood tithe pouch", + "quest": true, + "weight": 0.001 + }, + "9651": { + "name": "Large ornate key", + "quest": true, + "weight": 2.0 + }, + "9652": { + "name": "Haemalchemy", + "quest": true, + "weight": 2.0 + }, + "9653": { + "name": "Sealed message", + "quest": true, + "weight": 0.001 + }, + "9654": { + "name": "Door key", + "quest": true, + "weight": 0.055 + }, + "9655": { + "name": "Ladder top", + "quest": true + }, + "9656": { + "name": "Tome of experience (3)", + "quest": true, + "weight": 1.0 + }, + "9657": { + "name": "Tome of experience (2)", + "quest": true, + "weight": 1.0 + }, + "9658": { + "name": "Tome of experience (1)", + "quest": true, + "weight": 1.0 + }, + "9659": { + "name": "Bucket of water", + "weight": 3.0 + }, + "9660": { + "name": "Bucket", + "weight": 1.0 + }, + "9662": { + "name": "Useless key" + }, + "9666": { + "name": "Proselyte harness m", + "weight": 14.514 + }, + "9668": { + "name": "Initiate harness m", + "weight": 14.514 + }, + "9670": { + "name": "Proselyte harness f", + "weight": 14.514 + }, + "9672": { + "name": "Proselyte sallet", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19, + "prayer": 4 + } + }, + "9674": { + "name": "Proselyte hauberk", + "quest": true, + "equipable": true, + "weight": 8.618, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63, + "prayer": 8 + } + }, + "9676": { + "name": "Proselyte cuisse", + "quest": true, + "equipable": true, + "weight": 7.711, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31, + "prayer": 6 + } + }, + "9678": { + "name": "Proselyte tasset", + "quest": true, + "equipable": true, + "weight": 8.164, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31, + "prayer": 6 + } + }, + "9680": { + "name": "Sea slug glue", + "quest": true, + "weight": 0.01 + }, + "9681": { + "name": "Commorb v2", + "quest": true, + "weight": 0.001 + }, + "9682": { + "name": "Door transcription", + "quest": true, + "weight": 0.02 + }, + "9683": { + "name": "Dead sea slug", + "quest": true, + "weight": 0.01 + }, + "9684": { + "name": "Page 1", + "quest": true, + "weight": 0.01 + }, + "9685": { + "name": "Page 2", + "quest": true, + "weight": 0.01 + }, + "9686": { + "name": "Page 3", + "quest": true, + "weight": 0.01 + }, + "9687": { + "name": "Fragment 1", + "quest": true, + "weight": 0.01 + }, + "9688": { + "name": "Fragment 2", + "quest": true, + "weight": 0.01 + }, + "9689": { + "name": "Fragment 3", + "quest": true, + "weight": 0.01 + }, + "9690": { + "name": "Blank water rune", + "quest": true, + "weight": 0.01 + }, + "9691": { + "name": "Water rune", + "quest": true, + "weight": 0.01 + }, + "9692": { + "name": "Blank air rune", + "quest": true, + "weight": 0.01 + }, + "9693": { + "name": "Air rune", + "quest": true, + "weight": 0.01 + }, + "9694": { + "name": "Blank earth rune", + "quest": true, + "weight": 0.01 + }, + "9695": { + "name": "Earth rune", + "quest": true, + "weight": 0.01 + }, + "9696": { + "name": "Blank mind rune", + "quest": true, + "weight": 0.01 + }, + "9697": { + "name": "Mind rune", + "quest": true, + "weight": 0.01 + }, + "9698": { + "name": "Blank fire rune", + "quest": true, + "weight": 0.01 + }, + "9699": { + "name": "Fire rune", + "quest": true, + "weight": 0.01 + }, + "9703": { + "name": "Training sword", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 4, + "aslash": 3, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 5, + "aspeed": 4 + } + }, + "9704": { + "name": "Training shield", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": 1, + "drange": 4 + } + }, + "9705": { + "name": "Training bow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 8, + "aspeed": 4 + } + }, + "9706": { + "name": "Training arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 7 + } + }, + "9715": { + "name": "Slashed book", + "quest": true, + "weight": 0.113 + }, + "9717": { + "name": "Beaten book", + "quest": true, + "weight": 0.1 + }, + "9718": { + "name": "Crane schematic", + "quest": true, + "weight": 0.1 + }, + "9719": { + "name": "Lever schematic", + "quest": true, + "weight": 0.1 + }, + "9720": { + "name": "Crane claw", + "quest": true, + "weight": 1.814 + }, + "9721": { + "name": "Scroll", + "quest": true, + "weight": 0.02 + }, + "9722": { + "name": "Key", + "quest": true, + "weight": 0.01 + }, + "9723": { + "name": "Pipe", + "quest": true, + "weight": 3.175 + }, + "9724": { + "name": "Large cog", + "quest": true, + "weight": 2.721 + }, + "9725": { + "name": "Medium cog", + "quest": true, + "weight": 1.814 + }, + "9726": { + "name": "Small cog", + "quest": true, + "weight": 0.907 + }, + "9727": { + "name": "Primed bar", + "quest": true, + "weight": 1.814 + }, + "9728": { + "name": "Primed mind bar", + "quest": true, + "weight": 1.814 + }, + "9729": { + "name": "Elemental helmet", + "quest": true, + "equipable": true, + "weight": 0.113, + "equipment": { + "slot": 0, + "dmagic": 4 + } + }, + "9731": { + "name": "Mind shield", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 5, + "dmagic": 9 + } + }, + "9733": { + "name": "Mind helmet", + "quest": true, + "equipable": true, + "weight": 0.113, + "equipment": { + "slot": 0, + "dmagic": 6 + } + }, + "9735": { + "name": "Desert goat horn", + "weight": 0.453 + }, + "9736": { + "name": "Goat horn dust", + "weight": 0.453 + }, + "9739": { + "name": "Combat potion(4)", + "weight": 0.035 + }, + "9741": { + "name": "Combat potion(3)", + "weight": 0.03 + }, + "9743": { + "name": "Combat potion(2)", + "weight": 0.025 + }, + "9745": { + "name": "Combat potion(1)", + "weight": 0.02 + }, + "9747": { + "name": "Attack cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9748": { + "name": "Attack cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9749": { + "name": "Attack hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9750": { + "name": "Strength cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9751": { + "name": "Strength cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9752": { + "name": "Strength hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9753": { + "name": "Defence cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9754": { + "name": "Defence cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9755": { + "name": "Defence hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9756": { + "name": "Ranging cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9757": { + "name": "Ranging cape(t)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9758": { + "name": "Ranging hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9759": { + "name": "Prayer cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9760": { + "name": "Prayer cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9761": { + "name": "Prayer hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9762": { + "name": "Magic cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9763": { + "name": "Magic cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9764": { + "name": "Magic hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9765": { + "name": "Runecraft cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9766": { + "name": "Runecraft cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9767": { + "name": "Runecrafting hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9768": { + "name": "Hitpoints cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9769": { + "name": "Hitpoints cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9770": { + "name": "Hitpoints hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9771": { + "name": "Agility cape", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9772": { + "name": "Agility cape(t)", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9773": { + "name": "Agility hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9774": { + "name": "Herblore cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9775": { + "name": "Herblore cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9776": { + "name": "Herblore hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9777": { + "name": "Thieving cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9778": { + "name": "Thieving cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9779": { + "name": "Thieving hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9780": { + "name": "Crafting cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9781": { + "name": "Crafting cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9782": { + "name": "Crafting hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9783": { + "name": "Fletching cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9784": { + "name": "Fletching cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9785": { + "name": "Fletching hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9786": { + "name": "Slayer cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9787": { + "name": "Slayer cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9788": { + "name": "Slayer hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9789": { + "name": "Construct. cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9790": { + "name": "Construct. cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9791": { + "name": "Construct. hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "9792": { + "name": "Mining cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9793": { + "name": "Mining cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9794": { + "name": "Mining hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9795": { + "name": "Smithing cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9796": { + "name": "Smithing cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9797": { + "name": "Smithing hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9798": { + "name": "Fishing cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9799": { + "name": "Fishing cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9800": { + "name": "Fishing hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9801": { + "name": "Cooking cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9802": { + "name": "Cooking cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9803": { + "name": "Cooking hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9804": { + "name": "Firemaking cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9805": { + "name": "Firemaking cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9806": { + "name": "Firemaking hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9807": { + "name": "Woodcutting cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9808": { + "name": "Woodcut. cape(t)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9809": { + "name": "Woodcutting hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9810": { + "name": "Farming cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9811": { + "name": "Farming cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9812": { + "name": "Farming hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9813": { + "name": "Quest point cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9814": { + "name": "Quest point hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9843": { + "name": "Oak cape rack", + "weight": 1.0 + }, + "9844": { + "name": "Teak cape rack", + "weight": 1.0 + }, + "9845": { + "name": "Mahogany cape rack", + "weight": 1.0 + }, + "9846": { + "name": "Gilded cape rack", + "weight": 1.0 + }, + "9847": { + "name": "Marble cape rack", + "weight": 1.0 + }, + "9848": { + "name": "Magic cape rack", + "weight": 1.0 + }, + "9849": { + "name": "Oak toy box", + "weight": 1.0 + }, + "9850": { + "name": "Teak toy box", + "weight": 1.0 + }, + "9851": { + "name": "Mahogany toy box", + "weight": 1.0 + }, + "9852": { + "name": "Oak magic wardrobe", + "weight": 1.0 + }, + "9853": { + "name": "Carved oak magic wardrobe", + "weight": 1.0 + }, + "9854": { + "name": "Teak magic wardrobe", + "weight": 1.0 + }, + "9855": { + "name": "Carved teak magic wardrobe", + "weight": 1.0 + }, + "9856": { + "name": "Mahogany magic wardrobe", + "weight": 1.0 + }, + "9857": { + "name": "Gilded magic wardrobe", + "weight": 1.0 + }, + "9858": { + "name": "Marble magic wardrobe", + "weight": 1.0 + }, + "9859": { + "name": "Oak armour case", + "weight": 1.0 + }, + "9860": { + "name": "Teak armour case", + "weight": 1.0 + }, + "9861": { + "name": "Mahogany armour case", + "weight": 1.0 + }, + "9862": { + "name": "Oak treasure chest", + "weight": 1.0 + }, + "9863": { + "name": "Teak treasure chest", + "weight": 1.0 + }, + "9864": { + "name": "M. treasure chest", + "weight": 1.0 + }, + "9865": { + "name": "Oak fancy dress box", + "weight": 1.0 + }, + "9866": { + "name": "Teak fancy dress box", + "weight": 1.0 + }, + "9867": { + "name": "Mahogany fancy dress box", + "weight": 1.0 + }, + "9901": { + "name": "Goutweedy lump", + "quest": true, + "weight": 0.1 + }, + "9902": { + "name": "Hardy gout tubers", + "quest": true, + "weight": 0.1 + }, + "9903": { + "name": "Farming manual", + "quest": true, + "weight": 0.5 + }, + "9904": { + "name": "Sailing book", + "quest": true, + "weight": 0.001 + }, + "9906": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9907": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9908": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9909": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9910": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9911": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9912": { + "name": "Ghost buster 500", + "equipable": true, + "weight": 0.003 + }, + "9913": { + "name": "White destabiliser" + }, + "9914": { + "name": "Red destabiliser" + }, + "9915": { + "name": "Blue destabiliser" + }, + "9916": { + "name": "Green destabiliser" + }, + "9917": { + "name": "Yellow destabiliser" + }, + "9918": { + "name": "Black destabiliser" + }, + "9919": { + "name": "Evil root", + "weight": 0.003 + }, + "9920": { + "name": "Jack lantern mask", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 0 + } + }, + "9921": { + "name": "Skeleton boots", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 10 + } + }, + "9922": { + "name": "Skeleton gloves", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 9 + } + }, + "9923": { + "name": "Skeleton leggings", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 7 + } + }, + "9924": { + "name": "Skeleton shirt", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 4 + } + }, + "9925": { + "name": "Skeleton mask", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0 + } + }, + "9932": { + "name": "Auguste's sapling", + "quest": true, + "weight": 0.907 + }, + "9933": { + "name": "Balloon structure", + "quest": true, + "weight": 0.001 + }, + "9934": { + "name": "Origami balloon", + "quest": true, + "weight": 0.001 + }, + "9935": { + "name": "Yellow balloon", + "quest": true, + "weight": 0.001 + }, + "9936": { + "name": "Blue balloon", + "quest": true, + "weight": 0.001 + }, + "9937": { + "name": "Red balloon", + "quest": true, + "weight": 0.001 + }, + "9938": { + "name": "Orange balloon", + "quest": true, + "weight": 0.001 + }, + "9939": { + "name": "Green balloon", + "quest": true, + "weight": 0.001 + }, + "9940": { + "name": "Purple balloon", + "quest": true, + "weight": 0.001 + }, + "9941": { + "name": "Pink balloon", + "quest": true, + "weight": 0.001 + }, + "9942": { + "name": "Black balloon", + "quest": true, + "weight": 0.001 + }, + "9943": { + "name": "Sandbag", + "quest": true, + "weight": 1.5 + }, + "9944": { + "name": "Bomber jacket", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "9945": { + "name": "Bomber cap", + "quest": true, + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 0 + } + }, + "9946": { + "name": "Cap and goggles", + "equipable": true, + "weight": 0.001, + "equipment": { + "slot": 0 + } + }, + "9947": { + "name": "Old red disk", + "quest": true, + "weight": 0.002 + }, + "9948": { + "name": "Hunter cape", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "9949": { + "name": "Hunter cape(t)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "9950": { + "name": "Hunter hood", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "9978": { + "name": "Raw bird meat", + "weight": 0.15 + }, + "9980": { + "name": "Roast bird meat", + "weight": 0.15 + }, + "9982": { + "name": "Burnt bird meat" + }, + "9984": { + "name": "Skewered bird meat", + "weight": 1.65 + }, + "9986": { + "name": "Raw beast meat", + "weight": 2.0 + }, + "9988": { + "name": "Roast beast meat", + "weight": 2.0 + }, + "9990": { + "name": "Burnt beast meat" + }, + "9992": { + "name": "Skewered beast", + "weight": 3.5 + }, + "9994": { + "name": "Spicy tomato", + "weight": 0.2 + }, + "9996": { + "name": "Spicy minced meat", + "weight": 0.5 + }, + "9998": { + "name": "Hunter potion(4)", + "weight": 0.035 + }, + "10000": { + "name": "Hunter potion(3)", + "weight": 0.03 + }, + "10002": { + "name": "Hunter potion(2)", + "weight": 0.025 + }, + "10004": { + "name": "Hunter potion(1)", + "weight": 0.02 + }, + "10006": { + "name": "Bird snare", + "weight": 0.453 + }, + "10008": { + "name": "Box trap", + "weight": 0.226 + }, + "10010": { + "name": "Butterfly net", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "10012": { + "name": "Butterfly jar" + }, + "10014": { + "name": "Black warlock", + "weight": 0.02 + }, + "10016": { + "name": "Snowy knight", + "weight": 0.02 + }, + "10018": { + "name": "Sapphire glacialis", + "weight": 0.02 + }, + "10020": { + "name": "Ruby harvest", + "weight": 0.02 + }, + "10023": { + "name": "Falconer's glove", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "aspeed": 4 + } + }, + "10025": { + "name": "Magic box", + "weight": 1.0 + }, + "10027": { + "name": "Imp-in-a-box(2)", + "weight": 1.0 + }, + "10028": { + "name": "Imp-in-a-box(1)", + "weight": 1.0 + }, + "10029": { + "name": "Teasing stick", + "weight": 1.0 + }, + "10031": { + "name": "Rabbit snare", + "quest": true, + "weight": 0.02 + }, + "10033": { + "name": "Chinchompa", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 45, + "aspeed": 4 + } + }, + "10034": { + "name": "Red chinchompa", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 70, + "rstr": 15, + "aspeed": 4 + } + }, + "10035": { + "name": "Kyatt legs", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10037": { + "name": "Kyatt top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10039": { + "name": "Kyatt hat", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 0, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "drange": 4 + } + }, + "10041": { + "name": "Larupia legs", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10043": { + "name": "Larupia top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10045": { + "name": "Larupia hat", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 0, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "drange": 1 + } + }, + "10047": { + "name": "Graahk legs", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10049": { + "name": "Graahk top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10051": { + "name": "Graahk headdress", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 0, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "drange": 4 + } + }, + "10053": { + "name": "Wood camo top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10055": { + "name": "Wood camo legs", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10057": { + "name": "Jungle camo top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10059": { + "name": "Jungle camo legs", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10061": { + "name": "Desert camo top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10063": { + "name": "Desert camo legs", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10065": { + "name": "Polar camo top", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 4, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "drange": 12 + } + }, + "10067": { + "name": "Polar camo legs", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 7, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "drange": 10 + } + }, + "10069": { + "name": "Spotted cape", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "10071": { + "name": "Spottier cape", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "10073": { + "name": "Spotted cape", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "10074": { + "name": "Spottier cape", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "10075": { + "name": "Gloves of silence", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "10077": { + "name": "Spiky vambraces", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "arange": 4, + "dstab": 2, + "dslash": 2, + "dcrush": 1, + "str": 2 + } + }, + "10079": { + "name": "Green spiky vambs", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 8, + "dstab": 3, + "dslash": 2, + "dcrush": 4, + "dmagic": 2, + "str": 2 + } + }, + "10081": { + "name": "Blue spiky vambs", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 9, + "dstab": 4, + "dslash": 3, + "dcrush": 5, + "dmagic": 4, + "str": 2 + } + }, + "10083": { + "name": "Red spiky vambs", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 10, + "dstab": 5, + "dslash": 4, + "dcrush": 6, + "dmagic": 6, + "str": 2 + } + }, + "10085": { + "name": "Black spiky vambs", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "str": 2 + } + }, + "10087": { + "name": "Stripy feather" + }, + "10088": { + "name": "Red feather" + }, + "10089": { + "name": "Blue feather" + }, + "10090": { + "name": "Yellow feather" + }, + "10091": { + "name": "Orange feather" + }, + "10092": { + "name": "Ferret" + }, + "10093": { + "name": "Tatty larupia fur", + "weight": 2.0 + }, + "10095": { + "name": "Larupia fur", + "weight": 2.0 + }, + "10097": { + "name": "Tatty graahk fur", + "weight": 2.0 + }, + "10099": { + "name": "Graahk fur", + "weight": 2.0 + }, + "10101": { + "name": "Tatty kyatt fur", + "weight": 2.0 + }, + "10103": { + "name": "Kyatt fur", + "weight": 2.0 + }, + "10105": { + "name": "Kebbit spike", + "weight": 0.02 + }, + "10107": { + "name": "Long kebbit spike", + "weight": 0.04 + }, + "10109": { + "name": "Kebbit teeth", + "weight": 0.02 + }, + "10111": { + "name": "Kebbit teeth dust", + "weight": 0.02 + }, + "10113": { + "name": "Kebbit claws", + "weight": 0.02 + }, + "10115": { + "name": "Dark kebbit fur", + "weight": 0.453 + }, + "10117": { + "name": "Polar kebbit fur", + "weight": 0.453 + }, + "10119": { + "name": "Feldip weasel fur", + "weight": 0.453 + }, + "10121": { + "name": "Common kebbit fur", + "weight": 0.453 + }, + "10123": { + "name": "Desert devil fur", + "weight": 0.453 + }, + "10125": { + "name": "Spotted kebbit fur", + "weight": 0.453 + }, + "10127": { + "name": "Dashing kebbit fur", + "weight": 0.453 + }, + "10129": { + "name": "Barb-tail harpoon", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "astab": 9, + "aslash": 4, + "acrush": -4, + "str": 6, + "aspeed": 4 + } + }, + "10132": { + "name": "Strung rabbit foot", + "equipable": true, + "weight": 0.03, + "equipment": { + "slot": 2 + } + }, + "10134": { + "name": "Rabbit foot", + "weight": 0.03 + }, + "10136": { + "name": "Rainbow fish", + "weight": 0.4 + }, + "10138": { + "name": "Raw rainbow fish", + "weight": 0.45 + }, + "10140": { + "name": "Burnt rainbow fish" + }, + "10142": { + "name": "Guam tar", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 16 + } + }, + "10143": { + "name": "Marrentill tar" + }, + "10144": { + "name": "Tarromin tar", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "10145": { + "name": "Harralander tar", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "10146": { + "name": "Orange salamander", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aslash": 19, + "arange": 29, + "str": 31 + } + }, + "10147": { + "name": "Red salamander", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aslash": 37, + "arange": 47, + "str": 49 + } + }, + "10148": { + "name": "Black salamander", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aslash": 59, + "arange": 69, + "str": 71 + } + }, + "10149": { + "name": "Swamp lizard", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aslash": 10, + "arange": 20, + "str": 22 + } + }, + "10150": { + "name": "Noose wand", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "10156": { + "name": "Hunters' crossbow", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 3, + "arange": 55, + "aspeed": 4 + } + }, + "10158": { + "name": "Kebbit bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 28 + } + }, + "10159": { + "name": "Long kebbit bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 38 + } + }, + "10167": { + "name": "Eagle feather", + "quest": true + }, + "10171": { + "name": "Eagle cape", + "quest": true, + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 1 + } + }, + "10172": { + "name": "Fake beak", + "quest": true, + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 0 + } + }, + "10173": { + "name": "Bird book", + "quest": true, + "weight": 0.01 + }, + "10174": { + "name": "Metal feather", + "quest": true, + "weight": 0.001 + }, + "10175": { + "name": "Golden feather", + "quest": true, + "weight": 0.001 + }, + "10176": { + "name": "Silver feather", + "quest": true, + "weight": 0.001 + }, + "10177": { + "name": "Bronze feather", + "quest": true, + "weight": 0.001 + }, + "10178": { + "name": "Odd bird seed", + "quest": true + }, + "10179": { + "name": "Feathered journal", + "quest": true, + "weight": 0.01 + }, + "10180": { + "name": "Clue scroll (easy)" + }, + "10182": { + "name": "Clue scroll (easy)" + }, + "10184": { + "name": "Clue scroll (easy)" + }, + "10186": { + "name": "Clue scroll (easy)" + }, + "10188": { + "name": "Clue scroll (easy)" + }, + "10190": { + "name": "Clue scroll (easy)" + }, + "10192": { + "name": "Clue scroll (easy)" + }, + "10194": { + "name": "Clue scroll (easy)" + }, + "10196": { + "name": "Clue scroll (easy)" + }, + "10198": { + "name": "Clue scroll (easy)" + }, + "10200": { + "name": "Clue scroll (easy)" + }, + "10202": { + "name": "Clue scroll (easy)" + }, + "10204": { + "name": "Clue scroll (easy)" + }, + "10206": { + "name": "Clue scroll (easy)" + }, + "10208": { + "name": "Clue scroll (easy)" + }, + "10210": { + "name": "Clue scroll (easy)" + }, + "10212": { + "name": "Clue scroll (easy)" + }, + "10214": { + "name": "Clue scroll (easy)" + }, + "10216": { + "name": "Clue scroll (easy)" + }, + "10218": { + "name": "Clue scroll (easy)" + }, + "10220": { + "name": "Clue scroll (easy)" + }, + "10222": { + "name": "Clue scroll (easy)" + }, + "10224": { + "name": "Clue scroll (easy)" + }, + "10226": { + "name": "Clue scroll (easy)" + }, + "10228": { + "name": "Clue scroll (easy)" + }, + "10230": { + "name": "Clue scroll (easy)" + }, + "10232": { + "name": "Clue scroll (easy)" + }, + "10234": { + "name": "Clue scroll (hard)" + }, + "10236": { + "name": "Clue scroll (hard)" + }, + "10238": { + "name": "Clue scroll (hard)" + }, + "10240": { + "name": "Clue scroll (hard)" + }, + "10242": { + "name": "Clue scroll (hard)" + }, + "10244": { + "name": "Clue scroll (hard)" + }, + "10246": { + "name": "Clue scroll (hard)" + }, + "10248": { + "name": "Clue scroll (hard)" + }, + "10250": { + "name": "Clue scroll (hard)" + }, + "10252": { + "name": "Clue scroll (hard)" + }, + "10254": { + "name": "Clue scroll (medium)" + }, + "10256": { + "name": "Clue scroll (medium)" + }, + "10258": { + "name": "Clue scroll (medium)" + }, + "10260": { + "name": "Clue scroll (medium)" + }, + "10262": { + "name": "Clue scroll (medium)" + }, + "10264": { + "name": "Clue scroll (medium)" + }, + "10266": { + "name": "Clue scroll (medium)" + }, + "10268": { + "name": "Clue scroll (medium)" + }, + "10270": { + "name": "Clue scroll (medium)" + }, + "10272": { + "name": "Clue scroll (medium)" + }, + "10274": { + "name": "Clue scroll (medium)" + }, + "10276": { + "name": "Clue scroll (medium)" + }, + "10278": { + "name": "Clue scroll (medium)" + }, + "10280": { + "name": "Willow comp bow", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "arange": 22, + "aspeed": 5 + } + }, + "10282": { + "name": "Yew comp bow", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "arange": 49, + "aspeed": 5 + } + }, + "10284": { + "name": "Magic comp bow", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "arange": 71, + "aspeed": 5 + } + }, + "10286": { + "name": "Rune helm (h1)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "10288": { + "name": "Rune helm (h2)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "10290": { + "name": "Rune helm (h3)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "10292": { + "name": "Rune helm (h4)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "10294": { + "name": "Rune helm (h5)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "10296": { + "name": "Adamant helm (h1)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "10298": { + "name": "Adamant helm (h2)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "10300": { + "name": "Adamant helm (h3)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "10302": { + "name": "Adamant helm (h4)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "10304": { + "name": "Adamant helm (h5)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "10306": { + "name": "Black helm (h1)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "10308": { + "name": "Black helm (h2)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "10310": { + "name": "Black helm (h3)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "10312": { + "name": "Black helm (h4)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "10314": { + "name": "Black helm (h5)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 12, + "dslash": 13, + "dcrush": 10, + "dmagic": -1, + "drange": 12 + } + }, + "10316": { + "name": "Bob's red shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10318": { + "name": "Bob's blue shirt", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 4 + } + }, + "10320": { + "name": "Bob's green shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10322": { + "name": "Bob's black shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10324": { + "name": "Bob's purple shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10326": { + "name": "Purple firelighter" + }, + "10327": { + "name": "White firelighter" + }, + "10328": { + "name": "White logs", + "weight": 0.003 + }, + "10329": { + "name": "Purple logs", + "weight": 0.003 + }, + "10330": { + "name": "3rd age range top", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 60, + "drange": 55 + } + }, + "10332": { + "name": "3rd age range legs", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 30, + "drange": 31 + } + }, + "10334": { + "name": "3rd age range coif", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "amagic": -2, + "arange": 9, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 5, + "drange": 8 + } + }, + "10336": { + "name": "3rd age vambraces", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 9 + } + }, + "10338": { + "name": "3rd age robe top", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 4, + "amagic": 24, + "dmagic": 24 + } + }, + "10340": { + "name": "3rd age robe", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 19, + "dmagic": 19 + } + }, + "10342": { + "name": "3rd age mage hat", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 8, + "dmagic": 8 + } + }, + "10344": { + "name": "3rd age amulet", + "equipable": true, + "weight": 0.003, + "equipment": { + "slot": 2, + "amagic": 15, + "dmagic": 10 + } + }, + "10346": { + "name": "3rd age platelegs", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 7, + "amagic": -25, + "arange": -2, + "dstab": 78, + "dslash": 76, + "dcrush": 83, + "dmagic": -5, + "drange": 75 + } + }, + "10348": { + "name": "3rd age platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -20, + "dstab": 96, + "dslash": 108, + "dcrush": 113, + "dmagic": -4, + "drange": 97 + } + }, + "10350": { + "name": "3rd age full helmet", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -2, + "dstab": 47, + "dslash": 49, + "dcrush": 43, + "dmagic": -3, + "drange": 48 + } + }, + "10352": { + "name": "3rd age kiteshield", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -4, + "dstab": 63, + "dslash": 65, + "dcrush": 61, + "dmagic": -3, + "drange": 63 + } + }, + "10354": { + "name": "Amulet of glory (t4)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "10356": { + "name": "Amulet of glory (t3)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "10358": { + "name": "Amulet of glory (t2)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "10360": { + "name": "Amulet of glory (t1)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "10362": { + "name": "Amulet of glory (t)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "10364": { + "name": "Strength amulet (t)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "str": 10 + } + }, + "10366": { + "name": "Amulet of magic (t)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "amagic": 10 + } + }, + "10368": { + "name": "Zamorak bracers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "prayer": 1 + } + }, + "10370": { + "name": "Zamorak d'hide", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55, + "prayer": 1 + } + }, + "10372": { + "name": "Zamorak chaps", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31, + "prayer": 1 + } + }, + "10374": { + "name": "Zamorak coif", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 4, + "drange": 8, + "prayer": 1 + } + }, + "10376": { + "name": "Guthix bracers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "prayer": 1 + } + }, + "10378": { + "name": "Guthix d'hide", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55, + "prayer": 1 + } + }, + "10380": { + "name": "Guthix chaps", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31, + "prayer": 1 + } + }, + "10382": { + "name": "Guthix coif", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 4, + "drange": 8, + "prayer": 1 + } + }, + "10384": { + "name": "Saradomin bracers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "prayer": 1 + } + }, + "10386": { + "name": "Saradomin d'hide", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55, + "prayer": 1 + } + }, + "10388": { + "name": "Saradomin chaps", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31, + "prayer": 1 + } + }, + "10390": { + "name": "Saradomin coif", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 4, + "drange": 8, + "prayer": 1 + } + }, + "10392": { + "name": "A powdered wig", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "10394": { + "name": "Flared trousers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10396": { + "name": "Pantaloons", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10398": { + "name": "Sleeping cap", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "10400": { + "name": "Black elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10402": { + "name": "Black elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10404": { + "name": "Red elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10406": { + "name": "Red elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10408": { + "name": "Blue elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10410": { + "name": "Blue elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10412": { + "name": "Green elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10414": { + "name": "Green elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10416": { + "name": "Purple elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10418": { + "name": "Purple elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10420": { + "name": "White elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10422": { + "name": "White elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10424": { + "name": "Red elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10426": { + "name": "Red elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10428": { + "name": "Blue elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10430": { + "name": "Blue elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10432": { + "name": "Green elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10434": { + "name": "Green elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10436": { + "name": "Purple elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "10438": { + "name": "Purple elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10440": { + "name": "Saradomin crozier", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "10442": { + "name": "Guthix crozier", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "10444": { + "name": "Zamorak crozier", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "10446": { + "name": "Saradomin cloak", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 3 + } + }, + "10448": { + "name": "Guthix cloak", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 3 + } + }, + "10450": { + "name": "Zamorak cloak", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 3 + } + }, + "10452": { + "name": "Saradomin mitre", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "10454": { + "name": "Guthix mitre", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "10456": { + "name": "Zamorak mitre", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "10458": { + "name": "Saradomin robe top", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 4, + "amagic": 4, + "dmagic": 4, + "prayer": 6 + } + }, + "10460": { + "name": "Zamorak robe top", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 4, + "amagic": 4, + "dmagic": 4, + "prayer": 6 + } + }, + "10462": { + "name": "Guthix robe top", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 4, + "amagic": 4, + "dmagic": 4, + "prayer": 6 + } + }, + "10464": { + "name": "Saradomin robe legs", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "10466": { + "name": "Guthix robe legs", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "10468": { + "name": "Zamorak robe legs", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "10470": { + "name": "Saradomin stole", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "amagic": 2, + "dmagic": 2, + "prayer": 10 + } + }, + "10472": { + "name": "Guthix stole", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "amagic": 2, + "dmagic": 2, + "prayer": 10 + } + }, + "10474": { + "name": "Zamorak stole", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "amagic": 2, + "dmagic": 2, + "prayer": 10 + } + }, + "10476": { + "name": "Purple sweets" + }, + "10487": { + "name": "Undead chicken", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "10488": { + "name": "Selected iron", + "quest": true + }, + "10489": { + "name": "Bar magnet", + "quest": true, + "weight": 0.25 + }, + "10490": { + "name": "Undead twigs", + "quest": true, + "weight": 0.453 + }, + "10491": { + "name": "Blessed axe", + "quest": true, + "equipable": true, + "weight": 1.162, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 12, + "acrush": 10, + "dslash": 1, + "str": 13, + "prayer": 2, + "aspeed": 5 + } + }, + "10492": { + "name": "Research notes", + "quest": true, + "weight": 0.2 + }, + "10493": { + "name": "Translated notes", + "quest": true, + "weight": 0.2 + }, + "10494": { + "name": "A pattern", + "quest": true, + "weight": 0.05 + }, + "10495": { + "name": "A container", + "quest": true, + "weight": 0.25 + }, + "10496": { + "name": "Polished buttons", + "weight": 0.001 + }, + "10498": { + "name": "Ava's attractor", + "quest": true, + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 1, + "arange": 2, + "dmagic": 2 + } + }, + "10499": { + "name": "Ava's accumulator", + "quest": true, + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 1, + "arange": 4, + "dslash": 1, + "dmagic": 4 + } + }, + "10500": { + "name": "Crone-made amulet", + "quest": true, + "weight": 0.01 + }, + "10501": { + "name": "Snowball", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "10506": { + "name": "Gublinch shards", + "weight": 9.071 + }, + "10507": { + "name": "Reindeer hat", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "10508": { + "name": "Wintumber tree", + "weight": 10.0 + }, + "10512": { + "name": "Scroll", + "weight": 0.005 + }, + "10513": { + "name": "Crackers", + "weight": 0.001 + }, + "10514": { + "name": "Tofu", + "weight": 0.001 + }, + "10515": { + "name": "Worms", + "weight": 0.001 + }, + "10516": { + "name": "Attacker horn" + }, + "10517": { + "name": "Attacker horn" + }, + "10518": { + "name": "Attacker horn" + }, + "10519": { + "name": "Attacker horn" + }, + "10520": { + "name": "Attacker horn" + }, + "10521": { + "name": "Collection bag" + }, + "10522": { + "name": "Collection bag" + }, + "10523": { + "name": "Collection bag" + }, + "10524": { + "name": "Collection bag" + }, + "10525": { + "name": "Collection bag" + }, + "10526": { + "name": "Healer horn" + }, + "10527": { + "name": "Healer horn" + }, + "10528": { + "name": "Healer horn" + }, + "10529": { + "name": "Healer horn" + }, + "10530": { + "name": "Healer horn" + }, + "10531": { + "name": "Green egg", + "weight": 0.02 + }, + "10532": { + "name": "Red egg", + "weight": 0.02 + }, + "10533": { + "name": "Blue egg", + "weight": 0.02 + }, + "10534": { + "name": "Yellow egg", + "weight": 0.02 + }, + "10535": { + "name": "Poisoned egg", + "weight": 0.02 + }, + "10536": { + "name": "Spiked/pois. egg", + "weight": 0.02 + }, + "10537": { + "name": "Omega egg", + "weight": 0.02 + }, + "10538": { + "name": "Defender horn", + "weight": 0.001 + }, + "10539": { + "name": "Poisoned tofu" + }, + "10540": { + "name": "Poisoned worms" + }, + "10541": { + "name": "Poisoned meat" + }, + "10542": { + "name": "Healing vial(4)", + "weight": 0.001 + }, + "10543": { + "name": "Healing vial(3)", + "weight": 0.001 + }, + "10544": { + "name": "Healing vial(2)", + "weight": 0.001 + }, + "10545": { + "name": "Healing vial(1)", + "weight": 0.001 + }, + "10546": { + "name": "Healing vial", + "weight": 0.001 + }, + "10547": { + "name": "Healer hat", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": 6, + "arange": -5, + "dstab": 6, + "dslash": 8, + "dcrush": 10, + "dmagic": 7 + } + }, + "10548": { + "name": "Fighter hat", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "astab": 5, + "aslash": 5, + "acrush": 5, + "amagic": -7, + "arange": -7, + "dstab": 27, + "dslash": 29, + "dcrush": 26, + "dmagic": -3, + "drange": 28 + } + }, + "10549": { + "name": "Runner hat", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 1, + "drange": 30 + } + }, + "10550": { + "name": "Ranger hat", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": -5, + "arange": 6, + "dstab": 7, + "dslash": 10, + "dcrush": 11, + "dmagic": 5, + "drange": 8 + } + }, + "10551": { + "name": "Fighter torso", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 4, + "amagic": -40, + "dstab": 62, + "dslash": 85, + "dcrush": 62, + "dmagic": -10, + "drange": 67, + "str": 4 + } + }, + "10552": { + "name": "Runner boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "amagic": 1, + "arange": 1, + "dstab": 8, + "dslash": 8, + "dcrush": 8 + } + }, + "10553": { + "name": "Penance gloves", + "equipable": true, + "equipment": { + "slot": 9, + "dslash": 3, + "dcrush": 4, + "drange": 2 + } + }, + "10554": { + "name": "Penance gloves", + "equipable": true, + "equipment": { + "slot": 9, + "dslash": 3, + "dcrush": 4, + "drange": 2 + } + }, + "10555": { + "name": "Penance skirt", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 15, + "dstab": 26, + "dslash": 21, + "dcrush": 28, + "dmagic": 19, + "drange": 26 + } + }, + "10556": { + "name": "Attacker icon", + "equipable": true + }, + "10557": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "10558": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "10559": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "10560": { + "name": "Collector horn", + "weight": 0.001 + }, + "10561": { + "name": "Spikes", + "weight": 0.001 + }, + "10562": { + "name": "Queen help book", + "weight": 0.02 + }, + "10564": { + "name": "Granite body", + "equipable": true, + "weight": 22.679, + "equipment": { + "slot": 4, + "amagic": -22, + "arange": -5, + "dstab": 87, + "dslash": 84, + "dcrush": 79, + "dmagic": -6, + "drange": 97 + } + }, + "10567": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "10581": { + "name": "Keris", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 20, + "acrush": -10, + "amagic": 2, + "dmagic": 2, + "str": 30, + "prayer": 2, + "aspeed": 4 + } + }, + "10582": { + "name": "Keris(p)", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 20, + "acrush": -10, + "amagic": 2, + "dmagic": 2, + "str": 30, + "prayer": 2, + "aspeed": 4 + } + }, + "10583": { + "name": "Keris(p+)", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 20, + "acrush": -10, + "amagic": 2, + "dmagic": 2, + "str": 30, + "prayer": 2, + "aspeed": 4 + } + }, + "10584": { + "name": "Keris(p++)", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 20, + "acrush": -10, + "amagic": 2, + "dmagic": 2, + "str": 30, + "prayer": 2, + "aspeed": 4 + } + }, + "10585": { + "name": "Parchment", + "quest": true, + "weight": 0.02 + }, + "10586": { + "name": "Combat lamp", + "quest": true, + "weight": 0.02 + }, + "10587": { + "name": "Tarn's diary", + "quest": true, + "weight": 0.453 + }, + "10588": { + "name": "Salve amulet (e)", + "equipable": true, + "weight": 0.007, + "equipment": { + "slot": 2, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "prayer": 3 + } + }, + "10589": { + "name": "Granite helm", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 0, + "amagic": -9, + "arange": -7, + "dstab": 31, + "dslash": 33, + "dcrush": 29, + "dmagic": -1, + "drange": 39 + } + }, + "10592": { + "name": "Penguin bongos", + "quest": true, + "weight": 2.0 + }, + "10593": { + "name": "Cowbells", + "quest": true, + "weight": 2.0 + }, + "10594": { + "name": "Clockwork book", + "quest": true, + "weight": 1.0 + }, + "10595": { + "name": "Clockwork suit", + "quest": true, + "equipable": true, + "weight": 2.0 + }, + "10596": { + "name": "Clockwork suit", + "quest": true, + "equipable": true, + "weight": 2.0 + }, + "10597": { + "name": "Mission report", + "quest": true, + "weight": 0.001 + }, + "10598": { + "name": "Mission report", + "quest": true, + "weight": 0.001 + }, + "10599": { + "name": "Mission report", + "quest": true, + "weight": 0.001 + }, + "10600": { + "name": "Kgp id card", + "quest": true, + "weight": 0.001 + }, + "10808": { + "name": "Arctic pyre logs", + "weight": 1.36 + }, + "10810": { + "name": "Arctic pine logs", + "weight": 1.36 + }, + "10812": { + "name": "Split log", + "quest": true, + "weight": 1.814 + }, + "10814": { + "name": "Hair", + "weight": 0.001 + }, + "10816": { + "name": "Raw yak meat", + "weight": 0.34 + }, + "10818": { + "name": "Yak-hide", + "weight": 0.453 + }, + "10820": { + "name": "Cured yak-hide", + "weight": 0.453 + }, + "10822": { + "name": "Yak-hide armour", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": -5, + "dstab": 25, + "dslash": 20, + "dcrush": 15, + "dmagic": -2, + "drange": 25 + } + }, + "10824": { + "name": "Yak-hide armour", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 7, + "amagic": -5, + "arange": 10, + "dstab": 25, + "dslash": 20, + "dcrush": 15, + "dmagic": -2, + "drange": 10 + } + }, + "10826": { + "name": "Fremennik shield", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 17, + "dslash": 17, + "dcrush": 31, + "dmagic": -4, + "drange": 33 + } + }, + "10828": { + "name": "Helm of neitiznot", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "dstab": 31, + "dslash": 29, + "dcrush": 34, + "dmagic": 3, + "drange": 30, + "str": 3, + "prayer": 3 + } + }, + "10830": { + "name": "Royal decree", + "quest": true, + "weight": 0.453 + }, + "10831": { + "name": "Empty tax bag", + "quest": true, + "weight": 0.453 + }, + "10832": { + "name": "Light tax bag", + "quest": true, + "weight": 1.814 + }, + "10833": { + "name": "Normal tax bag", + "quest": true, + "weight": 3.628 + }, + "10834": { + "name": "Hefty tax bag", + "quest": true, + "weight": 5.443 + }, + "10836": { + "name": "Silly jester hat", + "quest": true, + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "dmagic": 5, + "drange": -5 + } + }, + "10837": { + "name": "Silly jester top", + "quest": true, + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "dmagic": 5, + "drange": -5 + } + }, + "10838": { + "name": "Silly jester tights", + "quest": true, + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7, + "dmagic": 5, + "drange": -5 + } + }, + "10839": { + "name": "Silly jester boots", + "quest": true, + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10, + "dmagic": 5, + "drange": -5 + } + }, + "10842": { + "name": "Decapitated head", + "quest": true, + "weight": 3.628 + }, + "10844": { + "name": "Spring sq'irk", + "weight": 0.01 + }, + "10845": { + "name": "Summer sq'irk" + }, + "10846": { + "name": "Autumn sq'irk", + "weight": 0.01 + }, + "10847": { + "name": "Winter sq'irk", + "weight": 0.01 + }, + "10848": { + "name": "Spring sq'irkjuice", + "weight": 0.05 + }, + "10849": { + "name": "Summer sq'irkjuice", + "weight": 0.05 + }, + "10850": { + "name": "Autumn sq'irkjuice", + "weight": 0.05 + }, + "10851": { + "name": "Winter sq'irkjuice", + "weight": 0.05 + }, + "10856": { + "name": "Sin seer's note", + "weight": 0.028 + }, + "10857": { + "name": "Severed leg", + "quest": true, + "weight": 1.814 + }, + "10858": { + "name": "Shadow sword", + "quest": true, + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 27, + "acrush": 21, + "amagic": 4, + "dmagic": 4, + "drange": -1, + "str": 26, + "aspeed": 6 + } + }, + "10859": { + "name": "Tea flask", + "weight": 0.1 + }, + "10862": { + "name": "Hard hat", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "10863": { + "name": "Builder's shirt", + "quest": true, + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 4 + } + }, + "10864": { + "name": "Builder's trousers", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "10865": { + "name": "Builder's boots", + "quest": true, + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 10 + } + }, + "10866": { + "name": "Rivets", + "quest": true + }, + "10870": { + "name": "Binding fluid", + "quest": true, + "weight": 0.01 + }, + "10871": { + "name": "Pipe", + "quest": true, + "weight": 2.5 + }, + "10872": { + "name": "Pipe ring", + "quest": true, + "weight": 0.4 + }, + "10873": { + "name": "Metal sheet", + "quest": true, + "weight": 0.6 + }, + "10874": { + "name": "Coloured ball", + "quest": true, + "weight": 0.01 + }, + "10875": { + "name": "Valve wheel", + "quest": true, + "weight": 0.32 + }, + "10876": { + "name": "Metal bar", + "quest": true, + "weight": 0.92 + }, + "10877": { + "name": "Plain satchel", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 5 + } + }, + "10878": { + "name": "Green satchel", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 5 + } + }, + "10879": { + "name": "Red satchel", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 5 + } + }, + "10880": { + "name": "Black satchel", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 5 + } + }, + "10881": { + "name": "Gold satchel", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 5 + } + }, + "10882": { + "name": "Rune satchel", + "equipable": true, + "weight": 0.15, + "equipment": { + "slot": 5 + } + }, + "10884": { + "name": "Fuse", + "quest": true, + "weight": 0.007 + }, + "10885": { + "name": "Keg", + "quest": true, + "weight": 12.0 + }, + "10887": { + "name": "Barrelchest anchor", + "quest": true, + "equipable": true, + "weight": 30.0, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 10, + "acrush": 92, + "str": 100, + "aspeed": 6 + } + }, + "10888": { + "name": "Barrelchest anchor", + "quest": true, + "equipable": true, + "weight": 30.0, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 10, + "acrush": 92, + "str": 100, + "aspeed": 6 + } + }, + "10889": { + "name": "Blessed lamp", + "quest": true, + "weight": 0.1 + }, + "10890": { + "name": "Prayer book", + "weight": 0.05 + }, + "10891": { + "name": "Wooden cat", + "quest": true, + "weight": 0.03 + }, + "10893": { + "name": "Cranial clamp", + "quest": true, + "weight": 0.01 + }, + "10894": { + "name": "Brain tongs", + "quest": true, + "weight": 0.02 + }, + "10895": { + "name": "Bell jar", + "quest": true, + "weight": 1.0 + }, + "10896": { + "name": "Wolf whistle", + "quest": true + }, + "10897": { + "name": "Shipping order", + "quest": true, + "weight": 0.001 + }, + "10898": { + "name": "Keg", + "quest": true, + "weight": 12.0 + }, + "10899": { + "name": "Crate part", + "quest": true + }, + "10904": { + "name": "Skull staple", + "quest": true + }, + "10909": { + "name": "Mixture - step 1(4)", + "weight": 0.035 + }, + "10911": { + "name": "Mixture - step 1(3)", + "weight": 0.03 + }, + "10913": { + "name": "Mixture - step 1(2)" + }, + "10915": { + "name": "Mixture - step 1(1)", + "weight": 0.02 + }, + "10917": { + "name": "Mixture - step 2(4)", + "weight": 0.035 + }, + "10919": { + "name": "Mixture - step 2(3)", + "weight": 0.03 + }, + "10921": { + "name": "Mixture - step 2(2)", + "weight": 0.025 + }, + "10923": { + "name": "Mixture - step 2(1)", + "weight": 0.02 + }, + "10925": { + "name": "Sanfew serum(4)", + "weight": 0.035 + }, + "10927": { + "name": "Sanfew serum(3)", + "weight": 0.03 + }, + "10929": { + "name": "Sanfew serum(2)", + "weight": 0.025 + }, + "10931": { + "name": "Sanfew serum(1)", + "weight": 0.02 + }, + "10933": { + "name": "Lumberjack boots", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 10 + } + }, + "10934": { + "name": "Reward token" + }, + "10935": { + "name": "Reward token" + }, + "10936": { + "name": "Reward token" + }, + "10937": { + "name": "Nail beast nails", + "weight": 0.02 + }, + "10939": { + "name": "Lumberjack top", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 4 + } + }, + "10940": { + "name": "Lumberjack legs", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 7 + } + }, + "10941": { + "name": "Lumberjack hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0 + } + }, + "10942": { + "name": "Reward token" + }, + "10943": { + "name": "Reward token" + }, + "10944": { + "name": "Reward token" + }, + "10952": { + "name": "Slayer bell", + "weight": 0.028 + }, + "10954": { + "name": "Frog-leather body", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 4, + "amagic": -5, + "arange": 10, + "dstab": 23, + "dslash": 26, + "dcrush": 30, + "dmagic": 15, + "drange": 32 + } + }, + "10956": { + "name": "Frog-leather chaps", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 7, + "amagic": -5, + "arange": 2, + "dstab": 7, + "dslash": 7, + "dcrush": 9, + "dmagic": 4, + "drange": 9 + } + }, + "10958": { + "name": "Frog-leather boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -8, + "arange": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "drange": 1 + } + }, + "10960": { + "name": "Green gloop soup", + "weight": 0.001 + }, + "10961": { + "name": "Frogspawn gumbo", + "weight": 0.001 + }, + "10962": { + "name": "Frogburger", + "weight": 0.001 + }, + "10963": { + "name": "Coated frogs' legs", + "weight": 0.001 + }, + "10964": { + "name": "Bat shish", + "weight": 0.001 + }, + "10965": { + "name": "Fingers", + "weight": 0.001 + }, + "10966": { + "name": "Grubs à la mode", + "weight": 0.001 + }, + "10967": { + "name": "Roast frog", + "weight": 0.001 + }, + "10968": { + "name": "Mushrooms", + "weight": 0.001 + }, + "10969": { + "name": "Fillets", + "weight": 0.001 + }, + "10970": { + "name": "Loach", + "weight": 0.001 + }, + "10971": { + "name": "Eel sushi", + "weight": 0.001 + }, + "10972": { + "name": "Dorgesh-kaan sphere" + }, + "10973": { + "name": "Light orb", + "weight": 0.001 + }, + "10975": { + "name": "Spanner", + "weight": 1.0 + }, + "10976": { + "name": "Long bone", + "weight": 1.0 + }, + "10977": { + "name": "Curved bone", + "weight": 1.0 + }, + "10978": { + "name": "Swamp weed", + "weight": 0.2 + }, + "10980": { + "name": "Empty light orb", + "weight": 0.001 + }, + "10981": { + "name": "Cave goblin wire", + "weight": 1.0 + }, + "10983": { + "name": "Cog", + "weight": 3.0 + }, + "10984": { + "name": "Cog", + "weight": 3.0 + }, + "10985": { + "name": "Fuse", + "weight": 1.0 + }, + "10986": { + "name": "Fuse", + "weight": 1.0 + }, + "10987": { + "name": "Meter", + "weight": 1.0 + }, + "10988": { + "name": "Meter", + "weight": 1.0 + }, + "10989": { + "name": "Capacitor", + "weight": 1.0 + }, + "10990": { + "name": "Capacitor", + "weight": 1.0 + }, + "10991": { + "name": "Lever", + "weight": 3.0 + }, + "10992": { + "name": "Lever", + "weight": 3.0 + }, + "10993": { + "name": "Powerbox", + "weight": 3.0 + }, + "10994": { + "name": "Powerbox", + "weight": 3.0 + }, + "10995": { + "name": "Perfect shell", + "weight": 6.803 + }, + "10996": { + "name": "Perfect snail shell", + "weight": 7.0 + }, + "10999": { + "name": "Goblin book", + "weight": 0.1 + }, + "11001": { + "name": "Dagon'hai history", + "quest": true, + "weight": 0.01 + }, + "11002": { + "name": "Sin'keth's diary", + "quest": true, + "weight": 0.01 + }, + "11003": { + "name": "An empty folder", + "quest": true, + "weight": 0.001 + }, + "11006": { + "name": "Used folder", + "quest": true, + "weight": 0.001 + }, + "11007": { + "name": "Full folder", + "quest": true, + "weight": 0.001 + }, + "11008": { + "name": "Rat's paper", + "quest": true, + "weight": 0.001 + }, + "11009": { + "name": "Letter to surok", + "quest": true, + "weight": 0.001 + }, + "11010": { + "name": "Surok's letter", + "quest": true, + "weight": 0.001 + }, + "11011": { + "name": "Zaff's instructions", + "quest": true, + "weight": 0.001 + }, + "11012": { + "name": "Wand", + "quest": true, + "weight": 0.001 + }, + "11013": { + "name": "Infused wand", + "quest": true, + "weight": 0.001 + }, + "11014": { + "name": "Beacon ring", + "quest": true, + "equipable": true, + "weight": 0.006, + "equipment": { + "slot": 12, + "amagic": 2, + "dmagic": 1 + } + }, + "11019": { + "name": "Chicken feet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 10 + } + }, + "11020": { + "name": "Chicken wings", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 4 + } + }, + "11021": { + "name": "Chicken head", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 0 + } + }, + "11022": { + "name": "Chicken legs", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 7 + } + }, + "11023": { + "name": "Magic egg", + "weight": 0.01 + }, + "11024": { + "name": "Rabbit mould", + "weight": 0.1 + }, + "11025": { + "name": "Chocolate chunks" + }, + "11026": { + "name": "Chocolate kebbit" + }, + "11027": { + "name": "Easter egg", + "weight": 0.15 + }, + "11028": { + "name": "Easter egg", + "weight": 0.15 + }, + "11029": { + "name": "Easter egg", + "weight": 0.15 + }, + "11030": { + "name": "Easter egg", + "weight": 0.15 + }, + "11031": { + "name": "Damp planks", + "quest": true, + "weight": 0.2 + }, + "11032": { + "name": "Crude carving", + "quest": true + }, + "11033": { + "name": "Cruder carving", + "quest": true, + "weight": 0.05 + }, + "11034": { + "name": "Sven's last map", + "quest": true, + "weight": 0.01 + }, + "11035": { + "name": "Windswept logs", + "quest": true, + "weight": 0.05 + }, + "11036": { + "name": "Parchment", + "quest": true, + "weight": 0.453 + }, + "11037": { + "name": "Brine sabre", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 47, + "acrush": -2, + "str": 46, + "aspeed": 4 + } + }, + "11039": { + "name": "Key", + "quest": true, + "weight": 0.001 + }, + "11040": { + "name": "Key", + "quest": true, + "weight": 0.001 + }, + "11041": { + "name": "Key", + "quest": true, + "weight": 0.001 + }, + "11042": { + "name": "Key", + "quest": true, + "weight": 0.001 + }, + "11043": { + "name": "Key", + "quest": true, + "weight": 0.001 + }, + "11045": { + "name": "Rotten barrel", + "quest": true, + "weight": 0.001 + }, + "11048": { + "name": "Armour shard", + "quest": true, + "weight": 0.001 + }, + "11049": { + "name": "Artefact", + "quest": true + }, + "11050": { + "name": "Axe head", + "quest": true, + "weight": 0.001 + }, + "11051": { + "name": "Artefact", + "quest": true + }, + "11052": { + "name": "Helmet fragment", + "quest": true, + "weight": 0.001 + }, + "11053": { + "name": "Artefact", + "quest": true + }, + "11054": { + "name": "Shield fragment", + "quest": true, + "weight": 0.001 + }, + "11055": { + "name": "Artefact", + "quest": true + }, + "11056": { + "name": "Sword fragment", + "quest": true, + "weight": 0.001 + }, + "11057": { + "name": "Artefact", + "quest": true + }, + "11058": { + "name": "Mace", + "quest": true, + "weight": 0.001 + }, + "11059": { + "name": "Artefact", + "quest": true + }, + "11060": { + "name": "Goblin village sphere", + "quest": true + }, + "11061": { + "name": "Ancient mace", + "quest": true, + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -2, + "acrush": 16, + "str": 14, + "prayer": 3, + "aspeed": 5 + } + }, + "11065": { + "name": "Bracelet mould", + "weight": 0.453 + }, + "11069": { + "name": "Gold bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11072": { + "name": "Sapphire bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11074": { + "name": "Bracelet of clay", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11076": { + "name": "Emerald bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11079": { + "name": "Castle wars bracelet(3)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11081": { + "name": "Castle wars bracelet(2)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11083": { + "name": "Castle wars bracelet(1)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11085": { + "name": "Ruby bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11088": { + "name": "Inoculation bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11090": { + "name": "Phoenix necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11092": { + "name": "Diamond bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11095": { + "name": "Abyssal bracelet(5)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11097": { + "name": "Abyssal bracelet(4)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11099": { + "name": "Abyssal bracelet(3)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11101": { + "name": "Abyssal bracelet(2)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11103": { + "name": "Abyssal bracelet(1)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11105": { + "name": "Skills necklace(4)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11107": { + "name": "Skills necklace(3)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11109": { + "name": "Skills necklace(2)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11111": { + "name": "Skills necklace(1)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11113": { + "name": "Skills necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11115": { + "name": "Dragonstone bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11118": { + "name": "Combat bracelet(4)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11120": { + "name": "Combat bracelet(3)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11122": { + "name": "Combat bracelet(2)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11124": { + "name": "Combat bracelet(1)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11126": { + "name": "Combat bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11128": { + "name": "Berserker necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": -10, + "aslash": -10, + "acrush": -10, + "dstab": -20, + "dslash": -20, + "dcrush": -20, + "dmagic": -20, + "drange": -20, + "str": 7, + "prayer": 3 + } + }, + "11130": { + "name": "Onyx bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9 + } + }, + "11133": { + "name": "Regen bracelet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 8, + "aslash": 8, + "acrush": 8, + "amagic": 3, + "arange": 7, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 3, + "drange": 6, + "str": 7 + } + }, + "11136": { + "name": "Karamja gloves 1", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1 + } + }, + "11137": { + "name": "Antique lamp", + "quest": true + }, + "11138": { + "name": "Karamja gloves 2", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1 + } + }, + "11139": { + "name": "Antique lamp", + "quest": true + }, + "11140": { + "name": "Karamja gloves 3", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1 + } + }, + "11141": { + "name": "Antique lamp", + "quest": true + }, + "11151": { + "name": "Dream vial (empty)", + "quest": true, + "weight": 1.0 + }, + "11152": { + "name": "Dream vial (water)", + "quest": true, + "weight": 0.02 + }, + "11153": { + "name": "Dream vial (herb)", + "quest": true, + "weight": 0.025 + }, + "11154": { + "name": "Dream potion", + "quest": true, + "weight": 0.03 + }, + "11155": { + "name": "Ground astral rune", + "quest": true, + "weight": 0.004 + }, + "11156": { + "name": "Astral rune shards", + "quest": true, + "weight": 0.453 + }, + "11157": { + "name": "Dreamy lamp", + "quest": true, + "weight": 0.02 + }, + "11158": { + "name": "Cyrisus's chest", + "quest": true, + "weight": 0.6 + }, + "11159": { + "name": "Hunter kit", + "weight": 0.4 + }, + "11171": { + "name": "Newspaper", + "weight": 0.02 + }, + "11173": { + "name": "Half certificate", + "quest": true + }, + "11174": { + "name": "Half certificate", + "quest": true + }, + "11175": { + "name": "Uncleaned find", + "weight": 0.085 + }, + "11176": { + "name": "Arrowheads", + "weight": 0.001 + }, + "11177": { + "name": "Jewellery", + "weight": 0.001 + }, + "11178": { + "name": "Pottery", + "weight": 0.001 + }, + "11179": { + "name": "Old coin", + "weight": 0.001 + }, + "11180": { + "name": "Ancient coin", + "weight": 0.001 + }, + "11181": { + "name": "Ancient symbol", + "weight": 0.001 + }, + "11182": { + "name": "Old symbol", + "weight": 0.001 + }, + "11183": { + "name": "Old chipped vase", + "weight": 0.001 + }, + "11184": { + "name": "Museum map", + "weight": 0.001 + }, + "11185": { + "name": "Antique lamp", + "quest": true + }, + "11186": { + "name": "Antique lamp", + "quest": true + }, + "11187": { + "name": "Antique lamp", + "quest": true + }, + "11188": { + "name": "Antique lamp", + "quest": true + }, + "11189": { + "name": "Antique lamp", + "quest": true + }, + "11190": { + "name": "Digsite pendant (1)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11191": { + "name": "Digsite pendant (2)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11192": { + "name": "Digsite pendant (3)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11193": { + "name": "Digsite pendant (4)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11194": { + "name": "Digsite pendant (5)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11195": { + "name": "Clean necklace", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11196": { + "name": "Griffin feather", + "quest": true, + "weight": 0.001 + }, + "11197": { + "name": "Miazrqa's pendant", + "quest": true, + "weight": 0.01 + }, + "11198": { + "name": "Music sheet", + "quest": true, + "weight": 0.01 + }, + "11199": { + "name": "Rupert's helmet", + "quest": true, + "weight": 1.9 + }, + "11200": { + "name": "Dwarven helmet", + "quest": true, + "equipable": true, + "weight": 1.9, + "equipment": { + "slot": 0, + "acrush": 6, + "amagic": -2, + "arange": -2, + "dstab": 27, + "dslash": 28, + "dcrush": 31, + "dmagic": 5, + "drange": 24 + } + }, + "11202": { + "name": "Shrinking recipe", + "quest": true + }, + "11203": { + "name": "To-do list", + "quest": true, + "weight": 0.01 + }, + "11204": { + "name": "Shrink-me-quick", + "quest": true, + "weight": 0.035 + }, + "11205": { + "name": "Shrunk ogleroot", + "quest": true + }, + "11210": { + "name": "Golden goblin", + "quest": true, + "weight": 30.0 + }, + "11211": { + "name": "Magic beans", + "quest": true, + "weight": 0.01 + }, + "11212": { + "name": "Dragon arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "11217": { + "name": "Dragon fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "11222": { + "name": "Dragon fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "11227": { + "name": "Dragon arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "11228": { + "name": "Dragon arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "11229": { + "name": "Dragon arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "11230": { + "name": "Dragon dart", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 18, + "rstr": 20, + "aspeed": 3 + } + }, + "11231": { + "name": "Dragon dart(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 18, + "rstr": 20, + "aspeed": 3 + } + }, + "11232": { + "name": "Dragon dart tip" + }, + "11233": { + "name": "Dragon dart(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 18, + "rstr": 20, + "aspeed": 3 + } + }, + "11234": { + "name": "Dragon dart(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 18, + "rstr": 20, + "aspeed": 3 + } + }, + "11235": { + "name": "Dark bow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 9 + } + }, + "11237": { + "name": "Dragon arrowtips" + }, + "11238": { + "name": "Baby impling jar", + "weight": 2.267 + }, + "11240": { + "name": "Young impling jar", + "weight": 2.267 + }, + "11242": { + "name": "Gourmet impling jar", + "weight": 2.267 + }, + "11244": { + "name": "Earth impling jar", + "weight": 2.267 + }, + "11246": { + "name": "Essence impling jar", + "weight": 2.267 + }, + "11248": { + "name": "Eclectic impling jar", + "weight": 2.267 + }, + "11250": { + "name": "Nature impling jar", + "weight": 2.267 + }, + "11252": { + "name": "Magpie impling jar", + "weight": 2.267 + }, + "11254": { + "name": "Ninja impling jar", + "weight": 2.267 + }, + "11256": { + "name": "Dragon impling jar", + "weight": 2.267 + }, + "11258": { + "name": "Jar generator", + "weight": 1.0 + }, + "11259": { + "name": "Magic butterfly net", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 3, + "aspeed": 6 + } + }, + "11260": { + "name": "Impling jar", + "weight": 0.02 + }, + "11262": { + "name": "Imp repellent", + "weight": 2.267 + }, + "11264": { + "name": "Anchovy oil", + "weight": 0.035 + }, + "11266": { + "name": "Anchovy paste" + }, + "11273": { + "name": "Impling scroll", + "weight": 0.003 + }, + "11279": { + "name": "Elvarg's head", + "quest": true, + "weight": 0.01 + }, + "11280": { + "name": "Cavalier mask", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "11282": { + "name": "Beret mask", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "11283": { + "name": "Dragonfire shield", + "equipable": true, + "weight": 7.257, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -5, + "dstab": 20, + "dslash": 25, + "dcrush": 22, + "dmagic": 10, + "drange": 22, + "str": 7 + } + }, + "11284": { + "name": "Dragonfire shield", + "equipable": true, + "weight": 7.257, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -5, + "dstab": 20, + "dslash": 25, + "dcrush": 22, + "dmagic": 10, + "drange": 22, + "str": 7 + } + }, + "11286": { + "name": "Draconic visage", + "weight": 1.814 + }, + "11323": { + "name": "Barbarian rod", + "weight": 1.36 + }, + "11324": { + "name": "Roe", + "weight": 0.05 + }, + "11326": { + "name": "Caviar", + "weight": 0.05 + }, + "11328": { + "name": "Leaping trout", + "weight": 0.5 + }, + "11330": { + "name": "Leaping salmon", + "weight": 0.5 + }, + "11332": { + "name": "Leaping sturgeon", + "weight": 1.0 + }, + "11334": { + "name": "Fish offcuts" + }, + "11335": { + "name": "Dragon full helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 45, + "dslash": 48, + "dcrush": 41, + "dmagic": -1, + "drange": 46 + } + }, + "11337": { + "name": "Mangled bones", + "weight": 12.0 + }, + "11338": { + "name": "Chewed bones", + "weight": 9.6 + }, + "11339": { + "name": "My notes", + "weight": 0.01 + }, + "11340": { + "name": "Barbarian skills", + "weight": 0.01 + }, + "11367": { + "name": "Bronze hasta", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": -1, + "dslash": -1, + "dcrush": -1, + "drange": -1, + "str": 6, + "aspeed": 5 + } + }, + "11369": { + "name": "Iron hasta", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": -2, + "dslash": -2, + "dcrush": -2, + "drange": -2, + "str": 10, + "aspeed": 5 + } + }, + "11371": { + "name": "Steel hasta", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": -3, + "dslash": -3, + "dcrush": -3, + "drange": -3, + "str": 12, + "aspeed": 5 + } + }, + "11373": { + "name": "Mithril hasta", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": -5, + "dslash": -5, + "dcrush": -4, + "drange": -5, + "str": 18, + "aspeed": 5 + } + }, + "11375": { + "name": "Adamant hasta", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": -6, + "dslash": -7, + "dcrush": -5, + "drange": -6, + "str": 28, + "aspeed": 5 + } + }, + "11377": { + "name": "Rune hasta", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": -10, + "dslash": -10, + "dcrush": -9, + "drange": -10, + "str": 42, + "aspeed": 5 + } + }, + "11379": { + "name": "Bronze hasta(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": -1, + "dslash": -1, + "dcrush": -1, + "drange": -1, + "str": 6, + "aspeed": 5 + } + }, + "11381": { + "name": "Bronze hasta(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": -1, + "dslash": -1, + "dcrush": -1, + "drange": -1, + "str": 6, + "aspeed": 5 + } + }, + "11382": { + "name": "Bronze hasta(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": -1, + "dslash": -1, + "dcrush": -1, + "drange": -1, + "str": 6, + "aspeed": 5 + } + }, + "11384": { + "name": "Bronze hasta(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 5, + "aslash": 5, + "acrush": 5, + "dstab": -1, + "dslash": -1, + "dcrush": -1, + "drange": -1, + "str": 6, + "aspeed": 5 + } + }, + "11386": { + "name": "Iron hasta(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": -2, + "dslash": -2, + "dcrush": -2, + "drange": -2, + "str": 10, + "aspeed": 5 + } + }, + "11388": { + "name": "Iron hasta(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": -2, + "dslash": -2, + "dcrush": -2, + "drange": -2, + "str": 10, + "aspeed": 5 + } + }, + "11389": { + "name": "Iron hasta(p+)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": -2, + "dslash": -2, + "dcrush": -2, + "drange": -2, + "str": 10, + "aspeed": 5 + } + }, + "11391": { + "name": "Iron hasta(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": -2, + "dslash": -2, + "dcrush": -2, + "drange": -2, + "str": 10, + "aspeed": 5 + } + }, + "11393": { + "name": "Steel hasta(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": -3, + "dslash": -3, + "dcrush": -3, + "drange": -3, + "str": 12, + "aspeed": 5 + } + }, + "11395": { + "name": "Steel hasta(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": -3, + "dslash": -3, + "dcrush": -3, + "drange": -3, + "str": 12, + "aspeed": 5 + } + }, + "11396": { + "name": "Steel hasta(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": -3, + "dslash": -3, + "dcrush": -3, + "drange": -3, + "str": 12, + "aspeed": 5 + } + }, + "11398": { + "name": "Steel hasta(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": -3, + "dslash": -3, + "dcrush": -3, + "drange": -3, + "str": 12, + "aspeed": 5 + } + }, + "11400": { + "name": "Mithril hasta(p)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": -5, + "dslash": -5, + "dcrush": -4, + "drange": -5, + "str": 18, + "aspeed": 5 + } + }, + "11402": { + "name": "Mithril hasta(kp)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": -5, + "dslash": -5, + "dcrush": -4, + "drange": -5, + "str": 18, + "aspeed": 5 + } + }, + "11403": { + "name": "Mithril hasta(p+)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": -5, + "dslash": -5, + "dcrush": -4, + "drange": -5, + "str": 18, + "aspeed": 5 + } + }, + "11405": { + "name": "Mithril hasta(p++)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": -5, + "dslash": -5, + "dcrush": -4, + "drange": -5, + "str": 18, + "aspeed": 5 + } + }, + "11407": { + "name": "Adamant hasta(p)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": -6, + "dslash": -7, + "dcrush": -5, + "drange": -6, + "str": 28, + "aspeed": 5 + } + }, + "11409": { + "name": "Adamant hasta(kp)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": -6, + "dslash": -7, + "dcrush": -5, + "drange": -6, + "str": 28, + "aspeed": 5 + } + }, + "11410": { + "name": "Adamant hasta(p+)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": -6, + "dslash": -7, + "dcrush": -5, + "drange": -6, + "str": 28, + "aspeed": 5 + } + }, + "11412": { + "name": "Adamant hasta(p++)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": -6, + "dslash": -7, + "dcrush": -5, + "drange": -6, + "str": 28, + "aspeed": 5 + } + }, + "11414": { + "name": "Rune hasta(p)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": -10, + "dslash": -10, + "dcrush": -9, + "drange": -10, + "str": 42, + "aspeed": 5 + } + }, + "11416": { + "name": "Rune hasta(kp)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": -10, + "dslash": -10, + "dcrush": -9, + "drange": -10, + "str": 42, + "aspeed": 5 + } + }, + "11417": { + "name": "Rune hasta(p+)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": -10, + "dslash": -10, + "dcrush": -9, + "drange": -10, + "str": 42, + "aspeed": 5 + } + }, + "11419": { + "name": "Rune hasta(p++)", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": -10, + "dslash": -10, + "dcrush": -9, + "drange": -10, + "str": 42, + "aspeed": 5 + } + }, + "11429": { + "name": "Attack mix(2)", + "weight": 0.075 + }, + "11431": { + "name": "Attack mix(1)", + "weight": 0.045 + }, + "11433": { + "name": "Antipoison mix(2)", + "weight": 0.075 + }, + "11435": { + "name": "Antipoison mix(1)", + "weight": 0.045 + }, + "11437": { + "name": "Relicym's mix(2)", + "weight": 0.075 + }, + "11439": { + "name": "Relicym's mix(1)", + "weight": 0.045 + }, + "11441": { + "name": "Strength mix(1)", + "weight": 0.045 + }, + "11443": { + "name": "Strength mix(2)", + "weight": 0.075 + }, + "11445": { + "name": "Combat mix(2)", + "weight": 0.075 + }, + "11447": { + "name": "Combat mix(1)", + "weight": 0.045 + }, + "11449": { + "name": "Restore mix(2)", + "weight": 0.075 + }, + "11451": { + "name": "Restore mix(1)", + "weight": 0.045 + }, + "11453": { + "name": "Energy mix(2)", + "weight": 0.075 + }, + "11455": { + "name": "Energy mix(1)", + "weight": 0.045 + }, + "11457": { + "name": "Defence mix(2)" + }, + "11459": { + "name": "Defence mix(1)", + "weight": 0.045 + }, + "11461": { + "name": "Agility mix(2)", + "weight": 0.075 + }, + "11463": { + "name": "Agility mix(1)", + "weight": 0.045 + }, + "11465": { + "name": "Prayer mix(2)", + "weight": 0.075 + }, + "11467": { + "name": "Prayer mix(1)", + "weight": 0.045 + }, + "11469": { + "name": "Superattack mix(2)", + "weight": 0.075 + }, + "11471": { + "name": "Superattack mix(1)", + "weight": 0.045 + }, + "11473": { + "name": "Anti-poison supermix(2)", + "weight": 0.075 + }, + "11475": { + "name": "Anti-poison supermix(1)", + "weight": 0.045 + }, + "11477": { + "name": "Fishing mix(2)", + "weight": 0.075 + }, + "11479": { + "name": "Fishing mix(1)", + "weight": 0.045 + }, + "11481": { + "name": "Super energy mix(2)", + "weight": 0.075 + }, + "11483": { + "name": "Super energy mix(1)", + "weight": 0.045 + }, + "11485": { + "name": "Super str. mix(2)", + "weight": 0.075 + }, + "11487": { + "name": "Super str. mix(1)", + "weight": 0.045 + }, + "11489": { + "name": "Magic essence mix(2)", + "weight": 0.075 + }, + "11491": { + "name": "Magic essence mix(1)" + }, + "11493": { + "name": "Super restore mix(2)", + "weight": 0.075 + }, + "11495": { + "name": "Super restore mix(1)", + "weight": 0.045 + }, + "11497": { + "name": "Super def. mix(2)", + "weight": 0.075 + }, + "11499": { + "name": "Super def. mix(1)", + "weight": 0.045 + }, + "11501": { + "name": "Antidote+ mix(2)", + "weight": 0.075 + }, + "11503": { + "name": "Antidote+ mix(1)", + "weight": 0.045 + }, + "11505": { + "name": "Antifire mix(2)", + "weight": 0.075 + }, + "11507": { + "name": "Antifire mix(1)", + "weight": 0.045 + }, + "11509": { + "name": "Ranging mix(2)", + "weight": 0.075 + }, + "11511": { + "name": "Ranging mix(1)", + "weight": 0.045 + }, + "11513": { + "name": "Magic mix(2)", + "weight": 0.075 + }, + "11515": { + "name": "Magic mix(1)", + "weight": 0.045 + }, + "11517": { + "name": "Hunting mix(2)", + "weight": 0.075 + }, + "11519": { + "name": "Hunting mix(1)", + "weight": 0.045 + }, + "11521": { + "name": "Zamorak mix(2)", + "weight": 0.075 + }, + "11523": { + "name": "Zamorak mix(1)", + "weight": 0.045 + }, + "11640": { + "name": "Book of knowledge", + "weight": 1.0 + }, + "11656": { + "name": "Glassblowing book", + "weight": 0.003 + }, + "11663": { + "name": "Void mage helm", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6 + } + }, + "11664": { + "name": "Void ranger helm", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6 + } + }, + "11665": { + "name": "Void melee helm", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6 + } + }, + "11666": { + "name": "Void seal(8)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11667": { + "name": "Void seal(7)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11668": { + "name": "Void seal(6)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11669": { + "name": "Void seal(5)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11670": { + "name": "Void seal(4)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11671": { + "name": "Void seal(3)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11672": { + "name": "Void seal(2)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11673": { + "name": "Void seal(1)", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 2, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1 + } + }, + "11677": { + "name": "Explorer's notes", + "weight": 0.51 + }, + "11678": { + "name": "Black knight helm", + "quest": true, + "weight": 3.0 + }, + "11679": { + "name": "Antique lamp", + "quest": true + }, + "11680": { + "name": "Address form", + "quest": true, + "weight": 0.001 + }, + "11681": { + "name": "Scrap paper", + "quest": true, + "weight": 0.001 + }, + "11682": { + "name": "Hair clip", + "quest": true, + "weight": 0.001 + }, + "11704": { + "name": "Raw pheasant", + "weight": 10.0 + }, + "11705": { + "name": "Beach boxing gloves", + "equipable": true, + "equipment": { + "slot": 3, + "acrush": 1, + "dslash": 1, + "dcrush": 1, + "aspeed": 4 + } + }, + "11706": { + "name": "Beach boxing gloves", + "equipable": true, + "equipment": { + "slot": 3, + "acrush": 1, + "dslash": 1, + "dcrush": 1, + "aspeed": 4 + } + }, + "11707": { + "name": "Cursed goblin hammer", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "11708": { + "name": "Cursed goblin bow", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "11709": { + "name": "Cursed goblin staff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "11710": { + "name": "Anti-dragon shield (nz)", + "quest": true, + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 5, + "dstab": 7, + "dslash": 9, + "dcrush": 8, + "dmagic": 2, + "drange": 8 + } + }, + "11711": { + "name": "Magic secateurs (nz)", + "quest": true, + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 9, + "acrush": -5, + "amagic": 1, + "dslash": 1, + "dmagic": 1, + "str": 1, + "aspeed": 5 + } + }, + "11712": { + "name": "Chaos rune (nz)" + }, + "11713": { + "name": "Death rune (nz)" + }, + "11714": { + "name": "Blood rune (nz)" + }, + "11715": { + "name": "Air rune (nz)" + }, + "11716": { + "name": "Water rune (nz)" + }, + "11717": { + "name": "Earth rune (nz)" + }, + "11718": { + "name": "Fire rune (nz)" + }, + "11722": { + "name": "Super ranging (4)" + }, + "11723": { + "name": "Super ranging (3)" + }, + "11724": { + "name": "Super ranging (2)" + }, + "11725": { + "name": "Super ranging (1)" + }, + "11726": { + "name": "Super magic potion (4)" + }, + "11727": { + "name": "Super magic potion (3)" + }, + "11728": { + "name": "Super magic potion (2)" + }, + "11729": { + "name": "Super magic potion (1)" + }, + "11730": { + "name": "Overload (4)" + }, + "11731": { + "name": "Overload (3)" + }, + "11732": { + "name": "Overload (2)" + }, + "11733": { + "name": "Overload (1)" + }, + "11734": { + "name": "Absorption (4)" + }, + "11735": { + "name": "Absorption (3)" + }, + "11736": { + "name": "Absorption (2)" + }, + "11737": { + "name": "Absorption (1)" + }, + "11738": { + "name": "Herb box", + "weight": 0.2 + }, + "11739": { + "name": "Opened herb box", + "weight": 0.2 + }, + "11740": { + "name": "Scroll of redirection" + }, + "11741": { + "name": "Rimmington teleport" + }, + "11742": { + "name": "Taverley teleport" + }, + "11743": { + "name": "Pollnivneach teleport" + }, + "11744": { + "name": "Rellekka teleport" + }, + "11745": { + "name": "Brimhaven teleport" + }, + "11746": { + "name": "Yanille teleport" + }, + "11747": { + "name": "Trollheim teleport" + }, + "11748": { + "name": "New crystal bow (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11749": { + "name": "Crystal bow full (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11750": { + "name": "Crystal bow 9/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11751": { + "name": "Crystal bow 8/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11752": { + "name": "Crystal bow 7/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11753": { + "name": "Crystal bow 6/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11754": { + "name": "Crystal bow 5/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11755": { + "name": "Crystal bow 4/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11756": { + "name": "Crystal bow 3/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11757": { + "name": "Crystal bow 2/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11758": { + "name": "Crystal bow 1/10 (i)", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "arange": 100, + "rstr": 70, + "aspeed": 5 + } + }, + "11759": { + "name": "New crystal shield (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11760": { + "name": "Crystal shield full (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11761": { + "name": "Crystal shield 9/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11762": { + "name": "Crystal shield 8/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11763": { + "name": "Crystal shield 7/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11764": { + "name": "Crystal shield 6/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11765": { + "name": "Crystal shield 5/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11766": { + "name": "Crystal shield 4/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11767": { + "name": "Crystal shield 3/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11768": { + "name": "Crystal shield 2/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11769": { + "name": "Crystal shield 1/10 (i)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 5, + "amagic": -10, + "arange": -10, + "dstab": 51, + "dslash": 54, + "dcrush": 53, + "drange": 80 + } + }, + "11770": { + "name": "Seers ring (i)", + "equipable": true, + "equipment": { + "slot": 12, + "amagic": 12, + "dmagic": 12 + } + }, + "11771": { + "name": "Archers ring (i)", + "equipable": true, + "equipment": { + "slot": 12, + "arange": 8, + "drange": 8 + } + }, + "11772": { + "name": "Warrior ring (i)", + "equipable": true, + "equipment": { + "slot": 12, + "aslash": 8, + "dslash": 8 + } + }, + "11773": { + "name": "Berserker ring (i)", + "equipable": true, + "equipment": { + "slot": 12, + "dcrush": 8, + "str": 8 + } + }, + "11774": { + "name": "Black mask (10) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11775": { + "name": "Black mask (9) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11776": { + "name": "Black mask (8) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11777": { + "name": "Black mask (7) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11778": { + "name": "Black mask (6) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11779": { + "name": "Black mask (5) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11780": { + "name": "Black mask (4) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11781": { + "name": "Black mask (3) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11782": { + "name": "Black mask (2) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11783": { + "name": "Black mask (1) (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11784": { + "name": "Black mask (i)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 0, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "11785": { + "name": "Armadyl crossbow", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 3, + "arange": 100, + "prayer": 1, + "aspeed": 6 + } + }, + "11787": { + "name": "Steam battlestaff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "11789": { + "name": "Mystic steam staff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "11791": { + "name": "Staff of the dead", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 70, + "amagic": 17, + "dslash": 3, + "dcrush": 3, + "dmagic": 17, + "str": 72, + "mdmg": 15, + "aspeed": 4 + } + }, + "11794": { + "name": "Godsword shards 1 & 2", + "weight": 2.0 + }, + "11796": { + "name": "Godsword shards 1 & 3", + "weight": 2.0 + }, + "11798": { + "name": "Godsword blade", + "weight": 7.5 + }, + "11800": { + "name": "Godsword shards 2 & 3", + "weight": 2.0 + }, + "11802": { + "name": "Armadyl godsword", + "equipable": true, + "weight": 11.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "11804": { + "name": "Bandos godsword", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "11806": { + "name": "Saradomin godsword", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "11808": { + "name": "Zamorak godsword", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "11810": { + "name": "Armadyl hilt", + "weight": 3.0 + }, + "11812": { + "name": "Bandos hilt", + "weight": 2.5 + }, + "11814": { + "name": "Saradomin hilt", + "weight": 2.5 + }, + "11816": { + "name": "Zamorak hilt", + "weight": 2.5 + }, + "11818": { + "name": "Godsword shard 1", + "weight": 2.0 + }, + "11820": { + "name": "Godsword shard 2", + "weight": 2.0 + }, + "11822": { + "name": "Godsword shard 3", + "weight": 2.0 + }, + "11824": { + "name": "Zamorakian spear", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 65, + "acrush": 65, + "dstab": 13, + "dslash": 13, + "dcrush": 12, + "drange": 13, + "str": 75, + "prayer": 2, + "aspeed": 4 + } + }, + "11826": { + "name": "Armadyl helmet", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": -5, + "arange": 10, + "dstab": 6, + "dslash": 8, + "dcrush": 10, + "dmagic": 10, + "drange": 8, + "prayer": 1 + } + }, + "11828": { + "name": "Armadyl chestplate", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 4, + "astab": -7, + "aslash": -7, + "acrush": -7, + "amagic": -15, + "arange": 33, + "dstab": 56, + "dslash": 48, + "dcrush": 61, + "dmagic": 70, + "drange": 57, + "prayer": 1 + } + }, + "11830": { + "name": "Armadyl chainskirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7, + "astab": -6, + "aslash": -6, + "acrush": -6, + "amagic": -10, + "arange": 20, + "dstab": 32, + "dslash": 26, + "dcrush": 34, + "dmagic": 40, + "drange": 33, + "prayer": 1 + } + }, + "11832": { + "name": "Bandos chestplate", + "equipable": true, + "weight": 12.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": -10, + "dstab": 98, + "dslash": 93, + "dcrush": 105, + "dmagic": -6, + "drange": 133, + "str": 4, + "prayer": 1 + } + }, + "11834": { + "name": "Bandos tassets", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 71, + "dslash": 63, + "dcrush": 66, + "dmagic": -4, + "drange": 93, + "str": 2, + "prayer": 1 + } + }, + "11836": { + "name": "Bandos boots", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 10, + "amagic": -5, + "arange": -3, + "dstab": 17, + "dslash": 18, + "dcrush": 19, + "drange": 15, + "prayer": 1 + } + }, + "11838": { + "name": "Saradomin sword", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "aslash": 82, + "acrush": 60, + "str": 82, + "prayer": 2, + "aspeed": 4 + } + }, + "11840": { + "name": "Dragon boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 16, + "dslash": 17, + "dcrush": 18, + "str": 4 + } + }, + "11842": { + "name": "Knight's notes", + "weight": 0.085 + }, + "11843": { + "name": "Knight's notes", + "weight": 0.085 + }, + "11847": { + "name": "Black h'ween mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "11848": { + "name": "Rancid turkey" + }, + "11849": { + "name": "Mark of grace" + }, + "11850": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "11851": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "11852": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "11853": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "11854": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "11855": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "11856": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "11857": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "11858": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "11859": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "11860": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "11861": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "11862": { + "name": "Black partyhat", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "11863": { + "name": "Rainbow partyhat", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "11864": { + "name": "Slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "11865": { + "name": "Slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "11866": { + "name": "Slayer ring (8)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11867": { + "name": "Slayer ring (7)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11868": { + "name": "Slayer ring (6)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11869": { + "name": "Slayer ring (5)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11870": { + "name": "Slayer ring (4)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11871": { + "name": "Slayer ring (3)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11872": { + "name": "Slayer ring (2)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11873": { + "name": "Slayer ring (1)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11874": { + "name": "Broad arrowheads" + }, + "11875": { + "name": "Broad bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 100 + } + }, + "11876": { + "name": "Unfinished broad bolts" + }, + "11877": { + "name": "Empty vial pack" + }, + "11879": { + "name": "Water-filled vial pack" + }, + "11881": { + "name": "Feather pack" + }, + "11883": { + "name": "Bait pack" + }, + "11885": { + "name": "Broad arrowhead pack" + }, + "11887": { + "name": "Unfinished broad bolt pack" + }, + "11889": { + "name": "Zamorakian hasta", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 65, + "acrush": 65, + "dstab": 13, + "dslash": 13, + "dcrush": 12, + "drange": 13, + "str": 75, + "prayer": 2, + "aspeed": 4 + } + }, + "11893": { + "name": "Decorative armour", + "equipable": true, + "weight": 9.05, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "11894": { + "name": "Decorative armour", + "equipable": true, + "weight": 9.05, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "11895": { + "name": "Decorative armour", + "equipable": true, + "weight": 9.05, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "11896": { + "name": "Decorative armour", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "dstab": 20, + "dslash": 20, + "dcrush": 20, + "dmagic": 20, + "drange": 20 + } + }, + "11897": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 7, + "dstab": 15, + "dslash": 15, + "dcrush": 15, + "dmagic": 15, + "drange": 15 + } + }, + "11898": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 0, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4 + } + }, + "11899": { + "name": "Decorative armour", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "dstab": 20, + "dslash": 20, + "dcrush": 20, + "dmagic": 20, + "drange": 20 + } + }, + "11900": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 7, + "dstab": 15, + "dslash": 15, + "dcrush": 15, + "dmagic": 15, + "drange": 15 + } + }, + "11901": { + "name": "Decorative armour", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 1, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4 + } + }, + "11902": { + "name": "Leaf-bladed sword", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 67, + "aslash": 62, + "str": 50, + "aspeed": 4 + } + }, + "11904": { + "name": "Entomologist's diary" + }, + "11905": { + "name": "Trident of the seas (full)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "11907": { + "name": "Trident of the seas", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "11908": { + "name": "Uncharged trident", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "11910": { + "name": "Chocolate strawberry" + }, + "11912": { + "name": "Box of chocolate strawberries" + }, + "11914": { + "name": "Box of chocolate strawberries" + }, + "11916": { + "name": "Slice of birthday cake" + }, + "11918": { + "name": "Birthday present" + }, + "11919": { + "name": "Cow mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "11920": { + "name": "Dragon pickaxe", + "equipable": true, + "weight": 2.4, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": -2, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "11922": { + "name": "Bonemeal", + "weight": 1.0 + }, + "11923": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "11924": { + "name": "Malediction ward", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 5, + "astab": -8, + "aslash": -8, + "acrush": -8, + "amagic": 12, + "arange": -12, + "dstab": 50, + "dslash": 52, + "dcrush": 48, + "dmagic": 15 + } + }, + "11926": { + "name": "Odium ward", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 5, + "astab": -12, + "aslash": -12, + "acrush": -12, + "amagic": -8, + "arange": 12, + "dmagic": 24, + "drange": 52 + } + }, + "11928": { + "name": "Odium shard 1", + "weight": 0.5 + }, + "11929": { + "name": "Odium shard 2", + "weight": 0.5 + }, + "11930": { + "name": "Odium shard 3", + "weight": 0.5 + }, + "11931": { + "name": "Malediction shard 1", + "weight": 0.5 + }, + "11932": { + "name": "Malediction shard 2", + "weight": 0.5 + }, + "11933": { + "name": "Malediction shard 3", + "weight": 0.5 + }, + "11934": { + "name": "Raw dark crab", + "weight": 0.3 + }, + "11936": { + "name": "Dark crab", + "weight": 0.3 + }, + "11938": { + "name": "Burnt dark crab" + }, + "11940": { + "name": "Dark fishing bait" + }, + "11941": { + "name": "Looting bag" + }, + "11942": { + "name": "Ecumenical key" + }, + "11943": { + "name": "Lava dragon bones", + "weight": 1.5 + }, + "11951": { + "name": "Extended antifire(4)" + }, + "11953": { + "name": "Extended antifire(3)" + }, + "11955": { + "name": "Extended antifire(2)" + }, + "11957": { + "name": "Extended antifire(1)" + }, + "11959": { + "name": "Black chinchompa", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 80, + "rstr": 30, + "aspeed": 4 + } + }, + "11960": { + "name": "Extended antifire mix(2)" + }, + "11962": { + "name": "Extended antifire mix(1)" + }, + "11964": { + "name": "Amulet of glory (t6)", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "11966": { + "name": "Amulet of glory (t5)", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "11968": { + "name": "Skills necklace(6)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11970": { + "name": "Skills necklace(5)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2 + } + }, + "11972": { + "name": "Combat bracelet(6)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11974": { + "name": "Combat bracelet(5)", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 3, + "arange": 7, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 3, + "drange": 5, + "str": 6 + } + }, + "11976": { + "name": "Amulet of glory(5)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "11978": { + "name": "Amulet of glory(6)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "11980": { + "name": "Ring of wealth (5)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11982": { + "name": "Ring of wealth (4)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11984": { + "name": "Ring of wealth (3)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11986": { + "name": "Ring of wealth (2)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11988": { + "name": "Ring of wealth (1)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "11990": { + "name": "Fedora", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "11992": { + "name": "Lava scale" + }, + "11994": { + "name": "Lava scale shard" + }, + "11996": { + "name": "Holiday tool" + }, + "11998": { + "name": "Smoke battlestaff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "12000": { + "name": "Mystic smoke staff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "12002": { + "name": "Occult necklace", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 2, + "amagic": 12, + "mdmg": 10, + "prayer": 2 + } + }, + "12004": { + "name": "Kraken tentacle" + }, + "12006": { + "name": "Abyssal tentacle", + "equipable": true, + "equipment": { + "slot": 3, + "aslash": 90, + "str": 86, + "aspeed": 4 + } + }, + "12007": { + "name": "Jar of dirt" + }, + "12009": { + "name": "Soft clay pack", + "weight": 4.0 + }, + "12010": { + "name": "Soft clay pack", + "weight": 4.0 + }, + "12011": { + "name": "Pay-dirt", + "weight": 1.33 + }, + "12012": { + "name": "Golden nugget" + }, + "12013": { + "name": "Prospector helmet", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "12014": { + "name": "Prospector jacket", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 4 + } + }, + "12015": { + "name": "Prospector legs", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 7 + } + }, + "12016": { + "name": "Prospector boots", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 10 + } + }, + "12017": { + "name": "Salve amulet(i)", + "quest": true, + "equipable": true, + "weight": 0.6, + "equipment": { + "slot": 2, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "prayer": 3 + } + }, + "12018": { + "name": "Salve amulet(ei)", + "equipable": true, + "weight": 0.6, + "equipment": { + "slot": 2, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "prayer": 3 + } + }, + "12019": { + "name": "Coal bag", + "weight": 10.0 + }, + "12020": { + "name": "Gem bag" + }, + "12021": { + "name": "Clue scroll (medium)" + }, + "12023": { + "name": "Clue scroll (medium)" + }, + "12025": { + "name": "Clue scroll (medium)" + }, + "12027": { + "name": "Clue scroll (medium)" + }, + "12029": { + "name": "Clue scroll (medium)" + }, + "12031": { + "name": "Clue scroll (medium)" + }, + "12033": { + "name": "Clue scroll (medium)" + }, + "12035": { + "name": "Clue scroll (medium)" + }, + "12037": { + "name": "Clue scroll (medium)" + }, + "12039": { + "name": "Clue scroll (medium)" + }, + "12041": { + "name": "Clue scroll (medium)" + }, + "12043": { + "name": "Clue scroll (medium)" + }, + "12045": { + "name": "Clue scroll (medium)" + }, + "12047": { + "name": "Clue scroll (medium)" + }, + "12049": { + "name": "Clue scroll (medium)" + }, + "12051": { + "name": "Clue scroll (medium)" + }, + "12053": { + "name": "Clue scroll (medium)" + }, + "12055": { + "name": "Clue scroll (medium)" + }, + "12056": { + "name": "Challenge scroll (medium)" + }, + "12057": { + "name": "Clue scroll (medium)" + }, + "12058": { + "name": "Challenge scroll (medium)" + }, + "12059": { + "name": "Clue scroll (medium)" + }, + "12060": { + "name": "Challenge scroll (medium)" + }, + "12061": { + "name": "Clue scroll (medium)" + }, + "12062": { + "name": "Challenge scroll (medium)" + }, + "12063": { + "name": "Clue scroll (medium)" + }, + "12064": { + "name": "Challenge scroll (medium)" + }, + "12065": { + "name": "Clue scroll (medium)" + }, + "12066": { + "name": "Challenge scroll (medium)" + }, + "12067": { + "name": "Clue scroll (medium)" + }, + "12068": { + "name": "Challenge scroll (medium)" + }, + "12069": { + "name": "Clue scroll (medium)" + }, + "12070": { + "name": "Challenge scroll (medium)" + }, + "12071": { + "name": "Clue scroll (medium)" + }, + "12072": { + "name": "Challenge scroll (medium)" + }, + "12073": { + "name": "Clue scroll (elite)" + }, + "12074": { + "name": "Clue scroll (elite)" + }, + "12075": { + "name": "Clue scroll (elite)" + }, + "12076": { + "name": "Clue scroll (elite)" + }, + "12077": { + "name": "Clue scroll (elite)" + }, + "12078": { + "name": "Clue scroll (elite)" + }, + "12079": { + "name": "Clue scroll (elite)" + }, + "12080": { + "name": "Clue scroll (elite)" + }, + "12081": { + "name": "Clue scroll (elite)" + }, + "12082": { + "name": "Clue scroll (elite)" + }, + "12083": { + "name": "Clue scroll (elite)" + }, + "12085": { + "name": "Clue scroll (elite)" + }, + "12086": { + "name": "Clue scroll (elite)" + }, + "12087": { + "name": "Clue scroll (elite)" + }, + "12088": { + "name": "Clue scroll (elite)" + }, + "12089": { + "name": "Clue scroll (elite)" + }, + "12090": { + "name": "Clue scroll (elite)" + }, + "12091": { + "name": "Clue scroll (elite)" + }, + "12092": { + "name": "Clue scroll (elite)" + }, + "12093": { + "name": "Clue scroll (elite)" + }, + "12094": { + "name": "Clue scroll (elite)" + }, + "12095": { + "name": "Clue scroll (elite)" + }, + "12096": { + "name": "Clue scroll (elite)" + }, + "12097": { + "name": "Clue scroll (elite)" + }, + "12098": { + "name": "Clue scroll (elite)" + }, + "12099": { + "name": "Clue scroll (elite)" + }, + "12100": { + "name": "Clue scroll (elite)" + }, + "12101": { + "name": "Clue scroll (elite)" + }, + "12102": { + "name": "Clue scroll (elite)" + }, + "12103": { + "name": "Clue scroll (elite)" + }, + "12104": { + "name": "Clue scroll (elite)" + }, + "12105": { + "name": "Clue scroll (elite)" + }, + "12106": { + "name": "Clue scroll (elite)" + }, + "12107": { + "name": "Clue scroll (elite)" + }, + "12108": { + "name": "Clue scroll (elite)" + }, + "12109": { + "name": "Clue scroll (elite)" + }, + "12110": { + "name": "Clue scroll (elite)" + }, + "12111": { + "name": "Clue scroll (elite)" + }, + "12113": { + "name": "Clue scroll (elite)" + }, + "12114": { + "name": "Clue scroll (elite)" + }, + "12115": { + "name": "Clue scroll (elite)" + }, + "12116": { + "name": "Clue scroll (elite)" + }, + "12117": { + "name": "Clue scroll (elite)" + }, + "12118": { + "name": "Clue scroll (elite)" + }, + "12119": { + "name": "Clue scroll (elite)" + }, + "12120": { + "name": "Clue scroll (elite)" + }, + "12121": { + "name": "Clue scroll (elite)" + }, + "12122": { + "name": "Clue scroll (elite)" + }, + "12123": { + "name": "Clue scroll (elite)" + }, + "12124": { + "name": "Clue scroll (elite)" + }, + "12125": { + "name": "Clue scroll (elite)" + }, + "12126": { + "name": "Clue scroll (elite)" + }, + "12127": { + "name": "Clue scroll (elite)" + }, + "12128": { + "name": "Challenge scroll (elite)" + }, + "12130": { + "name": "Clue scroll (elite)" + }, + "12132": { + "name": "Clue scroll (elite)" + }, + "12133": { + "name": "Clue scroll (elite)" + }, + "12134": { + "name": "Clue scroll (elite)" + }, + "12135": { + "name": "Clue scroll (elite)" + }, + "12136": { + "name": "Clue scroll (elite)" + }, + "12137": { + "name": "Clue scroll (elite)" + }, + "12138": { + "name": "Clue scroll (elite)" + }, + "12139": { + "name": "Challenge scroll (elite)" + }, + "12140": { + "name": "Clue scroll (elite)" + }, + "12141": { + "name": "Clue scroll (elite)" + }, + "12142": { + "name": "Clue scroll (elite)" + }, + "12143": { + "name": "Clue scroll (elite)" + }, + "12144": { + "name": "Clue scroll (elite)" + }, + "12145": { + "name": "Clue scroll (elite)" + }, + "12146": { + "name": "Clue scroll (elite)" + }, + "12147": { + "name": "Clue scroll (elite)" + }, + "12148": { + "name": "Clue scroll (elite)" + }, + "12149": { + "name": "Clue scroll (elite)" + }, + "12150": { + "name": "Clue scroll (elite)" + }, + "12151": { + "name": "Clue scroll (elite)" + }, + "12152": { + "name": "Clue scroll (elite)" + }, + "12153": { + "name": "Clue scroll (elite)" + }, + "12154": { + "name": "Clue scroll (elite)" + }, + "12155": { + "name": "Clue scroll (elite)" + }, + "12156": { + "name": "Clue scroll (elite)" + }, + "12157": { + "name": "Clue scroll (elite)" + }, + "12158": { + "name": "Clue scroll (elite)" + }, + "12159": { + "name": "Clue scroll (elite)" + }, + "12161": { + "name": "Puzzle box (elite)" + }, + "12162": { + "name": "Clue scroll (easy)" + }, + "12164": { + "name": "Clue scroll (easy)" + }, + "12166": { + "name": "Clue scroll (easy)" + }, + "12167": { + "name": "Clue scroll (easy)" + }, + "12168": { + "name": "Clue scroll (easy)" + }, + "12169": { + "name": "Clue scroll (easy)" + }, + "12170": { + "name": "Clue scroll (easy)" + }, + "12172": { + "name": "Clue scroll (easy)" + }, + "12173": { + "name": "Clue scroll (easy)" + }, + "12174": { + "name": "Clue scroll (easy)" + }, + "12175": { + "name": "Clue scroll (easy)" + }, + "12176": { + "name": "Clue scroll (easy)" + }, + "12177": { + "name": "Clue scroll (easy)" + }, + "12178": { + "name": "Clue scroll (easy)" + }, + "12179": { + "name": "Clue scroll (easy)" + }, + "12181": { + "name": "Clue scroll (easy)" + }, + "12182": { + "name": "Clue scroll (easy)" + }, + "12183": { + "name": "Clue scroll (easy)" + }, + "12184": { + "name": "Clue scroll (easy)" + }, + "12185": { + "name": "Clue scroll (easy)" + }, + "12186": { + "name": "Clue scroll (easy)" + }, + "12187": { + "name": "Clue scroll (easy)" + }, + "12188": { + "name": "Clue scroll (easy)" + }, + "12189": { + "name": "Clue scroll (easy)" + }, + "12190": { + "name": "Clue scroll (easy)" + }, + "12191": { + "name": "Clue scroll (easy)" + }, + "12192": { + "name": "Clue scroll (easy)" + }, + "12193": { + "name": "Ancient robe top", + "equipable": true, + "weight": 0.005, + "equipment": { + "slot": 4, + "amagic": 4, + "dmagic": 4, + "prayer": 6 + } + }, + "12195": { + "name": "Ancient robe legs", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "12197": { + "name": "Ancient cloak", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 3 + } + }, + "12199": { + "name": "Ancient crozier", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "12201": { + "name": "Ancient stole", + "equipable": true, + "equipment": { + "slot": 2, + "amagic": 2, + "dmagic": 2, + "prayer": 10 + } + }, + "12203": { + "name": "Ancient mitre", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "12205": { + "name": "Bronze platebody (g)", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 15, + "dslash": 14, + "dcrush": 9, + "dmagic": -6, + "drange": 14 + } + }, + "12207": { + "name": "Bronze platelegs (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 8, + "dslash": 7, + "dcrush": 6, + "dmagic": -4, + "drange": 7 + } + }, + "12209": { + "name": "Bronze plateskirt (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 8, + "dslash": 7, + "dcrush": 6, + "dmagic": -4, + "drange": 7 + } + }, + "12211": { + "name": "Bronze full helm (g)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "12213": { + "name": "Bronze kiteshield (g)", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 5, + "dslash": 7, + "dcrush": 6, + "dmagic": -1, + "drange": 6 + } + }, + "12215": { + "name": "Bronze platebody (t)", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 15, + "dslash": 14, + "dcrush": 9, + "dmagic": -6, + "drange": 14 + } + }, + "12217": { + "name": "Bronze platelegs (t)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 8, + "dslash": 7, + "dcrush": 6, + "dmagic": -4, + "drange": 7 + } + }, + "12219": { + "name": "Bronze plateskirt (t)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 8, + "dslash": 7, + "dcrush": 6, + "dmagic": -4, + "drange": 7 + } + }, + "12221": { + "name": "Bronze full helm (t)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "12223": { + "name": "Bronze kiteshield (t)", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 5, + "dslash": 7, + "dcrush": 6, + "dmagic": -1, + "drange": 6 + } + }, + "12225": { + "name": "Iron platebody (t)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "12227": { + "name": "Iron platelegs (t)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "12229": { + "name": "Iron plateskirt (t)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "12231": { + "name": "Iron full helm (t)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "12233": { + "name": "Iron kiteshield (t)", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 8, + "dslash": 10, + "dcrush": 9, + "dmagic": -1, + "drange": 9 + } + }, + "12235": { + "name": "Iron platebody (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "12237": { + "name": "Iron platelegs (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "12239": { + "name": "Iron plateskirt (g)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "12241": { + "name": "Iron full helm (g)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "12243": { + "name": "Iron kiteshield (g)", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 8, + "dslash": 10, + "dcrush": 9, + "dmagic": -1, + "drange": 9 + } + }, + "12245": { + "name": "Beanie", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12247": { + "name": "Red beret", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12249": { + "name": "Imp mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12251": { + "name": "Goblin mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12253": { + "name": "Armadyl robe top", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 4, + "amagic": 4, + "dmagic": 4, + "prayer": 6 + } + }, + "12255": { + "name": "Armadyl robe legs", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "12257": { + "name": "Armadyl stole", + "equipable": true, + "equipment": { + "slot": 2, + "amagic": 2, + "dmagic": 2, + "prayer": 10 + } + }, + "12259": { + "name": "Armadyl mitre", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "12261": { + "name": "Armadyl cloak", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 3 + } + }, + "12263": { + "name": "Armadyl crozier", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "12265": { + "name": "Bandos robe top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": 4, + "dmagic": 4, + "prayer": 6 + } + }, + "12267": { + "name": "Bandos robe legs", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "12269": { + "name": "Bandos stole", + "equipable": true, + "equipment": { + "slot": 2, + "amagic": 2, + "dmagic": 2, + "prayer": 10 + } + }, + "12271": { + "name": "Bandos mitre", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4, + "prayer": 5 + } + }, + "12273": { + "name": "Bandos cloak", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 3 + } + }, + "12275": { + "name": "Bandos crozier", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "12277": { + "name": "Mithril platebody (g)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 46, + "dslash": 44, + "dcrush": 38, + "dmagic": -6, + "drange": 44 + } + }, + "12279": { + "name": "Mithril platelegs (g)", + "equipable": true, + "weight": 7.7, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "12281": { + "name": "Mithril kiteshield (g)", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 18, + "dslash": 22, + "dcrush": 20, + "dmagic": -1, + "drange": 20 + } + }, + "12283": { + "name": "Mithril full helm (g)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 13, + "dslash": 14, + "dcrush": 11, + "dmagic": -1, + "drange": 13 + } + }, + "12285": { + "name": "Mithril plateskirt (g)", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "12287": { + "name": "Mithril platebody (t)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 46, + "dslash": 44, + "dcrush": 38, + "dmagic": -6, + "drange": 44 + } + }, + "12289": { + "name": "Mithril platelegs (t)", + "equipable": true, + "weight": 7.7, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "12291": { + "name": "Mithril kiteshield (t)", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 18, + "dslash": 22, + "dcrush": 20, + "dmagic": -1, + "drange": 20 + } + }, + "12293": { + "name": "Mithril full helm (t)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 13, + "dslash": 14, + "dcrush": 11, + "dmagic": -1, + "drange": 13 + } + }, + "12295": { + "name": "Mithril plateskirt (t)", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "12297": { + "name": "Black pickaxe", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -2, + "acrush": 8, + "dslash": 1, + "str": 11, + "aspeed": 5 + } + }, + "12299": { + "name": "White headband", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12301": { + "name": "Blue headband", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12303": { + "name": "Gold headband", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12305": { + "name": "Pink headband", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12307": { + "name": "Green headband", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12309": { + "name": "Pink boater", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12311": { + "name": "Purple boater", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12313": { + "name": "White boater", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12315": { + "name": "Pink elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "12317": { + "name": "Pink elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "12319": { + "name": "Crier hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12321": { + "name": "White cavalier", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12323": { + "name": "Red cavalier", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12325": { + "name": "Navy cavalier", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12327": { + "name": "Red d'hide body (g)", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 25, + "dstab": 50, + "dslash": 42, + "dcrush": 55, + "dmagic": 40, + "drange": 50 + } + }, + "12329": { + "name": "Red d'hide chaps (g)", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 14, + "dstab": 28, + "dslash": 22, + "dcrush": 30, + "dmagic": 20, + "drange": 28 + } + }, + "12331": { + "name": "Red d'hide body (t)", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 25, + "dstab": 50, + "dslash": 42, + "dcrush": 55, + "dmagic": 40, + "drange": 50 + } + }, + "12333": { + "name": "Red d'hide chaps (t)", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 14, + "dstab": 28, + "dslash": 22, + "dcrush": 30, + "dmagic": 20, + "drange": 28 + } + }, + "12335": { + "name": "Briefcase", + "equipable": true, + "equipment": { + "slot": 5 + } + }, + "12337": { + "name": "Sagacious spectacles", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12339": { + "name": "Pink elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "12341": { + "name": "Pink elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "12343": { + "name": "Gold elegant blouse", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "12345": { + "name": "Gold elegant skirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "12347": { + "name": "Gold elegant shirt", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "12349": { + "name": "Gold elegant legs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "12351": { + "name": "Musketeer hat", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "12353": { + "name": "Monocle", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12355": { + "name": "Big pirate hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12357": { + "name": "Katana", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "dstab": 3, + "dslash": 7, + "dcrush": 7, + "drange": -3, + "str": 40, + "aspeed": 4 + } + }, + "12359": { + "name": "Leprechaun hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12361": { + "name": "Cat mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12363": { + "name": "Bronze dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12365": { + "name": "Iron dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12367": { + "name": "Steel dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12369": { + "name": "Mithril dragon mask", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 0 + } + }, + "12371": { + "name": "Lava dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12373": { + "name": "Dragon cane", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 42, + "aslash": -2, + "acrush": 60, + "str": 55, + "prayer": 5, + "aspeed": 5 + } + }, + "12375": { + "name": "Black cane", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": -2, + "acrush": 16, + "str": 13, + "prayer": 2, + "aspeed": 5 + } + }, + "12377": { + "name": "Adamant cane", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 3, + "astab": 13, + "aslash": -2, + "acrush": 25, + "str": 23, + "prayer": 3, + "aspeed": 5 + } + }, + "12379": { + "name": "Rune cane", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": -2, + "acrush": 39, + "str": 36, + "prayer": 4, + "aspeed": 5 + } + }, + "12381": { + "name": "Black d'hide body (g)", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55 + } + }, + "12383": { + "name": "Black d'hide chaps (g)", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31 + } + }, + "12385": { + "name": "Black d'hide body (t)", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55 + } + }, + "12387": { + "name": "Black d'hide chaps (t)", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31 + } + }, + "12389": { + "name": "Gilded scimitar", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "12391": { + "name": "Gilded boots", + "equipable": true, + "weight": 1.3, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 12, + "dslash": 13, + "dcrush": 14, + "str": 2 + } + }, + "12393": { + "name": "Royal gown top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "12395": { + "name": "Royal gown bottom", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "12397": { + "name": "Royal crown", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12399": { + "name": "Partyhat & specs", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "12402": { + "name": "Nardah teleport" + }, + "12403": { + "name": "Digsite teleport" + }, + "12404": { + "name": "Feldip hills teleport" + }, + "12405": { + "name": "Lunar isle teleport" + }, + "12406": { + "name": "Mort'ton teleport" + }, + "12407": { + "name": "Pest control teleport" + }, + "12408": { + "name": "Piscatoris teleport" + }, + "12409": { + "name": "Tai bwo wannai teleport" + }, + "12410": { + "name": "Elf camp teleport" + }, + "12411": { + "name": "Mos le'harmless teleport" + }, + "12412": { + "name": "Pirate hat & patch", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "12414": { + "name": "Dragon chainbody (g)", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 81, + "dslash": 93, + "dcrush": 98, + "dmagic": -3, + "drange": 82 + } + }, + "12415": { + "name": "Dragon platelegs (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 68, + "dslash": 66, + "dcrush": 63, + "dmagic": -4, + "drange": 65 + } + }, + "12416": { + "name": "Dragon plateskirt (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 68, + "dslash": 66, + "dcrush": 63, + "dmagic": -4, + "drange": 65 + } + }, + "12417": { + "name": "Dragon full helm (g)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 45, + "dslash": 48, + "dcrush": 41, + "dmagic": -1, + "drange": 46 + } + }, + "12418": { + "name": "Dragon sq shield (g)", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 50, + "dslash": 52, + "dcrush": 48, + "drange": 50 + } + }, + "12419": { + "name": "Light infinity hat", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 6, + "dmagic": 6 + } + }, + "12420": { + "name": "Light infinity top", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 4, + "amagic": 22, + "dmagic": 22 + } + }, + "12421": { + "name": "Light infinity bottoms", + "equipable": true, + "equipment": { + "slot": 7, + "amagic": 17, + "dmagic": 17 + } + }, + "12422": { + "name": "3rd age wand", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "amagic": 20, + "dmagic": 20, + "aspeed": 4 + } + }, + "12424": { + "name": "3rd age bow", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "arange": 80, + "aspeed": 4 + } + }, + "12426": { + "name": "3rd age longsword", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "aslash": 72, + "acrush": 60, + "dslash": 3, + "dcrush": 2, + "str": 75, + "aspeed": 5 + } + }, + "12428": { + "name": "Penguin mask", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "12430": { + "name": "Afro", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 0 + } + }, + "12432": { + "name": "Top hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12434": { + "name": "Top hat & monocle", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "12436": { + "name": "Amulet of fury (or)", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 15, + "dslash": 15, + "dcrush": 15, + "dmagic": 15, + "drange": 15, + "str": 8, + "prayer": 5 + } + }, + "12437": { + "name": "3rd age cloak", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 5 + } + }, + "12439": { + "name": "Royal sceptre", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "12441": { + "name": "Musketeer tabard", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 4 + } + }, + "12443": { + "name": "Musketeer pants", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "12445": { + "name": "Black skirt (g)", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "12447": { + "name": "Black skirt (t)", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "12449": { + "name": "Black wizard robe (g)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": 3, + "dmagic": 3 + } + }, + "12451": { + "name": "Black wizard robe (t)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": 3, + "dmagic": 3 + } + }, + "12453": { + "name": "Black wizard hat (g)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "12455": { + "name": "Black wizard hat (t)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "12457": { + "name": "Dark infinity hat", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 6, + "dmagic": 6 + } + }, + "12458": { + "name": "Dark infinity top", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 4, + "amagic": 22, + "dmagic": 22 + } + }, + "12459": { + "name": "Dark infinity bottoms", + "equipable": true, + "equipment": { + "slot": 7, + "amagic": 17, + "dmagic": 17 + } + }, + "12460": { + "name": "Ancient platebody", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80, + "prayer": 1 + } + }, + "12462": { + "name": "Ancient platelegs", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "12464": { + "name": "Ancient plateskirt", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "12466": { + "name": "Ancient full helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30, + "prayer": 1 + } + }, + "12468": { + "name": "Ancient kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46, + "prayer": 1 + } + }, + "12470": { + "name": "Armadyl platebody", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80, + "prayer": 1 + } + }, + "12472": { + "name": "Armadyl platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "12474": { + "name": "Armadyl plateskirt", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "12476": { + "name": "Armadyl full helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30, + "prayer": 1 + } + }, + "12478": { + "name": "Armadyl kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46, + "prayer": 1 + } + }, + "12480": { + "name": "Bandos platebody", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80, + "prayer": 1 + } + }, + "12482": { + "name": "Bandos platelegs", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "12484": { + "name": "Bandos plateskirt", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49, + "prayer": 1 + } + }, + "12486": { + "name": "Bandos full helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30, + "prayer": 1 + } + }, + "12488": { + "name": "Bandos kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 44, + "dslash": 48, + "dcrush": 46, + "dmagic": -1, + "drange": 46, + "prayer": 1 + } + }, + "12490": { + "name": "Ancient bracers", + "equipable": true, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "prayer": 1 + } + }, + "12492": { + "name": "Ancient d'hide", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55, + "prayer": 1 + } + }, + "12494": { + "name": "Ancient chaps", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31, + "prayer": 1 + } + }, + "12496": { + "name": "Ancient coif", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 4, + "drange": 8, + "prayer": 1 + } + }, + "12498": { + "name": "Bandos bracers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "prayer": 1 + } + }, + "12500": { + "name": "Bandos d'hide", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55, + "prayer": 1 + } + }, + "12502": { + "name": "Bandos chaps", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31, + "prayer": 1 + } + }, + "12504": { + "name": "Bandos coif", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 4, + "drange": 8, + "prayer": 1 + } + }, + "12506": { + "name": "Armadyl bracers", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 6, + "dslash": 5, + "dcrush": 7, + "dmagic": 8, + "prayer": 1 + } + }, + "12508": { + "name": "Armadyl d'hide", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55, + "prayer": 1 + } + }, + "12510": { + "name": "Armadyl chaps", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31, + "prayer": 1 + } + }, + "12512": { + "name": "Armadyl coif", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 7, + "dstab": 4, + "dslash": 7, + "dcrush": 10, + "dmagic": 4, + "drange": 8, + "prayer": 1 + } + }, + "12514": { + "name": "Explorer backpack", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 1 + } + }, + "12516": { + "name": "Pith helmet", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "12518": { + "name": "Green dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12520": { + "name": "Blue dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12522": { + "name": "Red dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12524": { + "name": "Black dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "12526": { + "name": "Fury ornament kit" + }, + "12528": { + "name": "Dark infinity colour kit" + }, + "12530": { + "name": "Light infinity colour kit" + }, + "12532": { + "name": "Dragon sq shield ornament kit" + }, + "12534": { + "name": "Dragon chainbody ornament kit" + }, + "12536": { + "name": "Dragon legs/skirt ornament kit" + }, + "12538": { + "name": "Dragon full helm ornament kit" + }, + "12540": { + "name": "Deerstalker", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12542": { + "name": "Clue scroll (hard)" + }, + "12544": { + "name": "Clue scroll (hard)" + }, + "12546": { + "name": "Clue scroll (hard)" + }, + "12548": { + "name": "Clue scroll (hard)" + }, + "12550": { + "name": "Clue scroll (hard)" + }, + "12552": { + "name": "Clue scroll (hard)" + }, + "12554": { + "name": "Clue scroll (hard)" + }, + "12556": { + "name": "Clue scroll (hard)" + }, + "12558": { + "name": "Clue scroll (hard)" + }, + "12560": { + "name": "Clue scroll (hard)" + }, + "12562": { + "name": "Clue scroll (hard)" + }, + "12564": { + "name": "Clue scroll (hard)" + }, + "12566": { + "name": "Clue scroll (hard)" + }, + "12567": { + "name": "Challenge scroll (hard)" + }, + "12568": { + "name": "Clue scroll (hard)" + }, + "12569": { + "name": "Challenge scroll (hard)" + }, + "12570": { + "name": "Clue scroll (hard)" + }, + "12571": { + "name": "Challenge scroll (hard)" + }, + "12572": { + "name": "Clue scroll (hard)" + }, + "12573": { + "name": "Challenge scroll (hard)" + }, + "12574": { + "name": "Clue scroll (hard)" + }, + "12575": { + "name": "Challenge scroll (hard)" + }, + "12576": { + "name": "Clue scroll (hard)" + }, + "12577": { + "name": "Challenge scroll (hard)" + }, + "12578": { + "name": "Clue scroll (hard)" + }, + "12579": { + "name": "Puzzle box (hard)" + }, + "12581": { + "name": "Clue scroll (hard)" + }, + "12582": { + "name": "Puzzle box (hard)" + }, + "12584": { + "name": "Clue scroll (hard)" + }, + "12585": { + "name": "Puzzle box (hard)" + }, + "12587": { + "name": "Clue scroll (hard)" + }, + "12588": { + "name": "Puzzle box (hard)" + }, + "12590": { + "name": "Clue scroll (hard)" + }, + "12592": { + "name": "Black pick head" + }, + "12594": { + "name": "Broken pickaxe", + "weight": 1.814 + }, + "12596": { + "name": "Rangers' tunic", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 15, + "dstab": 6, + "dslash": 9, + "dcrush": 12, + "dmagic": 6, + "drange": 6 + } + }, + "12598": { + "name": "Holy sandals", + "equipable": true, + "equipment": { + "slot": 10, + "prayer": 3 + } + }, + "12600": { + "name": "Druidic wreath", + "equipable": true, + "weight": 0.7, + "equipment": { + "slot": 0 + } + }, + "12601": { + "name": "Ring of the gods", + "equipable": true, + "equipment": { + "slot": 12, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "prayer": 4 + } + }, + "12603": { + "name": "Tyrannical ring", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 12, + "acrush": 4, + "dcrush": 4 + } + }, + "12605": { + "name": "Treasonous ring", + "equipable": true, + "equipment": { + "slot": 12, + "astab": 4, + "dstab": 4 + } + }, + "12607": { + "name": "Damaged book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "prayer": 5 + } + }, + "12608": { + "name": "Book of war", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "str": 2, + "prayer": 5 + } + }, + "12609": { + "name": "Damaged book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "prayer": 5 + } + }, + "12610": { + "name": "Book of law", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "arange": 10, + "prayer": 5 + } + }, + "12611": { + "name": "Damaged book", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "prayer": 5 + } + }, + "12612": { + "name": "Book of darkness", + "quest": true, + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "amagic": 10, + "prayer": 5 + } + }, + "12613": { + "name": "Bandos page 1" + }, + "12614": { + "name": "Bandos page 2" + }, + "12615": { + "name": "Bandos page 3" + }, + "12616": { + "name": "Bandos page 4" + }, + "12617": { + "name": "Armadyl page 1" + }, + "12618": { + "name": "Armadyl page 2" + }, + "12619": { + "name": "Armadyl page 3" + }, + "12620": { + "name": "Armadyl page 4" + }, + "12621": { + "name": "Ancient page 1" + }, + "12622": { + "name": "Ancient page 2" + }, + "12623": { + "name": "Ancient page 3" + }, + "12624": { + "name": "Ancient page 4" + }, + "12625": { + "name": "Stamina potion(4)" + }, + "12627": { + "name": "Stamina potion(3)" + }, + "12629": { + "name": "Stamina potion(2)" + }, + "12631": { + "name": "Stamina potion(1)" + }, + "12633": { + "name": "Stamina mix(2)" + }, + "12635": { + "name": "Stamina mix(1)" + }, + "12637": { + "name": "Saradomin halo", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "dstab": 11, + "dslash": 12, + "dcrush": 10, + "dmagic": 11, + "drange": -1, + "prayer": 3 + } + }, + "12638": { + "name": "Zamorak halo", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "dstab": 11, + "dslash": 12, + "dcrush": 10, + "dmagic": 11, + "drange": -1, + "prayer": 3 + } + }, + "12639": { + "name": "Guthix halo", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "dstab": 11, + "dslash": 12, + "dcrush": 10, + "dmagic": 11, + "drange": -1, + "prayer": 3 + } + }, + "12640": { + "name": "Amylase crystal" + }, + "12641": { + "name": "Amylase pack" + }, + "12642": { + "name": "Lumberyard teleport" + }, + "12658": { + "name": "Iban's staff (u)", + "quest": true, + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "12691": { + "name": "Tyrannical ring (i)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 12, + "acrush": 8, + "dcrush": 8 + } + }, + "12692": { + "name": "Treasonous ring (i)", + "equipable": true, + "equipment": { + "slot": 12, + "astab": 8, + "dstab": 8 + } + }, + "12695": { + "name": "Super combat potion(4)" + }, + "12697": { + "name": "Super combat potion(3)" + }, + "12699": { + "name": "Super combat potion(2)" + }, + "12701": { + "name": "Super combat potion(1)" + }, + "12727": { + "name": "Event rpg", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "aspeed": 3 + } + }, + "12728": { + "name": "Air rune pack" + }, + "12730": { + "name": "Water rune pack" + }, + "12732": { + "name": "Earth rune pack" + }, + "12734": { + "name": "Fire rune pack" + }, + "12736": { + "name": "Mind rune pack" + }, + "12738": { + "name": "Chaos rune pack" + }, + "12740": { + "name": "Bird snare pack" + }, + "12742": { + "name": "Box trap pack" + }, + "12744": { + "name": "Magic imp box pack" + }, + "12746": { + "name": "Mysterious emblem" + }, + "12748": { + "name": "Mysterious emblem (tier 2)" + }, + "12749": { + "name": "Mysterious emblem (tier 3)" + }, + "12750": { + "name": "Mysterious emblem (tier 4)" + }, + "12751": { + "name": "Mysterious emblem (tier 5)" + }, + "12752": { + "name": "Mysterious emblem (tier 6)" + }, + "12753": { + "name": "Mysterious emblem (tier 7)" + }, + "12754": { + "name": "Mysterious emblem (tier 8)" + }, + "12755": { + "name": "Mysterious emblem (tier 9)" + }, + "12756": { + "name": "Mysterious emblem (tier 10)" + }, + "12757": { + "name": "Blue dark bow paint" + }, + "12759": { + "name": "Green dark bow paint" + }, + "12761": { + "name": "Yellow dark bow paint" + }, + "12763": { + "name": "White dark bow paint" + }, + "12765": { + "name": "Dark bow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 9 + } + }, + "12766": { + "name": "Dark bow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 9 + } + }, + "12767": { + "name": "Dark bow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 9 + } + }, + "12768": { + "name": "Dark bow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 9 + } + }, + "12769": { + "name": "Frozen whip mix" + }, + "12771": { + "name": "Volcanic whip mix" + }, + "12773": { + "name": "Volcanic abyssal whip", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 3, + "aslash": 82, + "str": 82, + "aspeed": 4 + } + }, + "12774": { + "name": "Frozen abyssal whip", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 3, + "aslash": 82, + "str": 82, + "aspeed": 4 + } + }, + "12775": { + "name": "Annakarl teleport" + }, + "12776": { + "name": "Carrallangar teleport" + }, + "12777": { + "name": "Dareeyak teleport" + }, + "12778": { + "name": "Ghorrock teleport" + }, + "12779": { + "name": "Kharyrll teleport" + }, + "12780": { + "name": "Lassar teleport" + }, + "12781": { + "name": "Paddewwa teleport" + }, + "12782": { + "name": "Senntisten teleport" + }, + "12783": { + "name": "Ring of wealth scroll" + }, + "12785": { + "name": "Ring of wealth (i)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "12786": { + "name": "Magic shortbow scroll" + }, + "12788": { + "name": "Magic shortbow (i)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "arange": 75, + "aspeed": 4 + } + }, + "12789": { + "name": "Clue box" + }, + "12791": { + "name": "Rune pouch", + "weight": 1.0 + }, + "12792": { + "name": "Nest box (empty)", + "weight": 1.0 + }, + "12793": { + "name": "Nest box (seeds)", + "weight": 1.0 + }, + "12794": { + "name": "Nest box (ring)", + "weight": 1.0 + }, + "12795": { + "name": "Steam battlestaff", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "12796": { + "name": "Mystic steam staff", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "12797": { + "name": "Dragon pickaxe", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": -2, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "12798": { + "name": "Steam staff upgrade kit" + }, + "12800": { + "name": "Dragon pickaxe upgrade kit" + }, + "12802": { + "name": "Ward upgrade kit" + }, + "12804": { + "name": "Saradomin's tear" + }, + "12806": { + "name": "Malediction ward", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 5, + "astab": -8, + "aslash": -8, + "acrush": -8, + "amagic": 12, + "arange": -12, + "dstab": 50, + "dslash": 52, + "dcrush": 48, + "dmagic": 15 + } + }, + "12807": { + "name": "Odium ward", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 5, + "astab": -12, + "aslash": -12, + "acrush": -12, + "amagic": -8, + "arange": 12, + "dmagic": 24, + "drange": 52 + } + }, + "12808": { + "name": "Sara's blessed sword (full)", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "aslash": 100, + "acrush": 60, + "str": 88, + "prayer": 2, + "aspeed": 4 + } + }, + "12809": { + "name": "Saradomin's blessed sword", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "aslash": 100, + "acrush": 60, + "str": 88, + "prayer": 2, + "aspeed": 4 + } + }, + "12810": { + "name": "Ironman helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "12811": { + "name": "Ironman platebody", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "12812": { + "name": "Ironman platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "12813": { + "name": "Ultimate ironman helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "12814": { + "name": "Ultimate ironman platebody", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "12815": { + "name": "Ultimate ironman platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "12817": { + "name": "Elysian spirit shield", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 5, + "dstab": 63, + "dslash": 65, + "dcrush": 75, + "dmagic": 2, + "drange": 57, + "prayer": 3 + } + }, + "12819": { + "name": "Elysian sigil", + "weight": 3.0 + }, + "12821": { + "name": "Spectral spirit shield", + "equipable": true, + "weight": 2.6, + "equipment": { + "slot": 5, + "dstab": 53, + "dslash": 55, + "dcrush": 73, + "dmagic": 30, + "drange": 52, + "prayer": 3 + } + }, + "12823": { + "name": "Spectral sigil", + "weight": 3.0 + }, + "12825": { + "name": "Arcane spirit shield", + "equipable": true, + "weight": 2.6, + "equipment": { + "slot": 5, + "amagic": 20, + "dstab": 53, + "dslash": 55, + "dcrush": 73, + "dmagic": 2, + "drange": 52, + "prayer": 3 + } + }, + "12827": { + "name": "Arcane sigil" + }, + "12829": { + "name": "Spirit shield", + "equipable": true, + "weight": 2.5, + "equipment": { + "slot": 5, + "dstab": 39, + "dslash": 41, + "dcrush": 50, + "dmagic": 1, + "drange": 45, + "prayer": 1 + } + }, + "12831": { + "name": "Blessed spirit shield", + "equipable": true, + "weight": 2.5, + "equipment": { + "slot": 5, + "dstab": 53, + "dslash": 55, + "dcrush": 73, + "dmagic": 2, + "drange": 52, + "prayer": 3 + } + }, + "12833": { + "name": "Holy elixir", + "weight": 2.0 + }, + "12836": { + "name": "Grim reaper's diary" + }, + "12837": { + "name": "Grim robe", + "weight": 1.0 + }, + "12838": { + "name": "Will and testament" + }, + "12839": { + "name": "Human bones", + "weight": 1.0 + }, + "12840": { + "name": "Servant's skull", + "weight": 1.0 + }, + "12841": { + "name": "Hourglass", + "weight": 1.0 + }, + "12842": { + "name": "Scythe sharpener", + "weight": 1.0 + }, + "12843": { + "name": "Human eye" + }, + "12844": { + "name": "Voice potion" + }, + "12845": { + "name": "Grim reaper hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12846": { + "name": "Bounty teleport scroll" + }, + "12848": { + "name": "Granite maul", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 3, + "acrush": 81, + "str": 79, + "aspeed": 7 + } + }, + "12849": { + "name": "Granite clamp" + }, + "12851": { + "name": "Amulet of the damned (full)", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "12853": { + "name": "Amulet of the damned", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "12854": { + "name": "Flamtaer bag", + "weight": 6.0 + }, + "12855": { + "name": "Hunter's honour" + }, + "12856": { + "name": "Rogue's revenge" + }, + "12857": { + "name": "Olive oil pack" + }, + "12859": { + "name": "Eye of newt pack" + }, + "12861": { + "name": "Thanksgiving dinner", + "weight": 0.2 + }, + "12862": { + "name": "Thanksgiving dinner", + "weight": 0.2 + }, + "12863": { + "name": "Dwarf cannon set" + }, + "12865": { + "name": "Green dragonhide set" + }, + "12867": { + "name": "Blue dragonhide set" + }, + "12869": { + "name": "Red dragonhide set" + }, + "12871": { + "name": "Black dragonhide set" + }, + "12873": { + "name": "Guthan's armour set" + }, + "12875": { + "name": "Verac's armour set" + }, + "12877": { + "name": "Dharok's armour set" + }, + "12879": { + "name": "Torag's armour set" + }, + "12881": { + "name": "Ahrim's armour set" + }, + "12883": { + "name": "Karil's armour set" + }, + "12885": { + "name": "Jar of sand" + }, + "12887": { + "name": "Santa mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12888": { + "name": "Santa jacket", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "12889": { + "name": "Santa pantaloons", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "12890": { + "name": "Santa gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "12891": { + "name": "Santa boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "12892": { + "name": "Antisanta mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "12893": { + "name": "Antisanta jacket", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "12894": { + "name": "Antisanta pantaloons", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "12895": { + "name": "Antisanta gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "12896": { + "name": "Antisanta boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "12897": { + "name": "Antisanta's coal box" + }, + "12898": { + "name": "Antisanta's coal box (full)" + }, + "12899": { + "name": "Trident of the swamp", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 25, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "12900": { + "name": "Uncharged toxic trident", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "12902": { + "name": "Toxic staff (uncharged)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 70, + "amagic": 17, + "dslash": 3, + "dcrush": 3, + "dmagic": 17, + "str": 72, + "mdmg": 15, + "aspeed": 4 + } + }, + "12904": { + "name": "Toxic staff of the dead", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 70, + "amagic": 25, + "dslash": 3, + "dcrush": 3, + "dmagic": 17, + "str": 72, + "mdmg": 15, + "aspeed": 4 + } + }, + "12905": { + "name": "Anti-venom(4)" + }, + "12907": { + "name": "Anti-venom(3)" + }, + "12909": { + "name": "Anti-venom(2)" + }, + "12911": { + "name": "Anti-venom(1)" + }, + "12913": { + "name": "Anti-venom+(4)" + }, + "12915": { + "name": "Anti-venom+(3)" + }, + "12917": { + "name": "Anti-venom+(2)" + }, + "12919": { + "name": "Anti-venom+(1)" + }, + "12922": { + "name": "Tanzanite fang" + }, + "12924": { + "name": "Toxic blowpipe (empty)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 60, + "aspeed": 3 + } + }, + "12926": { + "name": "Toxic blowpipe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 60, + "rstr": 40, + "aspeed": 3 + } + }, + "12927": { + "name": "Serpentine visage", + "weight": 1.0 + }, + "12929": { + "name": "Serpentine helm (uncharged)", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -5 + } + }, + "12931": { + "name": "Serpentine helm", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -5, + "dstab": 52, + "dslash": 55, + "dcrush": 58, + "drange": 50, + "str": 5 + } + }, + "12932": { + "name": "Magic fang" + }, + "12934": { + "name": "Zulrah's scales" + }, + "12935": { + "name": "Ohn's diary" + }, + "12936": { + "name": "Jar of swamp" + }, + "12938": { + "name": "Zul-andra teleport" + }, + "12954": { + "name": "Dragon defender", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 25, + "aslash": 24, + "acrush": 23, + "amagic": -3, + "arange": -2, + "dstab": 25, + "dslash": 24, + "dcrush": 23, + "dmagic": -3, + "drange": -2, + "str": 6 + } + }, + "12955": { + "name": "Free to play starter pack" + }, + "12956": { + "name": "Cow top", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 4 + } + }, + "12957": { + "name": "Cow trousers", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 7 + } + }, + "12958": { + "name": "Cow gloves", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 9 + } + }, + "12959": { + "name": "Cow shoes", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 10 + } + }, + "12960": { + "name": "Bronze set (lg)", + "weight": 6.0 + }, + "12962": { + "name": "Bronze set (sk)", + "weight": 6.0 + }, + "12964": { + "name": "Bronze trimmed set (lg)", + "weight": 6.0 + }, + "12966": { + "name": "Bronze trimmed set (sk)", + "weight": 6.0 + }, + "12968": { + "name": "Bronze gold-trimmed set (lg)", + "weight": 6.0 + }, + "12970": { + "name": "Bronze gold-trimmed set (sk)", + "weight": 6.0 + }, + "12972": { + "name": "Iron set (lg)", + "weight": 6.0 + }, + "12974": { + "name": "Iron set (sk)", + "weight": 6.0 + }, + "12976": { + "name": "Iron trimmed set (lg)", + "weight": 6.0 + }, + "12978": { + "name": "Iron trimmed set (sk)", + "weight": 6.0 + }, + "12980": { + "name": "Iron gold-trimmed set (lg)", + "weight": 6.0 + }, + "12982": { + "name": "Iron gold-trimmed set (sk)", + "weight": 6.0 + }, + "12984": { + "name": "Steel set (lg)", + "weight": 6.0 + }, + "12986": { + "name": "Steel set (sk)", + "weight": 6.0 + }, + "12988": { + "name": "Black set (lg)", + "weight": 6.0 + }, + "12990": { + "name": "Black set (sk)", + "weight": 6.0 + }, + "12992": { + "name": "Black trimmed set (lg)", + "weight": 6.0 + }, + "12994": { + "name": "Black trimmed set (sk)", + "weight": 6.0 + }, + "12996": { + "name": "Black gold-trimmed set (lg)", + "weight": 6.0 + }, + "12998": { + "name": "Black gold-trimmed set (sk)", + "weight": 6.0 + }, + "13000": { + "name": "Mithril set (lg)", + "weight": 6.0 + }, + "13002": { + "name": "Mithril set (sk)", + "weight": 6.0 + }, + "13004": { + "name": "Mithril trimmed set (lg)", + "weight": 6.0 + }, + "13006": { + "name": "Mithril trimmed set (sk)", + "weight": 6.0 + }, + "13008": { + "name": "Mithril gold-trimmed set (lg)", + "weight": 6.0 + }, + "13010": { + "name": "Mithril gold-trimmed set (sk)", + "weight": 6.0 + }, + "13012": { + "name": "Adamant set (lg)", + "weight": 6.0 + }, + "13014": { + "name": "Adamant set (sk)", + "weight": 6.0 + }, + "13016": { + "name": "Adamant trimmed set (lg)", + "weight": 6.0 + }, + "13018": { + "name": "Adamant trimmed set (sk)", + "weight": 6.0 + }, + "13020": { + "name": "Adamant gold-trimmed set (lg)", + "weight": 6.0 + }, + "13022": { + "name": "Adamant gold-trimmed set (sk)", + "weight": 6.0 + }, + "13024": { + "name": "Rune armour set (lg)", + "weight": 6.0 + }, + "13026": { + "name": "Rune armour set (sk)", + "weight": 6.0 + }, + "13028": { + "name": "Rune trimmed set (lg)", + "weight": 6.0 + }, + "13030": { + "name": "Rune trimmed set (sk)", + "weight": 6.0 + }, + "13032": { + "name": "Rune gold-trimmed set (lg)", + "weight": 6.0 + }, + "13034": { + "name": "Rune gold-trimmed set (sk)", + "weight": 6.0 + }, + "13036": { + "name": "Gilded armour set (lg)", + "weight": 6.0 + }, + "13038": { + "name": "Gilded armour set (sk)", + "weight": 6.0 + }, + "13040": { + "name": "Saradomin armour set (lg)", + "weight": 6.0 + }, + "13042": { + "name": "Saradomin armour set (sk)", + "weight": 6.0 + }, + "13044": { + "name": "Zamorak armour set (lg)", + "weight": 6.0 + }, + "13046": { + "name": "Zamorak armour set (sk)", + "weight": 6.0 + }, + "13048": { + "name": "Guthix armour set (lg)", + "weight": 6.0 + }, + "13050": { + "name": "Guthix armour set (sk)", + "weight": 6.0 + }, + "13052": { + "name": "Armadyl rune armour set (lg)", + "weight": 6.0 + }, + "13054": { + "name": "Armadyl rune armour set (sk)", + "weight": 6.0 + }, + "13056": { + "name": "Bandos rune armour set (lg)", + "weight": 6.0 + }, + "13058": { + "name": "Bandos rune armour set (sk)", + "weight": 6.0 + }, + "13060": { + "name": "Ancient rune armour set (lg)", + "weight": 6.0 + }, + "13062": { + "name": "Ancient rune armour set (sk)", + "weight": 6.0 + }, + "13064": { + "name": "Combat potion set" + }, + "13066": { + "name": "Super potion set" + }, + "13068": { + "name": "Quest point cape (t)", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "13069": { + "name": "Achievement diary cape (t)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "13070": { + "name": "Achievement diary hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13072": { + "name": "Elite void top", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "dstab": 45, + "dslash": 45, + "dcrush": 45, + "dmagic": 45, + "drange": 45, + "prayer": 3 + } + }, + "13073": { + "name": "Elite void robe", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 7, + "dstab": 30, + "dslash": 30, + "dcrush": 30, + "dmagic": 30, + "drange": 30, + "prayer": 3 + } + }, + "13074": { + "name": "Pharaoh's sceptre (8)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "13075": { + "name": "Pharaoh's sceptre (7)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "13076": { + "name": "Pharaoh's sceptre (6)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "13077": { + "name": "Pharaoh's sceptre (5)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "13078": { + "name": "Pharaoh's sceptre (4)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "aspeed": 4 + } + }, + "13079": { + "name": "Enchanted lyre(5)", + "quest": true, + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "13080": { + "name": "New crystal halberd full (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13081": { + "name": "Crystal halberd full (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13082": { + "name": "Crystal halberd 9/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13083": { + "name": "Crystal halberd 8/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13084": { + "name": "Crystal halberd 7/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13085": { + "name": "Crystal halberd 6/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13086": { + "name": "Crystal halberd 5/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13087": { + "name": "Crystal halberd 4/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13088": { + "name": "Crystal halberd 3/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13089": { + "name": "Crystal halberd 2/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13090": { + "name": "Crystal halberd 1/10 (i)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13091": { + "name": "New crystal halberd full", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13092": { + "name": "Crystal halberd full", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 110, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 118, + "aspeed": 7 + } + }, + "13093": { + "name": "Crystal halberd 9/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 82, + "aslash": 106, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 113, + "aspeed": 7 + } + }, + "13094": { + "name": "Crystal halberd 8/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 79, + "aslash": 102, + "acrush": 5, + "amagic": -4, + "dstab": -1, + "dslash": 4, + "dcrush": 5, + "str": 108, + "aspeed": 7 + } + }, + "13095": { + "name": "Crystal halberd 7/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 76, + "aslash": 98, + "acrush": 4, + "amagic": -4, + "dstab": -1, + "dslash": 3, + "dcrush": 4, + "str": 103, + "aspeed": 7 + } + }, + "13096": { + "name": "Crystal halberd 6/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 73, + "aslash": 94, + "acrush": 4, + "amagic": -4, + "dstab": -1, + "dslash": 3, + "dcrush": 4, + "str": 98, + "aspeed": 7 + } + }, + "13097": { + "name": "Crystal halberd 5/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 70, + "aslash": 90, + "acrush": 4, + "amagic": -4, + "dstab": -1, + "dslash": 3, + "dcrush": 4, + "str": 93, + "aspeed": 7 + } + }, + "13098": { + "name": "Crystal halberd 4/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 67, + "aslash": 86, + "acrush": 3, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 3, + "str": 88, + "aspeed": 7 + } + }, + "13099": { + "name": "Crystal halberd 3/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 64, + "aslash": 82, + "acrush": 3, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 3, + "str": 83, + "aspeed": 7 + } + }, + "13100": { + "name": "Crystal halberd 2/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 61, + "aslash": 78, + "acrush": 3, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 3, + "str": 78, + "aspeed": 7 + } + }, + "13101": { + "name": "Crystal halberd 1/10", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 58, + "aslash": 74, + "acrush": 2, + "amagic": -4, + "dstab": -1, + "dslash": 1, + "dcrush": 2, + "str": 73, + "aspeed": 7 + } + }, + "13102": { + "name": "Teleport crystal (5)" + }, + "13103": { + "name": "Karamja gloves 4", + "equipable": true, + "equipment": { + "slot": 9, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 1 + } + }, + "13104": { + "name": "Varrock armour 1", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 32, + "dslash": 31, + "dcrush": 24, + "dmagic": -6, + "drange": 31 + } + }, + "13105": { + "name": "Varrock armour 2", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "13106": { + "name": "Varrock armour 3", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 46, + "dslash": 44, + "dcrush": 38, + "dmagic": -6, + "drange": 44 + } + }, + "13107": { + "name": "Varrock armour 4", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "13108": { + "name": "Wilderness sword 1", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 6, + "aslash": 4, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 7, + "aspeed": 4 + } + }, + "13109": { + "name": "Wilderness sword 2", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 8, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 12, + "aspeed": 4 + } + }, + "13110": { + "name": "Wilderness sword 3", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 16, + "aslash": 11, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 17, + "aspeed": 4 + } + }, + "13111": { + "name": "Wilderness sword 4", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 23, + "aslash": 18, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 24, + "aspeed": 4 + } + }, + "13112": { + "name": "Morytania legs 1", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "13113": { + "name": "Morytania legs 2", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "13114": { + "name": "Morytania legs 3", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 24, + "dslash": 22, + "dcrush": 20, + "dmagic": -4, + "drange": 22 + } + }, + "13115": { + "name": "Morytania legs 4", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "13116": { + "name": "Bonecrusher" + }, + "13117": { + "name": "Falador shield 1", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 8, + "dslash": 10, + "dcrush": 9, + "dmagic": -1, + "drange": 9, + "prayer": 1 + } + }, + "13118": { + "name": "Falador shield 2", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14, + "prayer": 3 + } + }, + "13119": { + "name": "Falador shield 3", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 18, + "dslash": 22, + "dcrush": 20, + "dmagic": -1, + "drange": 20, + "prayer": 4 + } + }, + "13120": { + "name": "Falador shield 4", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29, + "prayer": 5 + } + }, + "13121": { + "name": "Ardougne cloak 1", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "astab": 2, + "amagic": 2, + "dstab": 2, + "dmagic": 2, + "prayer": 2 + } + }, + "13122": { + "name": "Ardougne cloak 2", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "astab": 4, + "amagic": 4, + "dstab": 4, + "dmagic": 4, + "prayer": 4 + } + }, + "13123": { + "name": "Ardougne cloak 3", + "equipable": true, + "equipment": { + "slot": 1, + "astab": 5, + "amagic": 5, + "dstab": 5, + "dmagic": 5, + "prayer": 5 + } + }, + "13124": { + "name": "Ardougne cloak 4", + "equipable": true, + "equipment": { + "slot": 1, + "astab": 6, + "amagic": 6, + "dstab": 6, + "dmagic": 6, + "prayer": 6 + } + }, + "13125": { + "name": "Explorer's ring 1", + "equipable": true, + "equipment": { + "slot": 12, + "prayer": 1 + } + }, + "13126": { + "name": "Explorer's ring 2", + "equipable": true, + "equipment": { + "slot": 12, + "prayer": 1 + } + }, + "13127": { + "name": "Explorer's ring 3", + "equipable": true, + "equipment": { + "slot": 12, + "prayer": 1 + } + }, + "13128": { + "name": "Explorer's ring 4", + "equipable": true, + "equipment": { + "slot": 12, + "prayer": 1 + } + }, + "13129": { + "name": "Fremennik sea boots 1", + "equipable": true, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 2, + "dslash": 3, + "dcrush": 4 + } + }, + "13130": { + "name": "Fremennik sea boots 2", + "equipable": true, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 5, + "dslash": 6, + "dcrush": 7 + } + }, + "13131": { + "name": "Fremennik sea boots 3", + "equipable": true, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 9 + } + }, + "13132": { + "name": "Fremennik sea boots 4", + "equipable": true, + "equipment": { + "slot": 10, + "amagic": 1, + "arange": 1, + "dstab": 10, + "dslash": 11, + "dcrush": 12, + "str": 1 + } + }, + "13133": { + "name": "Desert amulet 1", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "13134": { + "name": "Desert amulet 2", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "13135": { + "name": "Desert amulet 3", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "13136": { + "name": "Desert amulet 4", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "13137": { + "name": "Kandarin headgear 1", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": -1, + "drange": 4 + } + }, + "13138": { + "name": "Kandarin headgear 2", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "13139": { + "name": "Kandarin headgear 3", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 9, + "dslash": 10, + "dcrush": 8, + "dmagic": -1, + "drange": 9 + } + }, + "13140": { + "name": "Kandarin headgear 4", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 10, + "dslash": 11, + "dcrush": 9, + "dmagic": -1, + "drange": 10 + } + }, + "13141": { + "name": "Western banner 1", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "13142": { + "name": "Western banner 2", + "weight": 2.0 + }, + "13143": { + "name": "Western banner 3", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 17, + "aslash": 17, + "acrush": 17, + "dstab": 1, + "dslash": 1, + "str": 18, + "aspeed": 5 + } + }, + "13144": { + "name": "Western banner 4", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 24, + "acrush": 24, + "dstab": 1, + "dslash": 1, + "str": 28, + "aspeed": 5 + } + }, + "13145": { + "name": "Antique lamp", + "quest": true + }, + "13146": { + "name": "Antique lamp", + "quest": true + }, + "13147": { + "name": "Antique lamp", + "quest": true + }, + "13148": { + "name": "Antique lamp", + "quest": true + }, + "13149": { + "name": "Holy book page set" + }, + "13151": { + "name": "Unholy book page set" + }, + "13153": { + "name": "Book of balance page set" + }, + "13155": { + "name": "Book of war page set" + }, + "13157": { + "name": "Book of law page set" + }, + "13159": { + "name": "Book of darkness page set" + }, + "13161": { + "name": "Zamorak dragonhide set" + }, + "13163": { + "name": "Saradomin dragonhide set" + }, + "13165": { + "name": "Guthix dragonhide set" + }, + "13167": { + "name": "Bandos dragonhide set" + }, + "13169": { + "name": "Armadyl dragonhide set" + }, + "13171": { + "name": "Ancient dragonhide set" + }, + "13173": { + "name": "Partyhat set" + }, + "13175": { + "name": "Halloween mask set" + }, + "13182": { + "name": "Bunny feet", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13183": { + "name": "Empty blaster", + "equipable": true, + "equipment": { + "slot": 3 + } + }, + "13184": { + "name": "Incomplete blaster", + "equipable": true, + "equipment": { + "slot": 3 + } + }, + "13185": { + "name": "Easter blaster", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "13186": { + "name": "Volatile mineral", + "equipable": true + }, + "13187": { + "name": "Package" + }, + "13188": { + "name": "Diango's claws" + }, + "13190": { + "name": "Old school bond" + }, + "13192": { + "name": "Old school bond (untradeable)" + }, + "13193": { + "name": "Bone bolt pack" + }, + "13195": { + "name": "Oddskull", + "equipable": true, + "equipment": { + "slot": 3 + } + }, + "13196": { + "name": "Tanzanite helm (uncharged)" + }, + "13197": { + "name": "Tanzanite helm", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -5, + "dstab": 52, + "dslash": 55, + "dcrush": 58, + "drange": 50, + "str": 5 + } + }, + "13198": { + "name": "Magma helm (uncharged)" + }, + "13199": { + "name": "Magma helm", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -5, + "dstab": 52, + "dslash": 55, + "dcrush": 58, + "drange": 50, + "str": 5 + } + }, + "13200": { + "name": "Tanzanite mutagen" + }, + "13201": { + "name": "Magma mutagen" + }, + "13202": { + "name": "Ring of the gods (i)", + "equipable": true, + "equipment": { + "slot": 12, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "prayer": 8 + } + }, + "13203": { + "name": "Mask of balance", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 0 + } + }, + "13204": { + "name": "Platinum token" + }, + "13205": { + "name": "Rotten egg" + }, + "13215": { + "name": "Tiger toy" + }, + "13216": { + "name": "Lion toy" + }, + "13217": { + "name": "Snow leopard toy" + }, + "13218": { + "name": "Amur leopard toy" + }, + "13221": { + "name": "Music cape", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "13222": { + "name": "Music cape(t)", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "13223": { + "name": "Music hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13226": { + "name": "Herb sack", + "weight": 1.0 + }, + "13227": { + "name": "Eternal crystal" + }, + "13229": { + "name": "Pegasian crystal" + }, + "13231": { + "name": "Primordial crystal" + }, + "13233": { + "name": "Smouldering stone" + }, + "13235": { + "name": "Eternal boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": 8, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 8, + "drange": 5 + } + }, + "13237": { + "name": "Pegasian boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -12, + "arange": 12, + "dstab": 5, + "dslash": 5, + "dcrush": 5, + "dmagic": 5, + "drange": 5 + } + }, + "13239": { + "name": "Primordial boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "astab": 2, + "aslash": 2, + "acrush": 2, + "amagic": -4, + "arange": -1, + "dstab": 22, + "dslash": 22, + "dcrush": 22, + "str": 5 + } + }, + "13241": { + "name": "Infernal axe", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 38, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "13242": { + "name": "Infernal axe (uncharged)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 38, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "13243": { + "name": "Infernal pickaxe", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": -2, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "13244": { + "name": "Infernal pickaxe (uncharged)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": -2, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "13245": { + "name": "Jar of souls" + }, + "13249": { + "name": "Key master teleport" + }, + "13250": { + "name": "Plant pot pack" + }, + "13252": { + "name": "Sack pack" + }, + "13254": { + "name": "Basket pack" + }, + "13256": { + "name": "Saradomin's light" + }, + "13258": { + "name": "Angler hat", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "13259": { + "name": "Angler top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "13260": { + "name": "Angler waders", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "13261": { + "name": "Angler boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10 + } + }, + "13263": { + "name": "Abyssal bludgeon", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 3, + "acrush": 102, + "str": 85, + "aspeed": 4 + } + }, + "13265": { + "name": "Abyssal dagger", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 40, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 75, + "aspeed": 4 + } + }, + "13267": { + "name": "Abyssal dagger (p)", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 40, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 75, + "aspeed": 4 + } + }, + "13269": { + "name": "Abyssal dagger (p+)", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 40, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 75, + "aspeed": 4 + } + }, + "13271": { + "name": "Abyssal dagger (p++)", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 75, + "aslash": 40, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 75, + "aspeed": 4 + } + }, + "13273": { + "name": "Unsired", + "weight": 1.0 + }, + "13274": { + "name": "Bludgeon spine", + "weight": 2.0 + }, + "13275": { + "name": "Bludgeon claw", + "weight": 2.0 + }, + "13276": { + "name": "Bludgeon axon", + "weight": 2.0 + }, + "13277": { + "name": "Jar of miasma" + }, + "13279": { + "name": "Overseer's book" + }, + "13280": { + "name": "Max cape", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "13281": { + "name": "Max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "13283": { + "name": "Gravedigger mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13284": { + "name": "Gravedigger top", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4 + } + }, + "13285": { + "name": "Gravedigger leggings", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7 + } + }, + "13286": { + "name": "Gravedigger boots", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 10 + } + }, + "13287": { + "name": "Gravedigger gloves", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 9 + } + }, + "13288": { + "name": "Anti-panties" + }, + "13302": { + "name": "Bank key" + }, + "13303": { + "name": "Bank key" + }, + "13304": { + "name": "Bank key" + }, + "13305": { + "name": "Bank key" + }, + "13306": { + "name": "Bank key" + }, + "13307": { + "name": "Blood money" + }, + "13317": { + "name": "Deadman's chest", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "13318": { + "name": "Deadman's legs", + "equipable": true, + "weight": 9.5, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "13319": { + "name": "Deadman's cape", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "13327": { + "name": "Rotten onion" + }, + "13328": { + "name": "Green banner", + "weight": 2.0 + }, + "13329": { + "name": "Fire max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 11, + "dslash": 11, + "dcrush": 11, + "dmagic": 11, + "drange": 11, + "str": 4, + "prayer": 2 + } + }, + "13330": { + "name": "Fire max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "13331": { + "name": "Saradomin max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 10 + } + }, + "13332": { + "name": "Saradomin max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "13333": { + "name": "Zamorak max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 10 + } + }, + "13334": { + "name": "Zamorak max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "13335": { + "name": "Guthix max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 10 + } + }, + "13336": { + "name": "Guthix max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "13337": { + "name": "Accumulator max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "arange": 4, + "dslash": 1, + "dmagic": 4 + } + }, + "13338": { + "name": "Accumulator max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "13339": { + "name": "Sacred eel" + }, + "13340": { + "name": "Agility cape", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "13341": { + "name": "Agility cape(t)", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "13342": { + "name": "Max cape", + "equipable": true, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "13343": { + "name": "Black santa hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13344": { + "name": "Inverted santa hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13345": { + "name": "Anti-present", + "weight": 1.0 + }, + "13346": { + "name": "Present", + "weight": 1.0 + }, + "13347": { + "name": "Vial of tears (empty)" + }, + "13348": { + "name": "Vial of tears (1)" + }, + "13349": { + "name": "Vial of tears (2)" + }, + "13350": { + "name": "Vial of tears (3)" + }, + "13351": { + "name": "Vial of tears (full)" + }, + "13352": { + "name": "Vial of sorrow" + }, + "13353": { + "name": "Gricoller's can", + "weight": 1.0 + }, + "13354": { + "name": "Lovakite bar", + "weight": 1.25 + }, + "13355": { + "name": "Juniper logs", + "weight": 1.0 + }, + "13356": { + "name": "Lovakite ore", + "weight": 2.0 + }, + "13357": { + "name": "Shayzien gloves (1)", + "equipable": true, + "equipment": { + "slot": 9, + "amagic": -1, + "dcrush": 1, + "dmagic": -1 + } + }, + "13358": { + "name": "Shayzien boots (1)", + "equipable": true, + "equipment": { + "slot": 10, + "amagic": -2, + "arange": -1, + "dstab": 1, + "dslash": 2, + "dcrush": 3 + } + }, + "13359": { + "name": "Shayzien helm (1)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -2, + "dstab": 3, + "dslash": 5, + "dcrush": 4, + "dmagic": -1, + "drange": 5 + } + }, + "13360": { + "name": "Shayzien greaves (1)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": -2, + "dstab": 10, + "dslash": 9, + "dcrush": 8, + "dmagic": -2, + "drange": 10 + } + }, + "13361": { + "name": "Shayzien platebody (1)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -5, + "dstab": 16, + "dslash": 20, + "dcrush": 22, + "dmagic": -2, + "drange": 16 + } + }, + "13362": { + "name": "Shayzien gloves (2)", + "equipable": true, + "equipment": { + "slot": 9, + "acrush": 1, + "amagic": -1, + "dcrush": 1, + "dmagic": -1, + "str": 1 + } + }, + "13363": { + "name": "Shayzien boots (2)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -2, + "arange": -1, + "dstab": 2, + "dslash": 3, + "dcrush": 4 + } + }, + "13364": { + "name": "Shayzien helm (2)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": -2, + "dstab": 5, + "dslash": 8, + "dcrush": 6, + "dmagic": -1, + "drange": 7 + } + }, + "13365": { + "name": "Shayzien greaves (2)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -14, + "arange": -3, + "dstab": 14, + "dslash": 13, + "dcrush": 12, + "dmagic": -3, + "drange": 14 + } + }, + "13366": { + "name": "Shayzien platebody (2)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -7, + "dstab": 20, + "dslash": 25, + "dcrush": 30, + "dmagic": -3, + "drange": 20 + } + }, + "13367": { + "name": "Shayzien gloves (3)", + "equipable": true, + "equipment": { + "slot": 9, + "acrush": 2, + "amagic": -1, + "dcrush": 1, + "dmagic": -1, + "str": 2 + } + }, + "13368": { + "name": "Shayzien boots (3)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -2, + "arange": -1, + "dstab": 4, + "dslash": 5, + "dcrush": 6 + } + }, + "13369": { + "name": "Shayzien helm (3)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 7, + "dslash": 10, + "dcrush": 8, + "dmagic": -2, + "drange": 9 + } + }, + "13370": { + "name": "Shayzien greaves (3)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -17, + "arange": -4, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -3, + "drange": 17 + } + }, + "13371": { + "name": "Shayzien platebody (3)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -8, + "dstab": 25, + "dslash": 32, + "dcrush": 35, + "dmagic": -3, + "drange": 22 + } + }, + "13372": { + "name": "Shayzien gloves (4)", + "equipable": true, + "equipment": { + "slot": 9, + "acrush": 2, + "amagic": -1, + "dslash": 1, + "dcrush": 2, + "dmagic": -1, + "drange": 1, + "str": 2 + } + }, + "13373": { + "name": "Shayzien boots (4)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -2, + "arange": -1, + "dstab": 5, + "dslash": 6, + "dcrush": 7 + } + }, + "13374": { + "name": "Shayzien helm (4)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 8, + "dslash": 12, + "dcrush": 10, + "dmagic": -2, + "drange": 11 + } + }, + "13375": { + "name": "Shayzien greaves (4)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -20, + "arange": -5, + "dstab": 20, + "dslash": 19, + "dcrush": 18, + "dmagic": -4, + "drange": 20 + } + }, + "13376": { + "name": "Shayzien platebody (4)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -9, + "dstab": 28, + "dslash": 35, + "dcrush": 37, + "dmagic": -4, + "drange": 25 + } + }, + "13377": { + "name": "Shayzien gloves (5)", + "equipable": true, + "equipment": { + "slot": 9, + "acrush": 2, + "amagic": -1, + "dslash": 2, + "dcrush": 3, + "dmagic": -1, + "drange": 2, + "str": 3 + } + }, + "13378": { + "name": "Shayzien boots (5)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -2, + "arange": -1, + "dstab": 5, + "dslash": 7, + "dcrush": 8 + } + }, + "13379": { + "name": "Shayzien helm (5)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 10, + "dslash": 14, + "dcrush": 12, + "dmagic": -2, + "drange": 13 + } + }, + "13380": { + "name": "Shayzien greaves (5)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -20, + "arange": -5, + "dstab": 23, + "dslash": 22, + "dcrush": 21, + "dmagic": -4, + "drange": 23 + } + }, + "13381": { + "name": "Shayzien platebody (5)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "amagic": -10, + "dstab": 30, + "dslash": 37, + "dcrush": 40, + "dmagic": -4, + "drange": 27 + } + }, + "13382": { + "name": "Shayzien medpack" + }, + "13383": { + "name": "Xerician fabric" + }, + "13385": { + "name": "Xerician hat", + "equipable": true, + "equipment": { + "slot": 0, + "amagic": 3, + "dmagic": 3 + } + }, + "13387": { + "name": "Xerician top", + "equipable": true, + "equipment": { + "slot": 4, + "amagic": 12, + "dmagic": 10 + } + }, + "13389": { + "name": "Xerician robe", + "equipable": true, + "equipment": { + "slot": 7, + "amagic": 8, + "dmagic": 7 + } + }, + "13391": { + "name": "Lizardman fang" + }, + "13392": { + "name": "Xeric's talisman (inert)", + "equipable": true, + "weight": 0.05, + "equipment": { + "slot": 2, + "amagic": 2 + } + }, + "13393": { + "name": "Xeric's talisman", + "equipable": true, + "weight": 0.05, + "equipment": { + "slot": 2, + "amagic": 3, + "dmagic": 1 + } + }, + "13394": { + "name": "Gang meeting info" + }, + "13395": { + "name": "Intelligence" + }, + "13396": { + "name": "Training manual" + }, + "13397": { + "name": "Servery flour", + "weight": 1.0 + }, + "13398": { + "name": "Servery pastry dough" + }, + "13399": { + "name": "Servery raw meat", + "weight": 0.3 + }, + "13400": { + "name": "Servery dish", + "weight": 0.1 + }, + "13401": { + "name": "Servery pie shell", + "weight": 0.25 + }, + "13402": { + "name": "Servery uncooked pie" + }, + "13403": { + "name": "Servery meat pie", + "weight": 0.45 + }, + "13404": { + "name": "Servery pizza base" + }, + "13405": { + "name": "Servery tomato" + }, + "13406": { + "name": "Servery incomplete pizza", + "weight": 0.6 + }, + "13407": { + "name": "Servery cheese" + }, + "13408": { + "name": "Servery uncooked pizza" + }, + "13409": { + "name": "Servery plain pizza", + "weight": 0.8 + }, + "13410": { + "name": "Servery pineapple" + }, + "13411": { + "name": "Servery pineapple chunks" + }, + "13412": { + "name": "Servery pineapple pizza", + "weight": 0.9 + }, + "13413": { + "name": "Servery cooked meat", + "weight": 0.25 + }, + "13414": { + "name": "Servery potato", + "weight": 0.5 + }, + "13415": { + "name": "Servery incomplete stew", + "weight": 1.0 + }, + "13416": { + "name": "Servery incomplete stew", + "weight": 1.0 + }, + "13417": { + "name": "Servery uncooked stew" + }, + "13418": { + "name": "Servery stew", + "weight": 1.5 + }, + "13419": { + "name": "Sulphurous fertiliser", + "weight": 3.0 + }, + "13420": { + "name": "Gricoller's fertiliser", + "equipable": true, + "weight": 4.0 + }, + "13421": { + "name": "Saltpetre" + }, + "13423": { + "name": "Golovanova seed" + }, + "13424": { + "name": "Bologano seed" + }, + "13425": { + "name": "Logavano seed" + }, + "13426": { + "name": "Golovanova fruit" + }, + "13427": { + "name": "Bologano fruit" + }, + "13428": { + "name": "Logavano fruit" + }, + "13429": { + "name": "Fresh fish" + }, + "13430": { + "name": "Bucket of sandworms", + "weight": 2.0 + }, + "13431": { + "name": "Sandworms" + }, + "13432": { + "name": "Sandworms pack" + }, + "13434": { + "name": "Stolen pendant" + }, + "13435": { + "name": "Stolen garnet ring" + }, + "13436": { + "name": "Stolen circlet" + }, + "13437": { + "name": "Stolen family heirloom" + }, + "13438": { + "name": "Stolen jewelry box" + }, + "13439": { + "name": "Raw anglerfish", + "weight": 0.33 + }, + "13441": { + "name": "Anglerfish", + "weight": 0.33 + }, + "13443": { + "name": "Burnt anglerfish", + "weight": 0.33 + }, + "13445": { + "name": "Dense essence block" + }, + "13446": { + "name": "Dark essence block" + }, + "13447": { + "name": "Ensouled goblin head", + "weight": 0.4 + }, + "13448": { + "name": "Ensouled goblin head", + "weight": 0.4 + }, + "13450": { + "name": "Ensouled monkey head", + "weight": 0.4 + }, + "13451": { + "name": "Ensouled monkey head", + "weight": 0.4 + }, + "13453": { + "name": "Ensouled imp head", + "weight": 0.4 + }, + "13454": { + "name": "Ensouled imp head", + "weight": 0.4 + }, + "13456": { + "name": "Ensouled minotaur head" + }, + "13457": { + "name": "Ensouled minotaur head" + }, + "13459": { + "name": "Ensouled scorpion head" + }, + "13460": { + "name": "Ensouled scorpion head" + }, + "13462": { + "name": "Ensouled bear head" + }, + "13463": { + "name": "Ensouled bear head" + }, + "13465": { + "name": "Ensouled unicorn head", + "weight": 0.4 + }, + "13466": { + "name": "Ensouled unicorn head", + "weight": 0.4 + }, + "13468": { + "name": "Ensouled dog head", + "weight": 0.4 + }, + "13469": { + "name": "Ensouled dog head", + "weight": 0.4 + }, + "13471": { + "name": "Ensouled chaos druid head", + "weight": 0.4 + }, + "13472": { + "name": "Ensouled chaos druid head", + "weight": 0.4 + }, + "13474": { + "name": "Ensouled giant head", + "weight": 0.4 + }, + "13475": { + "name": "Ensouled giant head", + "weight": 0.4 + }, + "13477": { + "name": "Ensouled ogre head", + "weight": 0.4 + }, + "13478": { + "name": "Ensouled ogre head", + "weight": 0.4 + }, + "13480": { + "name": "Ensouled elf head", + "weight": 0.4 + }, + "13481": { + "name": "Ensouled elf head", + "weight": 0.4 + }, + "13483": { + "name": "Ensouled troll head" + }, + "13484": { + "name": "Ensouled troll head" + }, + "13486": { + "name": "Ensouled horror head", + "weight": 0.4 + }, + "13487": { + "name": "Ensouled horror head", + "weight": 0.4 + }, + "13489": { + "name": "Ensouled kalphite head", + "weight": 0.4 + }, + "13490": { + "name": "Ensouled kalphite head", + "weight": 0.4 + }, + "13492": { + "name": "Ensouled dagannoth head", + "weight": 0.4 + }, + "13493": { + "name": "Ensouled dagannoth head", + "weight": 0.4 + }, + "13495": { + "name": "Ensouled bloodveld head", + "weight": 0.4 + }, + "13496": { + "name": "Ensouled bloodveld head", + "weight": 0.4 + }, + "13498": { + "name": "Ensouled tzhaar head", + "weight": 0.4 + }, + "13499": { + "name": "Ensouled tzhaar head", + "weight": 0.4 + }, + "13501": { + "name": "Ensouled demon head", + "weight": 0.4 + }, + "13502": { + "name": "Ensouled demon head", + "weight": 0.4 + }, + "13504": { + "name": "Ensouled aviansie head", + "weight": 0.4 + }, + "13505": { + "name": "Ensouled aviansie head", + "weight": 0.4 + }, + "13507": { + "name": "Ensouled abyssal head", + "weight": 0.4 + }, + "13508": { + "name": "Ensouled abyssal head", + "weight": 0.4 + }, + "13510": { + "name": "Ensouled dragon head" + }, + "13511": { + "name": "Ensouled dragon head" + }, + "13513": { + "name": "Book of arcane knowledge" + }, + "13514": { + "name": "Dark manuscript" + }, + "13515": { + "name": "Dark manuscript" + }, + "13516": { + "name": "Dark manuscript" + }, + "13517": { + "name": "Dark manuscript" + }, + "13518": { + "name": "Dark manuscript" + }, + "13519": { + "name": "Dark manuscript" + }, + "13520": { + "name": "Dark manuscript" + }, + "13521": { + "name": "Dark manuscript" + }, + "13522": { + "name": "Dark manuscript" + }, + "13523": { + "name": "Dark manuscript" + }, + "13524": { + "name": "Rada's census" + }, + "13525": { + "name": "Ricktor's diary (7)" + }, + "13526": { + "name": "Eathram & rada extract" + }, + "13527": { + "name": "Killing of a king" + }, + "13528": { + "name": "Hosidius letter" + }, + "13529": { + "name": "Wintertodt parable" + }, + "13530": { + "name": "Twill accord" + }, + "13531": { + "name": "Byrne's coronation speech" + }, + "13532": { + "name": "Ideology of darkness" + }, + "13533": { + "name": "Rada's journey" + }, + "13534": { + "name": "Transvergence theory" + }, + "13535": { + "name": "Tristessa's tragedy" + }, + "13536": { + "name": "Treachery of royalty" + }, + "13537": { + "name": "Transportation incantations" + }, + "13538": { + "name": "Shayzien supply gloves (1)" + }, + "13539": { + "name": "Shayzien supply boots (1)" + }, + "13540": { + "name": "Shayzien supply helm (1)", + "weight": 2.0 + }, + "13541": { + "name": "Shayzien supply greaves (1)", + "weight": 9.0 + }, + "13542": { + "name": "Shayzien supply platebody (1)", + "weight": 9.0 + }, + "13543": { + "name": "Shayzien supply gloves (2)" + }, + "13544": { + "name": "Shayzien supply boots (2)" + }, + "13545": { + "name": "Shayzien supply helm (2)", + "weight": 2.0 + }, + "13546": { + "name": "Shayzien supply greaves (2)", + "weight": 9.0 + }, + "13547": { + "name": "Shayzien supply platebody (2)", + "weight": 9.0 + }, + "13548": { + "name": "Shayzien supply gloves (3)" + }, + "13549": { + "name": "Shayzien supply boots (3)" + }, + "13550": { + "name": "Shayzien supply helm (3)", + "weight": 2.0 + }, + "13551": { + "name": "Shayzien supply greaves (3)", + "weight": 9.0 + }, + "13552": { + "name": "Shayzien supply platebody (3)", + "weight": 9.0 + }, + "13553": { + "name": "Shayzien supply gloves (4)" + }, + "13554": { + "name": "Shayzien supply boots (4)" + }, + "13555": { + "name": "Shayzien supply helm (4)", + "weight": 2.0 + }, + "13556": { + "name": "Shayzien supply greaves (4)", + "weight": 9.0 + }, + "13557": { + "name": "Shayzien supply platebody (4)", + "weight": 9.0 + }, + "13558": { + "name": "Shayzien supply gloves (5)" + }, + "13559": { + "name": "Shayzien supply boots (5)" + }, + "13560": { + "name": "Shayzien supply helm (5)", + "weight": 2.0 + }, + "13561": { + "name": "Shayzien supply greaves (5)", + "weight": 9.0 + }, + "13562": { + "name": "Shayzien supply platebody (5)", + "weight": 9.0 + }, + "13563": { + "name": "Shayzien supply crate", + "weight": 0.4 + }, + "13565": { + "name": "Shayzien supply set (1)", + "weight": 6.0 + }, + "13566": { + "name": "Shayzien supply set (2)", + "weight": 6.0 + }, + "13567": { + "name": "Shayzien supply set (3)", + "weight": 6.0 + }, + "13568": { + "name": "Shayzien supply set (4)", + "weight": 6.0 + }, + "13569": { + "name": "Shayzien supply set (5)", + "weight": 6.0 + }, + "13570": { + "name": "Juniper charcoal" + }, + "13571": { + "name": "Volcanic sulphur" + }, + "13572": { + "name": "Dynamite pot", + "weight": 1.3 + }, + "13573": { + "name": "Dynamite", + "weight": 1.3 + }, + "13575": { + "name": "Blasted ore", + "weight": 2.0 + }, + "13576": { + "name": "Dragon warhammer", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 95, + "amagic": -4, + "str": 85, + "aspeed": 6 + } + }, + "13579": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13580": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13581": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13582": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13583": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13584": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13585": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13586": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13587": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13588": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13589": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13590": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13591": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13592": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13593": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13594": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13595": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13596": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13597": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13598": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13599": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13600": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13601": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13602": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13603": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13604": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13605": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13606": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13607": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13608": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13609": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13610": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13611": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13612": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13613": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13614": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13615": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13616": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13617": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13618": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13619": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13620": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13621": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13622": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13623": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13624": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13625": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13626": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13627": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13628": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13629": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13630": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13631": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13632": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13633": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13634": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13635": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13636": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13637": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13638": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13639": { + "name": "Seed box", + "weight": 1.0 + }, + "13640": { + "name": "Farmer's boro trousers", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "13641": { + "name": "Farmer's boro trousers", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "13642": { + "name": "Farmer's jacket", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 4 + } + }, + "13643": { + "name": "Farmer's shirt", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 4 + } + }, + "13644": { + "name": "Farmer's boots", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 10 + } + }, + "13645": { + "name": "Farmer's boots", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 10 + } + }, + "13646": { + "name": "Farmer's strawhat", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0 + } + }, + "13647": { + "name": "Farmer's strawhat", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0 + } + }, + "13648": { + "name": "Clue bottle (easy)" + }, + "13649": { + "name": "Clue bottle (medium)" + }, + "13650": { + "name": "Clue bottle (hard)" + }, + "13651": { + "name": "Clue bottle (elite)" + }, + "13652": { + "name": "Dragon claws", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 41, + "aslash": 57, + "acrush": -4, + "dstab": 13, + "dslash": 26, + "dcrush": 7, + "str": 56, + "aspeed": 4 + } + }, + "13653": { + "name": "Bird nest" + }, + "13654": { + "name": "Nest box (seeds)", + "weight": 1.0 + }, + "13655": { + "name": "Gnome child hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13656": { + "name": "Present" + }, + "13657": { + "name": "Grape seed" + }, + "13658": { + "name": "Teleport card" + }, + "13660": { + "name": "Chronicle", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5 + } + }, + "13663": { + "name": "Bunny top", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 4 + } + }, + "13664": { + "name": "Bunny legs", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "13665": { + "name": "Bunny paws", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 9 + } + }, + "13666": { + "name": "Deadman teleport tablet" + }, + "13667": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13668": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "13669": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13670": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "13671": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13672": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "13673": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13674": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "13675": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13676": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "13677": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13678": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "13679": { + "name": "Cabbage cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "13680": { + "name": "Cabbage rune" + }, + "13681": { + "name": "Cruciferous codex", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5 + } + }, + "19473": { + "name": "Bag full of gems", + "weight": 1.0 + }, + "19476": { + "name": "Achievement diary cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9, + "prayer": 4 + } + }, + "19478": { + "name": "Light ballista", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "arange": 110, + "aspeed": 7 + } + }, + "19481": { + "name": "Heavy ballista", + "quest": true, + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 3, + "arange": 125, + "rstr": 15, + "aspeed": 7 + } + }, + "19484": { + "name": "Dragon javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 150 + } + }, + "19486": { + "name": "Dragon javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 150 + } + }, + "19488": { + "name": "Dragon javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 150 + } + }, + "19490": { + "name": "Dragon javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 150 + } + }, + "19493": { + "name": "Zenyte" + }, + "19496": { + "name": "Uncut zenyte" + }, + "19501": { + "name": "Zenyte amulet (u)" + }, + "19505": { + "name": "Mysterious note", + "quest": true + }, + "19507": { + "name": "Mysterious note", + "quest": true + }, + "19509": { + "name": "Mysterious note", + "quest": true + }, + "19511": { + "name": "Scrawled note", + "quest": true + }, + "19513": { + "name": "Translated note", + "quest": true + }, + "19515": { + "name": "Book of spyology", + "quest": true, + "weight": 1.0 + }, + "19517": { + "name": "Brush", + "quest": true + }, + "19519": { + "name": "Juice-coated brush", + "quest": true + }, + "19521": { + "name": "Handkerchief", + "quest": true + }, + "19523": { + "name": "Kruk's paw", + "quest": true, + "weight": 1.0 + }, + "19525": { + "name": "Kruk monkey greegree", + "quest": true + }, + "19527": { + "name": "Satchel", + "quest": true + }, + "19528": { + "name": "Satchel", + "quest": true + }, + "19529": { + "name": "Zenyte shard" + }, + "19532": { + "name": "Zenyte bracelet", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "19535": { + "name": "Zenyte necklace", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19538": { + "name": "Zenyte ring", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "19541": { + "name": "Zenyte amulet", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19544": { + "name": "Tormented bracelet", + "equipable": true, + "equipment": { + "slot": 9, + "amagic": 10, + "mdmg": 5, + "prayer": 2 + } + }, + "19547": { + "name": "Necklace of anguish", + "equipable": true, + "equipment": { + "slot": 2, + "arange": 15, + "rstr": 5, + "prayer": 2 + } + }, + "19550": { + "name": "Ring of suffering", + "equipable": true, + "equipment": { + "slot": 12, + "dstab": 10, + "dslash": 10, + "dcrush": 10, + "dmagic": 10, + "drange": 10, + "prayer": 2 + } + }, + "19553": { + "name": "Amulet of torture", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 15, + "aslash": 15, + "acrush": 15, + "str": 10, + "prayer": 2 + } + }, + "19556": { + "name": "Monkey", + "quest": true, + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "19558": { + "name": "Nieve", + "quest": true + }, + "19559": { + "name": "Elysian spirit shield", + "quest": true + }, + "19560": { + "name": "Charged onyx", + "quest": true + }, + "19562": { + "name": "Deconstructed onyx", + "quest": true + }, + "19564": { + "name": "Royal seed pod", + "quest": true + }, + "19566": { + "name": "Bronze key", + "quest": true + }, + "19569": { + "name": "Combat damaged key", + "quest": true + }, + "19570": { + "name": "Bronze javelin heads" + }, + "19572": { + "name": "Iron javelin heads" + }, + "19574": { + "name": "Steel javelin heads" + }, + "19576": { + "name": "Mithril javelin heads" + }, + "19578": { + "name": "Adamant javelin heads" + }, + "19580": { + "name": "Rune javelin heads" + }, + "19582": { + "name": "Dragon javelin heads" + }, + "19584": { + "name": "Javelin shaft" + }, + "19586": { + "name": "Light frame", + "weight": 2.8 + }, + "19589": { + "name": "Heavy frame", + "weight": 5.2 + }, + "19592": { + "name": "Ballista limbs", + "weight": 0.2 + }, + "19595": { + "name": "Incomplete light ballista", + "weight": 2.8 + }, + "19598": { + "name": "Incomplete heavy ballista", + "weight": 5.2 + }, + "19601": { + "name": "Ballista spring", + "weight": 0.2 + }, + "19604": { + "name": "Unstrung light ballista", + "weight": 2.8 + }, + "19607": { + "name": "Unstrung heavy ballista", + "weight": 2.8 + }, + "19610": { + "name": "Monkey tail", + "weight": 0.2 + }, + "19613": { + "name": "Lumbridge graveyard teleport" + }, + "19615": { + "name": "Draynor manor teleport" + }, + "19617": { + "name": "Mind altar teleport" + }, + "19619": { + "name": "Salve graveyard teleport" + }, + "19621": { + "name": "Fenkenstrain's castle teleport" + }, + "19623": { + "name": "West ardougne teleport" + }, + "19625": { + "name": "Harmony island teleport" + }, + "19627": { + "name": "Cemetery teleport" + }, + "19629": { + "name": "Barrows teleport" + }, + "19631": { + "name": "Ape atoll teleport" + }, + "19634": { + "name": "Soul bearer", + "weight": 0.4 + }, + "19636": { + "name": "Damaged soul bearer" + }, + "19637": { + "name": "Soul journey" + }, + "19639": { + "name": "Black slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "19641": { + "name": "Black slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "19643": { + "name": "Green slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "19645": { + "name": "Green slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "19647": { + "name": "Red slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "19649": { + "name": "Red slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "19651": { + "name": "Hosidius teleport" + }, + "19653": { + "name": "Golovanova fruit top", + "weight": 2.2 + }, + "19656": { + "name": "Uncooked botanical pie", + "weight": 0.5 + }, + "19659": { + "name": "Half a botanical pie", + "weight": 0.2 + }, + "19662": { + "name": "Botanical pie", + "weight": 0.4 + }, + "19665": { + "name": "Damaged monkey tail", + "weight": 0.2 + }, + "19668": { + "name": "Minecart control scroll" + }, + "19669": { + "name": "Redwood logs", + "weight": 2.0 + }, + "19672": { + "name": "Redwood pyre logs", + "weight": 2.0 + }, + "19675": { + "name": "Arclight", + "equipable": true, + "weight": 1.3, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": 38, + "dslash": 3, + "dcrush": 2, + "dmagic": 2, + "str": 8, + "aspeed": 4 + } + }, + "19677": { + "name": "Ancient shard" + }, + "19679": { + "name": "Dark totem base" + }, + "19681": { + "name": "Dark totem middle" + }, + "19683": { + "name": "Dark totem top" + }, + "19685": { + "name": "Dark totem" + }, + "19687": { + "name": "Helm of raedwald", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "19689": { + "name": "Clue hunter garb", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 4, + "amagic": -2, + "arange": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 10, + "dmagic": 4, + "drange": 9 + } + }, + "19691": { + "name": "Clue hunter gloves", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "19693": { + "name": "Clue hunter trousers", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 7, + "arange": 4, + "dstab": 2, + "dslash": 2, + "dcrush": 1 + } + }, + "19695": { + "name": "Clue hunter boots", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "19697": { + "name": "Clue hunter cloak", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "19699": { + "name": "Hornwood helm", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "19701": { + "name": "Jar of darkness" + }, + "19704": { + "name": "Compost pack" + }, + "19707": { + "name": "Amulet of eternal glory", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "19710": { + "name": "Ring of suffering (i)", + "equipable": true, + "equipment": { + "slot": 12, + "dstab": 20, + "dslash": 20, + "dcrush": 20, + "dmagic": 20, + "drange": 20, + "prayer": 4 + } + }, + "19712": { + "name": "Clue nest (easy)" + }, + "19714": { + "name": "Clue nest (medium)" + }, + "19716": { + "name": "Clue nest (hard)" + }, + "19718": { + "name": "Clue nest (elite)" + }, + "19720": { + "name": "Occult necklace (or)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 2, + "amagic": 12, + "mdmg": 10, + "prayer": 2 + } + }, + "19722": { + "name": "Dragon defender (t)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 25, + "aslash": 24, + "acrush": 23, + "amagic": -3, + "arange": -2, + "dstab": 25, + "dslash": 24, + "dcrush": 23, + "dmagic": -3, + "drange": -2, + "str": 6 + } + }, + "19724": { + "name": "Left eye patch", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "19727": { + "name": "Double eye patch", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "19732": { + "name": "Lucky impling jar", + "weight": 2.2 + }, + "19734": { + "name": "Clue scroll (medium)" + }, + "19735": { + "name": "Challenge scroll (medium)" + }, + "19736": { + "name": "Clue scroll (medium)" + }, + "19737": { + "name": "Challenge scroll (medium)" + }, + "19738": { + "name": "Clue scroll (medium)" + }, + "19739": { + "name": "Challenge scroll (medium)" + }, + "19740": { + "name": "Clue scroll (medium)" + }, + "19741": { + "name": "Challenge scroll (medium)" + }, + "19742": { + "name": "Clue scroll (medium)" + }, + "19743": { + "name": "Challenge scroll (medium)" + }, + "19744": { + "name": "Clue scroll (medium)" + }, + "19745": { + "name": "Challenge scroll (medium)" + }, + "19746": { + "name": "Clue scroll (medium)" + }, + "19747": { + "name": "Challenge scroll (medium)" + }, + "19748": { + "name": "Clue scroll (medium)" + }, + "19749": { + "name": "Challenge scroll (medium)" + }, + "19750": { + "name": "Clue scroll (medium)" + }, + "19751": { + "name": "Challenge scroll (medium)" + }, + "19752": { + "name": "Clue scroll (medium)" + }, + "19753": { + "name": "Challenge scroll (medium)" + }, + "19754": { + "name": "Clue scroll (medium)" + }, + "19755": { + "name": "Challenge scroll (medium)" + }, + "19756": { + "name": "Clue scroll (medium)" + }, + "19757": { + "name": "Challenge scroll (medium)" + }, + "19758": { + "name": "Clue scroll (medium)" + }, + "19759": { + "name": "Challenge scroll (medium)" + }, + "19760": { + "name": "Clue scroll (medium)" + }, + "19761": { + "name": "Key (medium)" + }, + "19762": { + "name": "Clue scroll (medium)" + }, + "19763": { + "name": "Challenge scroll (medium)" + }, + "19764": { + "name": "Clue scroll (medium)" + }, + "19765": { + "name": "Challenge scroll (medium)" + }, + "19766": { + "name": "Clue scroll (medium)" + }, + "19767": { + "name": "Challenge scroll (medium)" + }, + "19768": { + "name": "Clue scroll (medium)" + }, + "19769": { + "name": "Challenge scroll (medium)" + }, + "19770": { + "name": "Clue scroll (medium)" + }, + "19771": { + "name": "Challenge scroll (medium)" + }, + "19772": { + "name": "Clue scroll (medium)" + }, + "19773": { + "name": "Challenge scroll (medium)" + }, + "19774": { + "name": "Clue scroll (medium)" + }, + "19776": { + "name": "Clue scroll (medium)" + }, + "19778": { + "name": "Clue scroll (medium)" + }, + "19780": { + "name": "Clue scroll (medium)" + }, + "19782": { + "name": "Clue scroll (elite)" + }, + "19783": { + "name": "Clue scroll (elite)" + }, + "19784": { + "name": "Clue scroll (elite)" + }, + "19785": { + "name": "Clue scroll (elite)" + }, + "19786": { + "name": "Clue scroll (elite)" + }, + "19787": { + "name": "Clue scroll (elite)" + }, + "19788": { + "name": "Clue scroll (elite)" + }, + "19789": { + "name": "Clue scroll (elite)" + }, + "19790": { + "name": "Clue scroll (elite)" + }, + "19791": { + "name": "Clue scroll (elite)" + }, + "19792": { + "name": "Clue scroll (elite)" + }, + "19793": { + "name": "Clue scroll (elite)" + }, + "19794": { + "name": "Clue scroll (elite)" + }, + "19795": { + "name": "Clue scroll (elite)" + }, + "19796": { + "name": "Clue scroll (elite)" + }, + "19797": { + "name": "Clue scroll (elite)" + }, + "19798": { + "name": "Clue scroll (elite)" + }, + "19799": { + "name": "Clue scroll (elite)" + }, + "19800": { + "name": "Clue scroll (elite)" + }, + "19801": { + "name": "Clue scroll (elite)" + }, + "19802": { + "name": "Clue scroll (elite)" + }, + "19803": { + "name": "Clue scroll (elite)" + }, + "19804": { + "name": "Clue scroll (elite)" + }, + "19805": { + "name": "Clue scroll (elite)" + }, + "19806": { + "name": "Clue scroll (elite)" + }, + "19807": { + "name": "Clue scroll (elite)" + }, + "19808": { + "name": "Clue scroll (elite)" + }, + "19809": { + "name": "Clue scroll (elite)" + }, + "19810": { + "name": "Clue scroll (elite)" + }, + "19811": { + "name": "Clue scroll (elite)" + }, + "19812": { + "name": "Key (elite)" + }, + "19813": { + "name": "Clue scroll (elite)" + }, + "19814": { + "name": "Clue scroll (easy)" + }, + "19816": { + "name": "Clue scroll (easy)" + }, + "19817": { + "name": "Clue scroll (easy)" + }, + "19818": { + "name": "Clue scroll (easy)" + }, + "19819": { + "name": "Clue scroll (easy)" + }, + "19820": { + "name": "Clue scroll (easy)" + }, + "19821": { + "name": "Clue scroll (easy)" + }, + "19822": { + "name": "Clue scroll (easy)" + }, + "19823": { + "name": "Clue scroll (easy)" + }, + "19824": { + "name": "Clue scroll (easy)" + }, + "19825": { + "name": "Clue scroll (easy)" + }, + "19826": { + "name": "Clue scroll (easy)" + }, + "19828": { + "name": "Clue scroll (easy)" + }, + "19829": { + "name": "Clue scroll (easy)" + }, + "19830": { + "name": "Clue scroll (easy)" + }, + "19831": { + "name": "Clue scroll (easy)" + }, + "19833": { + "name": "Clue scroll (easy)" + }, + "19835": { + "name": "Clue scroll (master)" + }, + "19836": { + "name": "Reward casket (master)", + "weight": 5.0 + }, + "19837": { + "name": "Torn clue scroll (part 1)", + "equipable": true + }, + "19838": { + "name": "Torn clue scroll (part 2)", + "equipable": true + }, + "19839": { + "name": "Torn clue scroll (part 3)", + "equipable": true + }, + "19840": { + "name": "Clue scroll (hard)" + }, + "19842": { + "name": "Clue scroll (hard)" + }, + "19844": { + "name": "Clue scroll (hard)" + }, + "19846": { + "name": "Clue scroll (hard)" + }, + "19847": { + "name": "Challenge scroll (hard)" + }, + "19848": { + "name": "Clue scroll (hard)" + }, + "19850": { + "name": "Clue scroll (hard)" + }, + "19852": { + "name": "Clue scroll (hard)" + }, + "19853": { + "name": "Clue scroll (hard)" + }, + "19854": { + "name": "Clue scroll (hard)" + }, + "19855": { + "name": "Challenge scroll (hard)" + }, + "19856": { + "name": "Clue scroll (hard)" + }, + "19857": { + "name": "Clue scroll (hard)" + }, + "19858": { + "name": "Clue scroll (hard)" + }, + "19859": { + "name": "Challenge scroll (hard)" + }, + "19860": { + "name": "Clue scroll (hard)" + }, + "19862": { + "name": "Clue scroll (hard)" + }, + "19864": { + "name": "Clue scroll (hard)" + }, + "19866": { + "name": "Clue scroll (hard)" + }, + "19868": { + "name": "Clue scroll (hard)" + }, + "19870": { + "name": "Clue scroll (hard)" + }, + "19872": { + "name": "Clue scroll (hard)" + }, + "19874": { + "name": "Clue scroll (hard)" + }, + "19876": { + "name": "Clue scroll (hard)" + }, + "19878": { + "name": "Clue scroll (hard)" + }, + "19880": { + "name": "Clue scroll (hard)" + }, + "19882": { + "name": "Clue scroll (hard)" + }, + "19884": { + "name": "Clue scroll (hard)" + }, + "19885": { + "name": "Challenge scroll (hard)" + }, + "19886": { + "name": "Clue scroll (hard)" + }, + "19887": { + "name": "Puzzle box (hard)" + }, + "19888": { + "name": "Clue scroll (hard)" + }, + "19890": { + "name": "Clue scroll (hard)" + }, + "19891": { + "name": "Puzzle box (hard)" + }, + "19892": { + "name": "Clue scroll (hard)" + }, + "19893": { + "name": "Challenge scroll (hard)" + }, + "19894": { + "name": "Clue scroll (hard)" + }, + "19895": { + "name": "Puzzle box (hard)" + }, + "19896": { + "name": "Clue scroll (hard)" + }, + "19897": { + "name": "Puzzle box (hard)" + }, + "19898": { + "name": "Clue scroll (hard)" + }, + "19899": { + "name": "Challenge scroll (hard)" + }, + "19900": { + "name": "Clue scroll (hard)" + }, + "19902": { + "name": "Clue scroll (hard)" + }, + "19903": { + "name": "Puzzle box (hard)" + }, + "19904": { + "name": "Clue scroll (hard)" + }, + "19906": { + "name": "Clue scroll (hard)" + }, + "19907": { + "name": "Challenge scroll (hard)" + }, + "19908": { + "name": "Clue scroll (hard)" + }, + "19910": { + "name": "Clue scroll (hard)" + }, + "19911": { + "name": "Puzzle box (hard)" + }, + "19912": { + "name": "Zombie head", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 10, + "amagic": -4, + "str": 8, + "aspeed": 6 + } + }, + "19915": { + "name": "Cyclops head", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "19918": { + "name": "Nunchaku", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 11, + "amagic": -4, + "str": 14, + "aspeed": 5 + } + }, + "19921": { + "name": "Ancient d'hide boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 7, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 1 + } + }, + "19924": { + "name": "Bandos d'hide boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 7, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 1 + } + }, + "19927": { + "name": "Guthix d'hide boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 7, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 1 + } + }, + "19930": { + "name": "Armadyl d'hide boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 7, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 1 + } + }, + "19933": { + "name": "Saradomin d'hide boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 7, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 1 + } + }, + "19936": { + "name": "Zamorak d'hide boots", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 7, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4, + "prayer": 1 + } + }, + "19939": { + "name": "Strange device", + "weight": 1.0 + }, + "19941": { + "name": "Heavy casket", + "equipable": true, + "weight": 15.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 11, + "amagic": -4, + "str": 9, + "aspeed": 6 + } + }, + "19943": { + "name": "Arceuus scarf", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19946": { + "name": "Hosidius scarf", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19949": { + "name": "Lovakengj scarf", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19952": { + "name": "Piscarilius scarf", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19955": { + "name": "Shayzien scarf", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19958": { + "name": "Dark tuxedo jacket", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "19961": { + "name": "Dark tuxedo cuffs", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "19964": { + "name": "Dark trousers", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "19967": { + "name": "Dark tuxedo shoes", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "19970": { + "name": "Dark bow tie", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19973": { + "name": "Light tuxedo jacket", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "19976": { + "name": "Light tuxedo cuffs", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "19979": { + "name": "Light trousers", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "19982": { + "name": "Light tuxedo shoes", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "19985": { + "name": "Light bow tie", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "19988": { + "name": "Blacksmith's helm", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "19991": { + "name": "Bucket helm", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "19994": { + "name": "Ranger gloves", + "equipable": true, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 11, + "dstab": 1, + "dslash": 2, + "dcrush": 1, + "dmagic": 2 + } + }, + "19997": { + "name": "Holy wraps", + "equipable": true, + "equipment": { + "slot": 9, + "prayer": 3 + } + }, + "20000": { + "name": "Dragon scimitar (or)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 67, + "acrush": -2, + "dslash": 1, + "str": 66, + "aspeed": 4 + } + }, + "20002": { + "name": "Dragon scimitar ornament kit", + "equipable": true + }, + "20005": { + "name": "Ring of nature" + }, + "20008": { + "name": "Fancy tiara", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20011": { + "name": "3rd age axe", + "equipable": true, + "weight": 1.3, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 38, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "20014": { + "name": "3rd age pickaxe", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": -2, + "acrush": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "20017": { + "name": "Ring of coins" + }, + "20020": { + "name": "Lesser demon mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20023": { + "name": "Greater demon mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20026": { + "name": "Black demon mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20029": { + "name": "Old demon mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20032": { + "name": "Jungle demon mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20035": { + "name": "Samurai kasa", + "equipable": true, + "weight": 0.6, + "equipment": { + "slot": 0, + "dstab": 16, + "dslash": 17, + "dcrush": 15, + "dmagic": 4, + "drange": 16 + } + }, + "20038": { + "name": "Samurai shirt", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 4, + "dstab": 69, + "dslash": 67, + "dcrush": 59, + "dmagic": 10, + "drange": 67 + } + }, + "20041": { + "name": "Samurai gloves", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 9, + "astab": 2, + "aslash": 2, + "acrush": 2, + "amagic": 2, + "arange": 2, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3 + } + }, + "20044": { + "name": "Samurai greaves", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 7, + "dstab": 42, + "dslash": 40, + "dcrush": 38, + "dmagic": 3, + "drange": 40 + } + }, + "20047": { + "name": "Samurai boots", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 10, + "dstab": 11, + "dslash": 12, + "dcrush": 13, + "dmagic": 1 + } + }, + "20050": { + "name": "Obsidian cape (r)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "20053": { + "name": "Half moon spectacles", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20056": { + "name": "Ale of the gods", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "20059": { + "name": "Bucket helm (g)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "20062": { + "name": "Torture ornament kit", + "equipable": true + }, + "20065": { + "name": "Occult ornament kit", + "equipable": true + }, + "20068": { + "name": "Armadyl godsword ornament kit" + }, + "20071": { + "name": "Bandos godsword ornament kit" + }, + "20074": { + "name": "Saradomin godsword ornament kit", + "equipable": true + }, + "20077": { + "name": "Zamorak godsword ornament kit", + "equipable": true + }, + "20080": { + "name": "Mummy's head", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20083": { + "name": "Mummy's body", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "20086": { + "name": "Mummy's hands", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "20089": { + "name": "Mummy's legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "20092": { + "name": "Mummy's feet", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "20095": { + "name": "Ankou mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20098": { + "name": "Ankou top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "20101": { + "name": "Ankou gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "20104": { + "name": "Ankou's leggings", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "20107": { + "name": "Ankou socks", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "20110": { + "name": "Bowl wig", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20113": { + "name": "Arceuus hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20116": { + "name": "Hosidius hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20119": { + "name": "Lovakengj hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20122": { + "name": "Piscarilius hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20125": { + "name": "Shayzien hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20128": { + "name": "Hood of darkness", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "20131": { + "name": "Robe top of darkness", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "20134": { + "name": "Gloves of darkness", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 9, + "amagic": 3, + "dmagic": 3 + } + }, + "20137": { + "name": "Robe bottom of darkness", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "20140": { + "name": "Boots of darkness", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 10, + "amagic": 3, + "dmagic": 3 + } + }, + "20143": { + "name": "Dragon defender ornament kit", + "equipable": true + }, + "20146": { + "name": "Gilded med helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 22, + "dslash": 23, + "dcrush": 21, + "dmagic": -1, + "drange": 22 + } + }, + "20149": { + "name": "Gilded chainbody", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 63, + "dslash": 72, + "dcrush": 78, + "dmagic": -3, + "drange": 65 + } + }, + "20152": { + "name": "Gilded sq shield", + "equipable": true, + "weight": 3.64, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 38, + "dslash": 40, + "dcrush": 36, + "drange": 38 + } + }, + "20155": { + "name": "Gilded 2h sword", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 69, + "acrush": 50, + "amagic": -4, + "drange": -1, + "str": 70, + "aspeed": 7 + } + }, + "20158": { + "name": "Gilded spear", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": 1, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "20161": { + "name": "Gilded hasta", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 36, + "aslash": 36, + "acrush": 36, + "dstab": -10, + "dslash": -10, + "dcrush": -9, + "drange": -10, + "str": 42, + "aspeed": 5 + } + }, + "20164": { + "name": "Large spade", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "20166": { + "name": "Wooden shield (g)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 5, + "dstab": 4, + "dslash": 5, + "dcrush": 3, + "dmagic": 1, + "drange": 4 + } + }, + "20169": { + "name": "Steel platebody (g)", + "equipable": true, + "weight": 9.9, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 32, + "dslash": 31, + "dcrush": 24, + "dmagic": -6, + "drange": 31 + } + }, + "20172": { + "name": "Steel platelegs (g)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "20175": { + "name": "Steel plateskirt (g)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "20178": { + "name": "Steel full helm (g)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "20181": { + "name": "Steel kiteshield (g)", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "20184": { + "name": "Steel platebody (t)", + "equipable": true, + "weight": 9.9, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 32, + "dslash": 31, + "dcrush": 24, + "dmagic": -6, + "drange": 31 + } + }, + "20187": { + "name": "Steel platelegs (t)", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "20190": { + "name": "Steel plateskirt (t)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 17, + "dslash": 16, + "dcrush": 15, + "dmagic": -4, + "drange": 16 + } + }, + "20193": { + "name": "Steel full helm (t)", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 9, + "dslash": 10, + "dcrush": 7, + "dmagic": -1, + "drange": 9 + } + }, + "20196": { + "name": "Steel kiteshield (t)", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 13, + "dslash": 15, + "dcrush": 14, + "dmagic": -1, + "drange": 14 + } + }, + "20199": { + "name": "Monk's robe top (g)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 4, + "prayer": 6 + } + }, + "20202": { + "name": "Monk's robe (g)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 7, + "prayer": 5 + } + }, + "20205": { + "name": "Golden chef's hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20208": { + "name": "Golden apron", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "20211": { + "name": "Team cape zero", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "20214": { + "name": "Team cape x", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "20217": { + "name": "Team cape i", + "equipable": true, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "20220": { + "name": "Holy blessing", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "20223": { + "name": "Unholy blessing", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "20226": { + "name": "Peaceful blessing", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "20229": { + "name": "Honourable blessing", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "20232": { + "name": "War blessing", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "20235": { + "name": "Ancient blessing", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "20238": { + "name": "Charge dragonstone jewellery scroll" + }, + "20240": { + "name": "Crier coat", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "20243": { + "name": "Crier bell", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "20246": { + "name": "Black leprechaun hat", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "20249": { + "name": "Clueless scroll", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "20251": { + "name": "Arceuus banner", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "20254": { + "name": "Hosidius banner", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "20257": { + "name": "Lovakengj banner", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "20260": { + "name": "Piscarilius banner", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "20263": { + "name": "Shayzien banner", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 12, + "aslash": 12, + "acrush": 12, + "dstab": 1, + "dslash": 1, + "str": 12, + "aspeed": 5 + } + }, + "20266": { + "name": "Black unicorn mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20269": { + "name": "White unicorn mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "20272": { + "name": "Cabbage round shield", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 5, + "amagic": -6, + "arange": -2, + "dstab": 24, + "dslash": 26, + "dcrush": 22, + "drange": 24 + } + }, + "20275": { + "name": "Gnomish firelighter", + "equipable": true + }, + "20278": { + "name": "Gnomish firelighter", + "equipable": true + }, + "20280": { + "name": "Puzzle box (master)" + }, + "20281": { + "name": "Puzzle box (master)" + }, + "20282": { + "name": "Puzzle box (master)" + }, + "20355": { + "name": "Light box", + "weight": 0.1 + }, + "20358": { + "name": "Clue geode (easy)" + }, + "20360": { + "name": "Clue geode (medium)" + }, + "20362": { + "name": "Clue geode (hard)" + }, + "20364": { + "name": "Clue geode (elite)" + }, + "20366": { + "name": "Amulet of torture (or)", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 15, + "aslash": 15, + "acrush": 15, + "str": 10, + "prayer": 2 + } + }, + "20368": { + "name": "Armadyl godsword (or)", + "equipable": true, + "weight": 11.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "20370": { + "name": "Bandos godsword (or)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "20372": { + "name": "Saradomin godsword (or)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "20374": { + "name": "Zamorak godsword (or)", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "20376": { + "name": "Steel trimmed set (lg)", + "weight": 6.0 + }, + "20379": { + "name": "Steel trimmed set (sk)", + "weight": 6.0 + }, + "20382": { + "name": "Steel gold-trimmed set (lg)", + "weight": 6.0 + }, + "20385": { + "name": "Steel gold-trimmed set (sk)", + "weight": 6.0 + }, + "20388": { + "name": "Adamant arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 31 + } + }, + "20389": { + "name": "Dragon arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 60 + } + }, + "20390": { + "name": "Shark", + "weight": 0.65 + }, + "20393": { + "name": "Prayer potion(4)", + "weight": 0.035 + }, + "20394": { + "name": "Prayer potion(3)", + "weight": 0.03 + }, + "20395": { + "name": "Prayer potion(2)", + "weight": 0.025 + }, + "20396": { + "name": "Prayer potion(1)", + "weight": 0.02 + }, + "20397": { + "name": "Spear", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": 22, + "aslash": 18, + "amagic": -4, + "dstab": -1, + "dslash": 2, + "dcrush": 4, + "str": 20, + "aspeed": 7 + } + }, + "20401": { + "name": "Yew shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 47, + "aspeed": 4 + } + }, + "20402": { + "name": "Rune scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "20403": { + "name": "Maple shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 29, + "aspeed": 4 + } + }, + "20405": { + "name": "Abyssal whip", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "aslash": 82, + "str": 82, + "aspeed": 4 + } + }, + "20406": { + "name": "Dragon scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 67, + "acrush": -2, + "dslash": 1, + "str": 66, + "aspeed": 4 + } + }, + "20407": { + "name": "Dragon dagger", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 3, + "astab": 40, + "aslash": 25, + "acrush": -4, + "amagic": 1, + "dmagic": 1, + "str": 40, + "aspeed": 4 + } + }, + "20408": { + "name": "Dark bow", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 9 + } + }, + "20415": { + "name": "Adamant platebody", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "20416": { + "name": "Adamant platelegs", + "equipable": true, + "weight": 10.432, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "20417": { + "name": "Blue d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 20, + "dstab": 45, + "dslash": 37, + "dcrush": 50, + "dmagic": 30, + "drange": 45 + } + }, + "20418": { + "name": "Blue d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 11, + "dstab": 25, + "dslash": 19, + "dcrush": 27, + "dmagic": 14, + "drange": 25 + } + }, + "20421": { + "name": "Rune platebody", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "20422": { + "name": "Rune platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 51, + "dslash": 49, + "dcrush": 47, + "dmagic": -4, + "drange": 49 + } + }, + "20423": { + "name": "Black d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 30, + "dstab": 55, + "dslash": 47, + "dcrush": 60, + "dmagic": 50, + "drange": 55 + } + }, + "20424": { + "name": "Black d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 17, + "dstab": 31, + "dslash": 25, + "dcrush": 33, + "dmagic": 28, + "drange": 31 + } + }, + "20425": { + "name": "Mystic robe top", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "20426": { + "name": "Mystic robe bottom", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "20428": { + "name": "Dragon chainbody", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 81, + "dslash": 93, + "dcrush": 98, + "dmagic": -3, + "drange": 82 + } + }, + "20429": { + "name": "Dragon platelegs", + "equipable": true, + "weight": 9.071, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 68, + "dslash": 66, + "dcrush": 63, + "dmagic": -4, + "drange": 65 + } + }, + "20430": { + "name": "Ancient magicks tablet" + }, + "20431": { + "name": "Ancient staff", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "str": 50, + "prayer": -1, + "aspeed": 4 + } + }, + "20433": { + "name": "Evil chicken feet", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 10 + } + }, + "20436": { + "name": "Evil chicken wings", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 4 + } + }, + "20439": { + "name": "Evil chicken head", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 0 + } + }, + "20442": { + "name": "Evil chicken legs", + "equipable": true, + "weight": 0.25, + "equipment": { + "slot": 7 + } + }, + "20445": { + "name": "Fire cape (broken)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 1, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 11, + "dslash": 11, + "dcrush": 11, + "dmagic": 11, + "drange": 11, + "str": 4, + "prayer": 2 + } + }, + "20447": { + "name": "Fire max cape (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "astab": 1, + "aslash": 1, + "acrush": 1, + "amagic": 1, + "arange": 1, + "dstab": 11, + "dslash": 11, + "dcrush": 11, + "dmagic": 11, + "drange": 11, + "str": 4, + "prayer": 2 + } + }, + "20449": { + "name": "Bronze defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 3, + "aslash": 2, + "acrush": 1, + "amagic": -3, + "arange": -2, + "dstab": 3, + "dslash": 2, + "dcrush": 1, + "dmagic": -3, + "drange": -2 + } + }, + "20451": { + "name": "Iron defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 5, + "aslash": 4, + "acrush": 3, + "amagic": -3, + "arange": -2, + "dstab": 5, + "dslash": 4, + "dcrush": 3, + "dmagic": -3, + "drange": -2 + } + }, + "20453": { + "name": "Steel defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 7, + "aslash": 6, + "acrush": 5, + "amagic": -3, + "arange": -2, + "dstab": 7, + "dslash": 6, + "dcrush": 5, + "dmagic": -3, + "drange": -2, + "str": 1 + } + }, + "20455": { + "name": "Black defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 9, + "aslash": 8, + "acrush": 7, + "amagic": -3, + "arange": -2, + "dstab": 9, + "dslash": 8, + "dcrush": 7, + "dmagic": -3, + "drange": -2, + "str": 2 + } + }, + "20457": { + "name": "Mithril defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 10, + "aslash": 9, + "acrush": 8, + "amagic": -3, + "arange": -2, + "dstab": 10, + "dslash": 9, + "dcrush": 8, + "dmagic": -3, + "drange": -2, + "str": 3 + } + }, + "20459": { + "name": "Adamant defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 13, + "aslash": 12, + "acrush": 11, + "amagic": -3, + "arange": -2, + "dstab": 13, + "dslash": 12, + "dcrush": 11, + "dmagic": -3, + "drange": -2, + "str": 4 + } + }, + "20461": { + "name": "Rune defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 20, + "aslash": 19, + "acrush": 18, + "amagic": -3, + "arange": -2, + "dstab": 20, + "dslash": 19, + "dcrush": 18, + "dmagic": -3, + "drange": -2, + "str": 5 + } + }, + "20463": { + "name": "Dragon defender (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 25, + "aslash": 24, + "acrush": 23, + "amagic": -3, + "arange": -2, + "dstab": 25, + "dslash": 24, + "dcrush": 23, + "dmagic": -3, + "drange": -2, + "str": 6 + } + }, + "20465": { + "name": "Void knight top (broken)", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "dstab": 45, + "dslash": 45, + "dcrush": 45, + "dmagic": 45, + "drange": 45 + } + }, + "20467": { + "name": "Elite void top (broken)", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "dstab": 45, + "dslash": 45, + "dcrush": 45, + "dmagic": 45, + "drange": 45, + "prayer": 3 + } + }, + "20469": { + "name": "Void knight robe (broken)", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "dstab": 30, + "dslash": 30, + "dcrush": 30, + "dmagic": 30, + "drange": 30 + } + }, + "20471": { + "name": "Elite void robe (broken)", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 7, + "dstab": 30, + "dslash": 30, + "dcrush": 30, + "dmagic": 30, + "drange": 30, + "prayer": 3 + } + }, + "20473": { + "name": "Void knight mace (broken)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 22, + "acrush": 41, + "amagic": 8, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": 2, + "drange": 2, + "str": 38, + "prayer": 6, + "aspeed": 5 + } + }, + "20475": { + "name": "Void knight gloves (broken)", + "equipable": true, + "equipment": { + "slot": 9, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 4, + "drange": 6 + } + }, + "20477": { + "name": "Void mage helm (broken)", + "equipable": true, + "equipment": { + "slot": 0, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6 + } + }, + "20479": { + "name": "Void ranger helm (broken)", + "equipable": true, + "equipment": { + "slot": 0, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6 + } + }, + "20481": { + "name": "Void melee helm (broken)", + "equipable": true, + "equipment": { + "slot": 0, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6 + } + }, + "20483": { + "name": "Decorative sword (broken)", + "equipable": true, + "weight": 1.588, + "equipment": { + "slot": 3, + "astab": 20, + "aslash": 29, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 31, + "aspeed": 5 + } + }, + "20485": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 8.6175, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "20487": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 9.05, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "20489": { + "name": "Decorative helm (broken)", + "equipable": true, + "weight": 1.355, + "equipment": { + "slot": 0, + "amagic": -3, + "arange": -1, + "dstab": 14, + "dslash": 15, + "dcrush": 13, + "dmagic": -1, + "drange": 14 + } + }, + "20491": { + "name": "Decorative shield (broken)", + "equipable": true, + "weight": 4.54, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "20493": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 9.05, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31 + } + }, + "20495": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "dstab": 20, + "dslash": 20, + "dcrush": 20, + "dmagic": 20, + "drange": 20 + } + }, + "20497": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 7, + "dstab": 15, + "dslash": 15, + "dcrush": 15, + "dmagic": 15, + "drange": 15 + } + }, + "20499": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 0, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4 + } + }, + "20501": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "dstab": 20, + "dslash": 20, + "dcrush": 20, + "dmagic": 20, + "drange": 20 + } + }, + "20503": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 7, + "dstab": 15, + "dslash": 15, + "dcrush": 15, + "dmagic": 15, + "drange": 15 + } + }, + "20505": { + "name": "Decorative armour (broken)", + "equipable": true, + "weight": 8.155, + "equipment": { + "slot": 1, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 4, + "drange": 4 + } + }, + "20507": { + "name": "Fighter hat (broken)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "astab": 5, + "aslash": 5, + "acrush": 5, + "amagic": -7, + "arange": -7, + "dstab": 27, + "dslash": 29, + "dcrush": 26, + "dmagic": -3, + "drange": 28 + } + }, + "20509": { + "name": "Ranger hat (broken)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": -5, + "arange": 6, + "dstab": 7, + "dslash": 10, + "dcrush": 11, + "dmagic": 5, + "drange": 8 + } + }, + "20511": { + "name": "Healer hat (broken)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": 6, + "arange": -5, + "dstab": 6, + "dslash": 8, + "dcrush": 10, + "dmagic": 7 + } + }, + "20513": { + "name": "Fighter torso (broken)", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 4, + "amagic": -40, + "dstab": 62, + "dslash": 85, + "dcrush": 62, + "dmagic": -10, + "drange": 67, + "str": 4 + } + }, + "20515": { + "name": "Penance skirt (broken)", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 15, + "dstab": 26, + "dslash": 21, + "dcrush": 28, + "dmagic": 19, + "drange": 26 + } + }, + "20517": { + "name": "Elder chaos top", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 4, + "amagic": 10, + "dmagic": 8 + } + }, + "20520": { + "name": "Elder chaos robe", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 7, + "amagic": 6, + "dmagic": 6 + } + }, + "20523": { + "name": "Catalytic rune pack" + }, + "20524": { + "name": "Elemental rune pack" + }, + "20525": { + "name": "Adamant arrow pack" + }, + "20526": { + "name": "Bloody key" + }, + "20527": { + "name": "Survival token" + }, + "20537": { + "name": "Saradomin halo (broken)", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "dstab": 11, + "dslash": 12, + "dcrush": 10, + "dmagic": 11, + "drange": -1, + "prayer": 3 + } + }, + "20539": { + "name": "Zamorak halo (broken)", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "dstab": 11, + "dslash": 12, + "dcrush": 10, + "dmagic": 11, + "drange": -1, + "prayer": 3 + } + }, + "20541": { + "name": "Guthix halo (broken)", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "dstab": 11, + "dslash": 12, + "dcrush": 10, + "dmagic": 11, + "drange": -1, + "prayer": 3 + } + }, + "20543": { + "name": "Reward casket (elite)", + "equipable": true, + "weight": 5.0 + }, + "20544": { + "name": "Reward casket (hard)", + "weight": 5.0 + }, + "20545": { + "name": "Reward casket (medium)", + "weight": 5.0 + }, + "20546": { + "name": "Reward casket (easy)", + "weight": 5.0 + }, + "20547": { + "name": "Monkfish", + "weight": 0.4 + }, + "20548": { + "name": "Super energy(4)", + "weight": 0.035 + }, + "20549": { + "name": "Super energy(3)", + "weight": 0.03 + }, + "20550": { + "name": "Super energy(2)", + "weight": 0.025 + }, + "20551": { + "name": "Super energy(1)", + "weight": 0.02 + }, + "20552": { + "name": "Rune battleaxe", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 48, + "acrush": 43, + "drange": -1, + "str": 64, + "aspeed": 6 + } + }, + "20553": { + "name": "Beginner wand", + "equipable": true, + "weight": 0.283, + "equipment": { + "slot": 3, + "amagic": 5, + "dmagic": 5, + "aspeed": 4 + } + }, + "20554": { + "name": "Toktz-xil-ak", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 47, + "aslash": 38, + "acrush": -2, + "dstab": 2, + "dslash": 3, + "str": 49, + "aspeed": 4 + } + }, + "20555": { + "name": "Rune 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 69, + "acrush": 50, + "amagic": -4, + "drange": -1, + "str": 70, + "aspeed": 7 + } + }, + "20556": { + "name": "Apprentice wand", + "equipable": true, + "weight": 0.255, + "equipment": { + "slot": 3, + "amagic": 10, + "dmagic": 10, + "aspeed": 4 + } + }, + "20557": { + "name": "Granite maul", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 3, + "acrush": 81, + "str": 79, + "aspeed": 7 + } + }, + "20558": { + "name": "Magic shortbow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 69, + "aspeed": 4 + } + }, + "20559": { + "name": "Dragon 2h sword", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 92, + "acrush": 80, + "amagic": -4, + "drange": -1, + "str": 93, + "aspeed": 7 + } + }, + "20560": { + "name": "Master wand", + "equipable": true, + "weight": 0.198, + "equipment": { + "slot": 3, + "amagic": 20, + "dmagic": 20, + "aspeed": 4 + } + }, + "20561": { + "name": "Adamant full helm", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "20562": { + "name": "Mystic hat", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "20563": { + "name": "Proselyte sallet", + "quest": true, + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19, + "prayer": 4 + } + }, + "20564": { + "name": "Proselyte hauberk", + "quest": true, + "equipable": true, + "weight": 8.618, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63, + "prayer": 8 + } + }, + "20565": { + "name": "Proselyte cuisse", + "quest": true, + "equipable": true, + "weight": 7.711, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 33, + "dslash": 31, + "dcrush": 29, + "dmagic": -4, + "drange": 31, + "prayer": 6 + } + }, + "20566": { + "name": "Red d'hide body", + "equipable": true, + "weight": 6.803, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 25, + "dstab": 50, + "dslash": 42, + "dcrush": 55, + "dmagic": 40, + "drange": 50 + } + }, + "20567": { + "name": "Red d'hide chaps", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 14, + "dstab": 28, + "dslash": 22, + "dcrush": 30, + "dmagic": 20, + "drange": 28 + } + }, + "20568": { + "name": "Splitbark helm", + "equipable": true, + "weight": 0.907, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": -2, + "dstab": 10, + "dslash": 9, + "dcrush": 11, + "dmagic": 3 + } + }, + "20571": { + "name": "Warrior helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "aslash": 5, + "amagic": -5, + "arange": -5, + "dstab": 31, + "dslash": 33, + "dcrush": 29, + "drange": 30 + } + }, + "20572": { + "name": "Archer helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": -5, + "arange": 6, + "dstab": 6, + "dslash": 8, + "dcrush": 10, + "dmagic": 6, + "drange": 6 + } + }, + "20573": { + "name": "Farseer helm", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 0, + "astab": -5, + "aslash": -5, + "acrush": -5, + "amagic": 6, + "arange": -5, + "dstab": 8, + "dslash": 10, + "dcrush": 12, + "dmagic": 6 + } + }, + "20574": { + "name": "Infinity top", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 4, + "amagic": 22, + "dmagic": 22 + } + }, + "20575": { + "name": "Infinity bottoms", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 7, + "amagic": 17, + "dmagic": 17 + } + }, + "20576": { + "name": "3rd age robe top", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 4, + "amagic": 24, + "dmagic": 24 + } + }, + "20577": { + "name": "3rd age robe", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 19, + "dmagic": 19 + } + }, + "20578": { + "name": "Climbing boots", + "quest": true, + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 2, + "dcrush": 2, + "str": 2 + } + }, + "20579": { + "name": "Mystic boots", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 10, + "amagic": 3, + "dmagic": 3 + } + }, + "20580": { + "name": "Snakeskin boots", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "amagic": -10, + "arange": 3, + "dstab": 1, + "dslash": 1, + "dcrush": 2, + "dmagic": 1 + } + }, + "20581": { + "name": "Mithril gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 6, + "aslash": 6, + "acrush": 6, + "amagic": 3, + "arange": 6, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 3, + "drange": 6, + "str": 6 + } + }, + "20582": { + "name": "Adamant gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 7, + "aslash": 7, + "acrush": 7, + "amagic": 4, + "arange": 7, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "dmagic": 4, + "drange": 7, + "str": 7 + } + }, + "20583": { + "name": "Rune gloves", + "equipable": true, + "weight": 0.226, + "equipment": { + "slot": 9, + "astab": 8, + "aslash": 8, + "acrush": 8, + "amagic": 4, + "arange": 8, + "dstab": 8, + "dslash": 8, + "dcrush": 8, + "dmagic": 4, + "drange": 8, + "str": 8 + } + }, + "20584": { + "name": "Amulet of accuracy", + "quest": true, + "equipable": true, + "equipment": { + "slot": 2, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 4, + "arange": 4 + } + }, + "20585": { + "name": "Amulet of power", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 6, + "aslash": 6, + "acrush": 6, + "amagic": 6, + "arange": 6, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6, + "str": 6, + "prayer": 1 + } + }, + "20586": { + "name": "Amulet of glory", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "20590": { + "name": "Stale baguette", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "20593": { + "name": "Armadyl godsword", + "equipable": true, + "weight": 11.0, + "equipment": { + "slot": 3, + "aslash": 132, + "acrush": 80, + "str": 132, + "prayer": 8, + "aspeed": 6 + } + }, + "20594": { + "name": "Bank filler" + }, + "20595": { + "name": "Elder chaos hood", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0, + "amagic": 5, + "dmagic": 4 + } + }, + "20598": { + "name": "Ahrim's robetop", + "equipable": true, + "weight": 4.535, + "equipment": { + "slot": 4, + "amagic": 30, + "arange": -10, + "dstab": 52, + "dslash": 37, + "dcrush": 63, + "dmagic": 30 + } + }, + "20599": { + "name": "Ahrim's robeskirt", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 7, + "amagic": 22, + "arange": -7, + "dstab": 33, + "dslash": 30, + "dcrush": 36, + "dmagic": 22 + } + }, + "20600": { + "name": "Rune arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 49 + } + }, + "20607": { + "name": "Rune arrow pack" + }, + "20608": { + "name": "Bloodier key" + }, + "20609": { + "name": "Fairy enchantment" + }, + "20611": { + "name": "Ancient signet" + }, + "20613": { + "name": "Lunar signet" + }, + "20615": { + "name": "Arceuus signet" + }, + "20655": { + "name": "Ring of suffering (r)", + "equipable": true, + "equipment": { + "slot": 12, + "dstab": 10, + "dslash": 10, + "dcrush": 10, + "dmagic": 10, + "drange": 10, + "prayer": 2 + } + }, + "20657": { + "name": "Ring of suffering (ri)", + "equipable": true, + "equipment": { + "slot": 12, + "dstab": 20, + "dslash": 20, + "dcrush": 20, + "dmagic": 20, + "drange": 20, + "prayer": 4 + } + }, + "20695": { + "name": "Bruma root", + "weight": 2.0 + }, + "20696": { + "name": "Bruma kindling", + "weight": 2.0 + }, + "20697": { + "name": "Rejuvenation potion (unf)" + }, + "20698": { + "name": "Bruma herb" + }, + "20699": { + "name": "Rejuvenation potion (4)" + }, + "20700": { + "name": "Rejuvenation potion (3)" + }, + "20701": { + "name": "Rejuvenation potion (2)" + }, + "20702": { + "name": "Rejuvenation potion (1)" + }, + "20703": { + "name": "Supply crate", + "weight": 4.0 + }, + "20704": { + "name": "Pyromancer garb", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 4 + } + }, + "20706": { + "name": "Pyromancer robe", + "equipable": true, + "weight": 0.18, + "equipment": { + "slot": 7 + } + }, + "20708": { + "name": "Pyromancer hood", + "equipable": true, + "weight": 0.18, + "equipment": { + "slot": 0 + } + }, + "20710": { + "name": "Pyromancer boots", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 10 + } + }, + "20712": { + "name": "Warm gloves", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 9 + } + }, + "20714": { + "name": "Tome of fire", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "amagic": 8, + "dmagic": 8 + } + }, + "20716": { + "name": "Tome of fire (empty)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 5, + "amagic": 8, + "dmagic": 8 + } + }, + "20718": { + "name": "Burnt page" + }, + "20720": { + "name": "Bruma torch", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "20722": { + "name": "Emerald lantern", + "quest": true, + "weight": 1.3 + }, + "20724": { + "name": "Imbued heart", + "weight": 0.3 + }, + "20727": { + "name": "Leaf-bladed battleaxe", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 72, + "acrush": 72, + "drange": -1, + "str": 92, + "aspeed": 5 + } + }, + "20730": { + "name": "Mist battlestaff", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "20733": { + "name": "Mystic mist staff", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "20736": { + "name": "Dust battlestaff", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "20739": { + "name": "Mystic dust staff", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "20742": { + "name": "Empty jug pack" + }, + "20747": { + "name": "Bologa's blessing", + "equipable": true + }, + "20749": { + "name": "Zamorak's grapes", + "weight": 0.25 + }, + "20752": { + "name": "Zamorak's unfermented wine", + "weight": 1.0 + }, + "20754": { + "name": "Giant key" + }, + "20756": { + "name": "Hill giant club", + "equipable": true, + "weight": 3.6, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": 50, + "acrush": 65, + "amagic": -4, + "drange": -1, + "str": 70, + "aspeed": 7 + } + }, + "20760": { + "name": "Ardougne max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "astab": 6, + "amagic": 6, + "dstab": 6, + "dmagic": 6, + "prayer": 6 + } + }, + "20764": { + "name": "Ardougne max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "20773": { + "name": "Banshee mask" + }, + "20775": { + "name": "Banshee top" + }, + "20777": { + "name": "Banshee robe", + "weight": 0.5 + }, + "20779": { + "name": "Hunting knife" + }, + "20782": { + "name": "Bandos godsword", + "quest": true, + "weight": 10.0 + }, + "20784": { + "name": "Dragon claws", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 41, + "aslash": 57, + "acrush": -4, + "dstab": 13, + "dslash": 26, + "dcrush": 7, + "str": 56, + "aspeed": 4 + } + }, + "20785": { + "name": "Dragon warhammer", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 95, + "amagic": -4, + "str": 85, + "aspeed": 6 + } + }, + "20786": { + "name": "Ring of wealth (i5)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "20787": { + "name": "Ring of wealth (i4)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "20788": { + "name": "Ring of wealth (i3)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "20789": { + "name": "Ring of wealth (i2)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "20790": { + "name": "Ring of wealth (i1)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "20791": { + "name": "Extra supply crate", + "weight": 4.0 + }, + "20792": { + "name": "Hardcore ironman helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "20794": { + "name": "Hardcore ironman platebody", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "20796": { + "name": "Hardcore ironman platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "20798": { + "name": "Smelly journal" + }, + "20799": { + "name": "Kindling" + }, + "20800": { + "name": "Empty gourd vial" + }, + "20801": { + "name": "Water-filled gourd vial" + }, + "20802": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "20832": { + "name": "Snow globe", + "equipable": true + }, + "20834": { + "name": "Sack of presents", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "20836": { + "name": "Giant present", + "equipable": true, + "weight": 15.0, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "20838": { + "name": "Corrupted helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "20840": { + "name": "Corrupted platebody", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 21, + "dslash": 20, + "dcrush": 12, + "dmagic": -6, + "drange": 20 + } + }, + "20842": { + "name": "Corrupted platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "20844": { + "name": "Corrupted plateskirt", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "20846": { + "name": "Corrupted kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 8, + "dslash": 10, + "dcrush": 9, + "dmagic": -1, + "drange": 9 + } + }, + "20849": { + "name": "Dragon thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 36, + "rstr": 47, + "aspeed": 5 + } + }, + "20853": { + "name": "Cave worms" + }, + "20854": { + "name": "Burnt fish", + "weight": 0.4 + }, + "20855": { + "name": "Raw pysk fish (0)", + "weight": 0.4 + }, + "20856": { + "name": "Pysk fish (0)", + "weight": 0.4 + }, + "20857": { + "name": "Raw suphi fish (1)", + "weight": 0.4 + }, + "20858": { + "name": "Suphi fish (1)", + "weight": 0.4 + }, + "20859": { + "name": "Raw leckish fish (2)", + "weight": 0.4 + }, + "20860": { + "name": "Leckish fish (2)", + "weight": 0.4 + }, + "20861": { + "name": "Raw brawk fish (3)", + "weight": 0.4 + }, + "20862": { + "name": "Brawk fish (3)", + "weight": 0.4 + }, + "20863": { + "name": "Raw mycil fish (4)", + "weight": 0.4 + }, + "20864": { + "name": "Mycil fish (4)", + "weight": 0.4 + }, + "20865": { + "name": "Raw roqed fish (5)", + "weight": 0.4 + }, + "20866": { + "name": "Roqed fish (5)", + "weight": 0.4 + }, + "20867": { + "name": "Raw kyren fish (6)", + "weight": 0.4 + }, + "20868": { + "name": "Kyren fish (6)", + "weight": 0.4 + }, + "20869": { + "name": "Burnt bat", + "weight": 0.4 + }, + "20870": { + "name": "Raw guanic bat (0)", + "weight": 0.4 + }, + "20871": { + "name": "Guanic bat (0)", + "weight": 0.4 + }, + "20872": { + "name": "Raw prael bat (1)", + "weight": 0.4 + }, + "20873": { + "name": "Prael bat (1)", + "weight": 0.4 + }, + "20874": { + "name": "Raw giral bat (2)", + "weight": 0.4 + }, + "20875": { + "name": "Giral bat (2)", + "weight": 0.4 + }, + "20876": { + "name": "Raw phluxia bat (3)", + "weight": 0.4 + }, + "20877": { + "name": "Phluxia bat (3)", + "weight": 0.4 + }, + "20878": { + "name": "Raw kryket bat (4)", + "weight": 0.4 + }, + "20879": { + "name": "Kryket bat (4)", + "weight": 0.4 + }, + "20880": { + "name": "Raw murng bat (5)", + "weight": 0.4 + }, + "20881": { + "name": "Murng bat (5)", + "weight": 0.4 + }, + "20882": { + "name": "Raw psykk bat (6)", + "weight": 0.4 + }, + "20883": { + "name": "Psykk bat (6)", + "weight": 0.4 + }, + "20884": { + "name": "Keystone crystal" + }, + "20885": { + "name": "Cavern grubs" + }, + "20886": { + "name": "Creature keeper's journal" + }, + "20888": { + "name": "Nistirio's manifesto" + }, + "20890": { + "name": "Tekton's journal" + }, + "20892": { + "name": "Medivaemia blossom" + }, + "20893": { + "name": "Transdimensional notes" + }, + "20895": { + "name": "Vanguard judgement" + }, + "20897": { + "name": "Houndmaster's diary" + }, + "20899": { + "name": "Dark journal" + }, + "20901": { + "name": "Grimy noxifer" + }, + "20902": { + "name": "Noxifer" + }, + "20903": { + "name": "Noxifer seed" + }, + "20904": { + "name": "Grimy golpar" + }, + "20905": { + "name": "Golpar" + }, + "20906": { + "name": "Golpar seed" + }, + "20907": { + "name": "Grimy buchu leaf" + }, + "20908": { + "name": "Buchu leaf" + }, + "20909": { + "name": "Buchu seed" + }, + "20910": { + "name": "Stinkhorn mushroom" + }, + "20911": { + "name": "Endarkened juice" + }, + "20912": { + "name": "Cicely" + }, + "20913": { + "name": "Elder (-)(1)" + }, + "20914": { + "name": "Elder (-)(2)" + }, + "20915": { + "name": "Elder (-)(3)" + }, + "20916": { + "name": "Elder (-)(4)" + }, + "20917": { + "name": "Elder potion (1)" + }, + "20918": { + "name": "Elder potion (2)" + }, + "20919": { + "name": "Elder potion (3)" + }, + "20920": { + "name": "Elder potion (4)" + }, + "20921": { + "name": "Elder (+)(1)" + }, + "20922": { + "name": "Elder (+)(2)" + }, + "20923": { + "name": "Elder (+)(3)" + }, + "20924": { + "name": "Elder (+)(4)" + }, + "20925": { + "name": "Twisted (-)(1)" + }, + "20926": { + "name": "Twisted (-)(2)" + }, + "20927": { + "name": "Twisted (-)(3)" + }, + "20928": { + "name": "Twisted (-)(4)" + }, + "20929": { + "name": "Twisted potion (1)" + }, + "20930": { + "name": "Twisted potion (2)" + }, + "20931": { + "name": "Twisted potion (3)" + }, + "20932": { + "name": "Twisted potion (4)" + }, + "20933": { + "name": "Twisted (+)(1)" + }, + "20934": { + "name": "Twisted (+)(2)" + }, + "20935": { + "name": "Twisted (+)(3)" + }, + "20936": { + "name": "Twisted (+)(4)" + }, + "20937": { + "name": "Kodai (-)(1)" + }, + "20938": { + "name": "Kodai (-)(2)" + }, + "20939": { + "name": "Kodai (-)(3)" + }, + "20940": { + "name": "Kodai (-)(4)" + }, + "20941": { + "name": "Kodai potion (1)" + }, + "20942": { + "name": "Kodai potion (2)" + }, + "20943": { + "name": "Kodai potion (3)" + }, + "20944": { + "name": "Kodai potion (4)" + }, + "20945": { + "name": "Kodai (+)(1)" + }, + "20946": { + "name": "Kodai (+)(2)" + }, + "20947": { + "name": "Kodai (+)(3)" + }, + "20948": { + "name": "Kodai (+)(4)" + }, + "20949": { + "name": "Revitalisation (-)(1)" + }, + "20950": { + "name": "Revitalisation (-)(2)" + }, + "20951": { + "name": "Revitalisation (-)(3)" + }, + "20952": { + "name": "Revitalisation (-)(4)" + }, + "20953": { + "name": "Revitalisation potion (1)" + }, + "20954": { + "name": "Revitalisation potion (2)" + }, + "20955": { + "name": "Revitalisation potion (3)" + }, + "20956": { + "name": "Revitalisation potion (4)" + }, + "20957": { + "name": "Revitalisation (+)(1)" + }, + "20958": { + "name": "Revitalisation (+)(2)" + }, + "20959": { + "name": "Revitalisation (+)(3)" + }, + "20960": { + "name": "Revitalisation (+)(4)" + }, + "20961": { + "name": "Prayer enhance (-)(1)" + }, + "20962": { + "name": "Prayer enhance (-)(2)" + }, + "20963": { + "name": "Prayer enhance (-)(3)" + }, + "20964": { + "name": "Prayer enhance (-)(4)" + }, + "20965": { + "name": "Prayer enhance (1)" + }, + "20966": { + "name": "Prayer enhance (2)" + }, + "20967": { + "name": "Prayer enhance (3)" + }, + "20968": { + "name": "Prayer enhance (4)" + }, + "20969": { + "name": "Prayer enhance (+)(1)" + }, + "20970": { + "name": "Prayer enhance (+)(2)" + }, + "20971": { + "name": "Prayer enhance (+)(3)" + }, + "20972": { + "name": "Prayer enhance (+)(4)" + }, + "20973": { + "name": "Xeric's aid (-)(1)" + }, + "20974": { + "name": "Xeric's aid (-)(2)" + }, + "20975": { + "name": "Xeric's aid (-)(3)" + }, + "20976": { + "name": "Xeric's aid (-)(4)" + }, + "20977": { + "name": "Xeric's aid (1)" + }, + "20978": { + "name": "Xeric's aid (2)" + }, + "20979": { + "name": "Xeric's aid (3)" + }, + "20980": { + "name": "Xeric's aid (4)" + }, + "20981": { + "name": "Xeric's aid (+)(1)" + }, + "20982": { + "name": "Xeric's aid (+)(2)" + }, + "20983": { + "name": "Xeric's aid (+)(3)" + }, + "20984": { + "name": "Xeric's aid (+)(4)" + }, + "20985": { + "name": "Overload (-)(1)" + }, + "20986": { + "name": "Overload (-)(2)" + }, + "20987": { + "name": "Overload (-)(3)" + }, + "20988": { + "name": "Overload (-)(4)" + }, + "20989": { + "name": "Overload (1)" + }, + "20990": { + "name": "Overload (2)" + }, + "20991": { + "name": "Overload (3)" + }, + "20992": { + "name": "Overload (4)" + }, + "20993": { + "name": "Overload (+)(1)" + }, + "20994": { + "name": "Overload (+)(2)" + }, + "20995": { + "name": "Overload (+)(3)" + }, + "20996": { + "name": "Overload (+)(4)" + }, + "20997": { + "name": "Twisted bow", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "arange": 70, + "rstr": 20, + "prayer": 4, + "aspeed": 6 + } + }, + "21000": { + "name": "Twisted buckler", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "astab": -7, + "aslash": -8, + "acrush": -7, + "amagic": -10, + "arange": 18, + "dstab": 22, + "dslash": 24, + "dcrush": 22, + "dmagic": 26, + "drange": 58 + } + }, + "21003": { + "name": "Elder maul", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 3, + "acrush": 135, + "amagic": -4, + "str": 147, + "aspeed": 6 + } + }, + "21006": { + "name": "Kodai wand", + "equipable": true, + "equipment": { + "slot": 3, + "amagic": 28, + "dslash": 3, + "dcrush": 3, + "dmagic": 20, + "mdmg": 15, + "aspeed": 4 + } + }, + "21009": { + "name": "Dragon sword", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 65, + "aslash": 55, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 63, + "aspeed": 4 + } + }, + "21012": { + "name": "Dragon hunter crossbow", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 3, + "arange": 95, + "aspeed": 6 + } + }, + "21015": { + "name": "Dinh's bulwark", + "equipable": true, + "weight": 30.0, + "equipment": { + "slot": 3, + "acrush": 110, + "dstab": 141, + "dslash": 145, + "dcrush": 145, + "dmagic": 18, + "drange": 148, + "str": 38, + "aspeed": 7 + } + }, + "21018": { + "name": "Ancestral hat", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 0, + "amagic": 8, + "arange": -2, + "dstab": 12, + "dslash": 11, + "dcrush": 13, + "dmagic": 5, + "mdmg": 2 + } + }, + "21021": { + "name": "Ancestral robe top", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": 35, + "arange": -8, + "dstab": 42, + "dslash": 31, + "dcrush": 51, + "dmagic": 28, + "mdmg": 2 + } + }, + "21024": { + "name": "Ancestral robe bottom", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 7, + "amagic": 26, + "arange": -7, + "dstab": 27, + "dslash": 24, + "dcrush": 30, + "dmagic": 20, + "mdmg": 2 + } + }, + "21027": { + "name": "Dark relic" + }, + "21028": { + "name": "Dragon harpoon", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "21031": { + "name": "Infernal harpoon", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "21033": { + "name": "Infernal harpoon (uncharged)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 38, + "aslash": 32, + "dslash": 1, + "str": 42, + "aspeed": 5 + } + }, + "21034": { + "name": "Dexterous prayer scroll" + }, + "21036": { + "name": "Mallignum root plank", + "weight": 1.0 + }, + "21043": { + "name": "Kodai insignia" + }, + "21046": { + "name": "Ancient tablet", + "weight": 2.0 + }, + "21047": { + "name": "Torn prayer scroll" + }, + "21049": { + "name": "Ancestral robes set" + }, + "21052": { + "name": "Manor key", + "quest": true + }, + "21053": { + "name": "Ruby key", + "quest": true + }, + "21054": { + "name": "Emerald key", + "quest": true + }, + "21055": { + "name": "Sapphire key", + "quest": true + }, + "21056": { + "name": "Notes", + "quest": true + }, + "21057": { + "name": "Notes", + "quest": true + }, + "21058": { + "name": "Notes", + "quest": true + }, + "21059": { + "name": "Killer's knife", + "quest": true, + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "21060": { + "name": "Bandos godsword", + "quest": true, + "weight": 10.0 + }, + "21061": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21063": { + "name": "Graceful hood", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21064": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "21066": { + "name": "Graceful cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "21067": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "21069": { + "name": "Graceful top", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "21070": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "21072": { + "name": "Graceful legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "21073": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21075": { + "name": "Graceful gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21076": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "21078": { + "name": "Graceful boots", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "21079": { + "name": "Arcane prayer scroll" + }, + "21081": { + "name": "Opal ring", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21084": { + "name": "Jade ring", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21087": { + "name": "Topaz ring", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21090": { + "name": "Opal necklace", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21093": { + "name": "Jade necklace", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21096": { + "name": "Topaz necklace", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21099": { + "name": "Opal amulet (u)" + }, + "21102": { + "name": "Jade amulet (u)" + }, + "21105": { + "name": "Topaz amulet (u)" + }, + "21108": { + "name": "Opal amulet", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21111": { + "name": "Jade amulet", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21114": { + "name": "Topaz amulet", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21117": { + "name": "Opal bracelet", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21120": { + "name": "Jade bracelet", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21123": { + "name": "Topaz bracelet", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21126": { + "name": "Ring of pursuit", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21129": { + "name": "Ring of returning(5)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21132": { + "name": "Ring of returning(4)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21134": { + "name": "Ring of returning(3)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21136": { + "name": "Ring of returning(2)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21138": { + "name": "Ring of returning(1)", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21140": { + "name": "Efaritay's aid", + "equipable": true, + "equipment": { + "slot": 12 + } + }, + "21143": { + "name": "Dodgy necklace", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21146": { + "name": "Necklace of passage(5)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21149": { + "name": "Necklace of passage(4)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21151": { + "name": "Necklace of passage(3)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21153": { + "name": "Necklace of passage(2)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21155": { + "name": "Necklace of passage(1)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21157": { + "name": "Necklace of faith", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21160": { + "name": "Amulet of bounty", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21163": { + "name": "Amulet of chemistry" + }, + "21166": { + "name": "Burning amulet(5)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21169": { + "name": "Burning amulet(4)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21171": { + "name": "Burning amulet(3)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21173": { + "name": "Burning amulet(2)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21175": { + "name": "Burning amulet(1)", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21177": { + "name": "Expeditious bracelet", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21180": { + "name": "Flamtaer bracelet", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21183": { + "name": "Bracelet of slaughter", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21198": { + "name": "Lava battlestaff", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 28, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 5 + } + }, + "21200": { + "name": "Mystic lava staff", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 50, + "aspeed": 5 + } + }, + "21202": { + "name": "Lava staff upgrade kit" + }, + "21205": { + "name": "Elder maul", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 3, + "acrush": 135, + "amagic": -4, + "str": 147, + "aspeed": 6 + } + }, + "21206": { + "name": "Dragon sword", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 65, + "aslash": 55, + "acrush": -2, + "dslash": 2, + "dcrush": 1, + "str": 63, + "aspeed": 4 + } + }, + "21207": { + "name": "Dragon thrownaxe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 36, + "rstr": 47, + "aspeed": 5 + } + }, + "21208": { + "name": "Invitation list" + }, + "21209": { + "name": "Birthday balloons", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "21211": { + "name": "4th birthday hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21214": { + "name": "Easter egg helm", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21216": { + "name": "Fruity easter egg" + }, + "21217": { + "name": "Fresh easter egg" + }, + "21218": { + "name": "Bitter easter egg" + }, + "21219": { + "name": "Earthy easter egg" + }, + "21220": { + "name": "Spicy easter egg" + }, + "21221": { + "name": "Meaty easter egg" + }, + "21222": { + "name": "Salted easter egg" + }, + "21223": { + "name": "Rich easter egg" + }, + "21224": { + "name": "Fluffy easter egg" + }, + "21225": { + "name": "Smoked easter egg" + }, + "21226": { + "name": "Fishy easter egg" + }, + "21227": { + "name": "Crunchy easter egg" + }, + "21228": { + "name": "Fruity chocolate mix" + }, + "21229": { + "name": "Fresh chocolate mix" + }, + "21230": { + "name": "Bitter chocolate mix" + }, + "21231": { + "name": "Earthy chocolate mix" + }, + "21232": { + "name": "Spicy chocolate mix" + }, + "21233": { + "name": "Meaty chocolate mix" + }, + "21235": { + "name": "Rich chocolate mix" + }, + "21236": { + "name": "Fluffy chocolate mix" + }, + "21237": { + "name": "Smoked chocolate mix" + }, + "21238": { + "name": "Fishy chocolate mix" + }, + "21239": { + "name": "Crunchy chocolate mix" + }, + "21240": { + "name": "Wester banana" + }, + "21241": { + "name": "Wester papaya" + }, + "21242": { + "name": "Wester lemon" + }, + "21243": { + "name": "Bucket of wester sand" + }, + "21244": { + "name": "Wester spices" + }, + "21245": { + "name": "Beef fillet" + }, + "21246": { + "name": "Sea salt" + }, + "21247": { + "name": "Gold fragment" + }, + "21248": { + "name": "Fluffy feathers" + }, + "21249": { + "name": "Wester fish" + }, + "21251": { + "name": "Wester chocolate" + }, + "21252": { + "name": "Egg mould" + }, + "21255": { + "name": "Slayer's staff (e)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 12, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 35, + "aspeed": 4 + } + }, + "21257": { + "name": "Slayer's enchantment" + }, + "21259": { + "name": "Enchanted scroll", + "quest": true + }, + "21260": { + "name": "Enchanted quill", + "quest": true + }, + "21261": { + "name": "Mysterious orb", + "quest": true + }, + "21262": { + "name": "Antique lamp", + "quest": true, + "weight": 0.1 + }, + "21263": { + "name": "Copper's crimson collar", + "quest": true + }, + "21264": { + "name": "Purple slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "21266": { + "name": "Purple slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "21268": { + "name": "Slayer ring (eternal)" + }, + "21270": { + "name": "Eternal gem" + }, + "21275": { + "name": "Dark claw" + }, + "21276": { + "name": "Skull sceptre (i)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "aslash": -1, + "acrush": 7, + "amagic": 4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 4, + "str": 3, + "aspeed": 5 + } + }, + "21279": { + "name": "Obsidian armour set" + }, + "21282": { + "name": "Infernal max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "21285": { + "name": "Infernal max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 1, + "arange": 1, + "dstab": 12, + "dslash": 12, + "dcrush": 12, + "dmagic": 12, + "drange": 12, + "str": 8, + "prayer": 2 + } + }, + "21287": { + "name": "Infernal cape (broken)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 1, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 1, + "arange": 1, + "dstab": 12, + "dslash": 12, + "dcrush": 12, + "dmagic": 12, + "drange": 12, + "str": 8, + "prayer": 2 + } + }, + "21289": { + "name": "Infernal max cape (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 1, + "arange": 1, + "dstab": 12, + "dslash": 12, + "dcrush": 12, + "dmagic": 12, + "drange": 12, + "str": 8, + "prayer": 2 + } + }, + "21293": { + "name": "Infernal eel" + }, + "21295": { + "name": "Infernal cape", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 1, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 1, + "arange": 1, + "dstab": 12, + "dslash": 12, + "dcrush": 12, + "dmagic": 12, + "drange": 12, + "str": 8, + "prayer": 2 + } + }, + "21298": { + "name": "Obsidian helmet", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "dstab": 25, + "dslash": 23, + "dcrush": 26, + "drange": 24, + "str": 3 + } + }, + "21301": { + "name": "Obsidian platebody", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 4, + "dstab": 55, + "dslash": 78, + "dcrush": 56, + "dmagic": -15, + "drange": 60, + "str": 3 + } + }, + "21304": { + "name": "Obsidian platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "dstab": 46, + "dslash": 43, + "dcrush": 41, + "dmagic": -10, + "drange": 40, + "str": 1 + } + }, + "21307": { + "name": "Rogue's equipment crate", + "weight": 0.1 + }, + "21308": { + "name": "Red rainbow strand" + }, + "21309": { + "name": "Orange rainbow strand" + }, + "21310": { + "name": "Yellow rainbow strand" + }, + "21311": { + "name": "Green rainbow strand" + }, + "21312": { + "name": "Blue rainbow strand" + }, + "21313": { + "name": "Purple rainbow strand" + }, + "21314": { + "name": "Rainbow scarf", + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "21316": { + "name": "Amethyst broad bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 115 + } + }, + "21318": { + "name": "Amethyst javelin", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 135 + } + }, + "21320": { + "name": "Amethyst javelin(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 135 + } + }, + "21322": { + "name": "Amethyst javelin(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 135 + } + }, + "21324": { + "name": "Amethyst javelin(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 135 + } + }, + "21326": { + "name": "Amethyst arrow", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "21328": { + "name": "Amethyst fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "21330": { + "name": "Amethyst fire arrows", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "21332": { + "name": "Amethyst arrow(p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "21334": { + "name": "Amethyst arrow(p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "21336": { + "name": "Amethyst arrow(p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 55 + } + }, + "21338": { + "name": "Amethyst bolt tips" + }, + "21341": { + "name": "Unidentified minerals" + }, + "21343": { + "name": "Mining gloves", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9 + } + }, + "21345": { + "name": "Superior mining gloves", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9 + } + }, + "21347": { + "name": "Amethyst", + "weight": 1.3 + }, + "21350": { + "name": "Amethyst arrowtips" + }, + "21352": { + "name": "Amethyst javelin heads" + }, + "21354": { + "name": "Hand fan", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "21356": { + "name": "Minnow" + }, + "21387": { + "name": "Master scroll book (empty)", + "weight": 1.0 + }, + "21389": { + "name": "Master scroll book", + "weight": 1.0 + }, + "21392": { + "name": "Expert mining gloves", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 9 + } + }, + "21394": { + "name": "Karambwanji", + "weight": 0.12 + }, + "21439": { + "name": "Champion's cape", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "21469": { + "name": "Teak seedling", + "weight": 0.9 + }, + "21471": { + "name": "Mahogany seedling", + "weight": 0.9 + }, + "21473": { + "name": "Teak seedling (w)" + }, + "21475": { + "name": "Mahogany seedling (w)" + }, + "21477": { + "name": "Teak sapling", + "weight": 0.9 + }, + "21480": { + "name": "Mahogany sapling", + "weight": 0.9 + }, + "21483": { + "name": "Ultracompost", + "weight": 3.0 + }, + "21486": { + "name": "Teak seed" + }, + "21488": { + "name": "Mahogany seed" + }, + "21490": { + "name": "Seaweed spore" + }, + "21504": { + "name": "Giant seaweed", + "weight": 0.2 + }, + "21512": { + "name": "Bird house", + "weight": 0.4 + }, + "21515": { + "name": "Oak bird house", + "weight": 0.4 + }, + "21518": { + "name": "Willow bird house", + "weight": 0.4 + }, + "21521": { + "name": "Teak bird house", + "weight": 0.4 + }, + "21524": { + "name": "Clue scroll (elite)" + }, + "21525": { + "name": "Clue scroll (elite)" + }, + "21526": { + "name": "Clue scroll (hard)" + }, + "21527": { + "name": "Clue scroll (hard)" + }, + "21528": { + "name": "Sawmill proposal", + "quest": true + }, + "21529": { + "name": "Sawmill agreement", + "quest": true + }, + "21530": { + "name": "Bone charm", + "quest": true, + "weight": 2.0 + }, + "21531": { + "name": "Potion of sealegs", + "quest": true + }, + "21532": { + "name": "Iron ore fragment" + }, + "21533": { + "name": "Silver ore fragment" + }, + "21534": { + "name": "Coal fragment" + }, + "21535": { + "name": "Gold ore fragment" + }, + "21536": { + "name": "Mithril ore fragment" + }, + "21537": { + "name": "Adamantite ore fragment" + }, + "21538": { + "name": "Runite ore fragment" + }, + "21539": { + "name": "Heat-proof vessel", + "equipable": true, + "weight": 4.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "21540": { + "name": "Large rock", + "weight": 2.0 + }, + "21541": { + "name": "Volcanic mine teleport" + }, + "21543": { + "name": "Calcite" + }, + "21545": { + "name": "Pyrophosphite" + }, + "21547": { + "name": "Small enriched bone", + "weight": 0.3 + }, + "21549": { + "name": "Medium enriched bone", + "weight": 0.3 + }, + "21551": { + "name": "Large enriched bone", + "weight": 0.3 + }, + "21553": { + "name": "Rare enriched bone", + "weight": 0.3 + }, + "21555": { + "name": "Numulite" + }, + "21562": { + "name": "Unidentified small fossil", + "weight": 0.125 + }, + "21564": { + "name": "Unidentified medium fossil", + "weight": 0.25 + }, + "21566": { + "name": "Unidentified large fossil", + "weight": 0.5 + }, + "21568": { + "name": "Unidentified rare fossil" + }, + "21570": { + "name": "Small fossilised limbs", + "weight": 0.9 + }, + "21572": { + "name": "Small fossilised spine", + "weight": 0.9 + }, + "21574": { + "name": "Small fossilised ribs", + "weight": 0.9 + }, + "21576": { + "name": "Small fossilised pelvis", + "weight": 0.9 + }, + "21578": { + "name": "Small fossilised skull", + "weight": 0.9 + }, + "21580": { + "name": "Medium fossilised limbs", + "weight": 0.9 + }, + "21582": { + "name": "Medium fossilised spine", + "weight": 0.9 + }, + "21584": { + "name": "Medium fossilised ribs", + "weight": 0.9 + }, + "21586": { + "name": "Medium fossilised pelvis", + "weight": 0.9 + }, + "21588": { + "name": "Medium fossilised skull", + "weight": 0.9 + }, + "21590": { + "name": "Fossilised roots", + "weight": 0.9 + }, + "21592": { + "name": "Fossilised stump", + "weight": 0.9 + }, + "21594": { + "name": "Fossilised branch", + "weight": 0.9 + }, + "21596": { + "name": "Fossilised leaf", + "weight": 0.9 + }, + "21598": { + "name": "Fossilised mushroom", + "weight": 0.9 + }, + "21600": { + "name": "Large fossilised limbs", + "weight": 0.9 + }, + "21602": { + "name": "Large fossilised spine", + "weight": 0.9 + }, + "21604": { + "name": "Large fossilised ribs", + "weight": 0.9 + }, + "21606": { + "name": "Large fossilised pelvis", + "weight": 0.9 + }, + "21608": { + "name": "Large fossilised skull", + "weight": 0.9 + }, + "21610": { + "name": "Rare fossilised limbs", + "weight": 0.9 + }, + "21612": { + "name": "Rare fossilised spine", + "weight": 0.9 + }, + "21614": { + "name": "Rare fossilised ribs", + "weight": 0.9 + }, + "21616": { + "name": "Rare fossilised pelvis", + "weight": 0.9 + }, + "21618": { + "name": "Rare fossilised skull", + "weight": 0.9 + }, + "21620": { + "name": "Rare fossilised tusk", + "weight": 0.9 + }, + "21622": { + "name": "Volcanic ash" + }, + "21624": { + "name": "Hoop snake", + "weight": 0.4 + }, + "21626": { + "name": "Sulliuscep cap", + "weight": 0.9 + }, + "21629": { + "name": "Archaeologist's diary" + }, + "21631": { + "name": "Ancient diary" + }, + "21633": { + "name": "Ancient wyvern shield", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "astab": -10, + "aslash": -10, + "acrush": -10, + "amagic": 15, + "arange": -10, + "dstab": 22, + "dslash": 30, + "dcrush": 25, + "dmagic": 15, + "drange": -55, + "str": -2 + } + }, + "21634": { + "name": "Ancient wyvern shield", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "astab": -10, + "aslash": -10, + "acrush": -10, + "amagic": 15, + "arange": -10, + "dstab": 22, + "dslash": 30, + "dcrush": 25, + "dmagic": 15, + "drange": -55, + "str": -2 + } + }, + "21637": { + "name": "Wyvern visage", + "weight": 0.9 + }, + "21640": { + "name": "Antique lamp", + "quest": true + }, + "21641": { + "name": "Antique lamp", + "quest": true + }, + "21642": { + "name": "Antique lamp", + "quest": true + }, + "21643": { + "name": "Granite boots", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 15, + "dslash": 16, + "dcrush": 17, + "drange": 8, + "str": 3 + } + }, + "21646": { + "name": "Granite longsword", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 56, + "aslash": 65, + "acrush": -2, + "dslash": 3, + "dcrush": 2, + "str": 62, + "aspeed": 5 + } + }, + "21649": { + "name": "Merfolk trident", + "equipable": true, + "equipment": { + "slot": 3, + "astab": 8, + "aslash": 8, + "acrush": 8, + "dstab": 1, + "dslash": 1, + "str": 4, + "aspeed": 5 + } + }, + "21652": { + "name": "Drift net", + "weight": 1.0 + }, + "21655": { + "name": "Pufferfish", + "weight": -0.5 + }, + "21656": { + "name": "Mermaid's tear" + }, + "21662": { + "name": "Fossil island note book", + "quest": true + }, + "21664": { + "name": "Scribbled note" + }, + "21666": { + "name": "Partial note" + }, + "21668": { + "name": "Ancient note" + }, + "21670": { + "name": "Ancient writings" + }, + "21672": { + "name": "Experimental note" + }, + "21674": { + "name": "Paragraph of text" + }, + "21676": { + "name": "Musty smelling note" + }, + "21678": { + "name": "Hastily scrawled note" + }, + "21680": { + "name": "Old writing" + }, + "21682": { + "name": "Short note" + }, + "21684": { + "name": "Uncooked mushroom pie", + "weight": 0.5 + }, + "21687": { + "name": "Half a mushroom pie", + "weight": 0.2 + }, + "21690": { + "name": "Mushroom pie", + "weight": 0.4 + }, + "21693": { + "name": "Bowl of fish" + }, + "21695": { + "name": "Runefest shield", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5 + } + }, + "21697": { + "name": "Ash covered tome" + }, + "21698": { + "name": "Tzhaar air rune pack", + "weight": 4.5 + }, + "21701": { + "name": "Tzhaar water rune pack", + "weight": 4.5 + }, + "21704": { + "name": "Tzhaar earth rune pack", + "weight": 4.5 + }, + "21707": { + "name": "Tzhaar fire rune pack", + "weight": 4.5 + }, + "21710": { + "name": "Death note", + "quest": true + }, + "21711": { + "name": "Murky potion" + }, + "21712": { + "name": "Spectral potion" + }, + "21713": { + "name": "Tomberries" + }, + "21714": { + "name": "Tattered book" + }, + "21715": { + "name": "Note" + }, + "21716": { + "name": "Carved gem" + }, + "21717": { + "name": "Time bubble" + }, + "21718": { + "name": "Traiborn note", + "quest": true + }, + "21720": { + "name": "Jonas mask", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21722": { + "name": "Diving helmet", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 0 + } + }, + "21723": { + "name": "Diving apparatus", + "equipable": true, + "weight": 10.0, + "equipment": { + "slot": 1 + } + }, + "21724": { + "name": "Brittle key" + }, + "21726": { + "name": "Granite dust" + }, + "21728": { + "name": "Granite cannonball" + }, + "21730": { + "name": "Black tourmaline core", + "weight": 1.0 + }, + "21733": { + "name": "Guardian boots", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 32, + "dslash": 32, + "dcrush": 32, + "dmagic": -3, + "drange": 24, + "str": 3, + "prayer": 2 + } + }, + "21736": { + "name": "Granite gloves", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "astab": 5, + "aslash": 5, + "acrush": 9, + "amagic": -3, + "arange": -1, + "dstab": 8, + "dslash": 8, + "dcrush": 8, + "dmagic": -3, + "drange": 5, + "str": 7 + } + }, + "21739": { + "name": "Granite ring", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 12, + "dstab": 2, + "dslash": 2, + "dcrush": 2, + "dmagic": -2, + "drange": 8 + } + }, + "21742": { + "name": "Granite hammer", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 3, + "acrush": 57, + "amagic": -3, + "arange": -1, + "str": 56, + "aspeed": 4 + } + }, + "21745": { + "name": "Jar of stone", + "weight": 1.0 + }, + "21752": { + "name": "Granite ring (i)", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 12, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": -4, + "drange": 16 + } + }, + "21754": { + "name": "Rock thrownhammer" + }, + "21756": { + "name": "Varlamore envoy", + "quest": true + }, + "21758": { + "name": "Royal accord of twill", + "quest": true + }, + "21759": { + "name": "Hosidius favour certificate", + "quest": true + }, + "21760": { + "name": "Kharedst's memoirs", + "quest": true, + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 5, + "prayer": 1 + } + }, + "21762": { + "name": "Lunch by the lancalliums", + "quest": true + }, + "21764": { + "name": "The fisher's flute", + "quest": true + }, + "21766": { + "name": "History and hearsay", + "quest": true + }, + "21768": { + "name": "Jewellery of jubilation", + "quest": true + }, + "21770": { + "name": "A dark disposition", + "quest": true + }, + "21772": { + "name": "Secret page" + }, + "21774": { + "name": "Letter", + "quest": true + }, + "21775": { + "name": "Piscarilius favour certificate", + "quest": true + }, + "21776": { + "name": "Imbued saradomin max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 15, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 15, + "mdmg": 2 + } + }, + "21778": { + "name": "Imbued saradomin max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "21780": { + "name": "Imbued zamorak max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 15, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 15, + "mdmg": 2 + } + }, + "21782": { + "name": "Imbued zamorak max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "21784": { + "name": "Imbued guthix max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 15, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 15, + "mdmg": 2 + } + }, + "21786": { + "name": "Imbued guthix max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "21791": { + "name": "Imbued saradomin cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 15, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 15, + "mdmg": 2 + } + }, + "21793": { + "name": "Imbued guthix cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 15, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 15, + "mdmg": 2 + } + }, + "21795": { + "name": "Imbued zamorak cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 15, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 15, + "mdmg": 2 + } + }, + "21797": { + "name": "Justiciar's hand", + "quest": true, + "weight": 0.3 + }, + "21798": { + "name": "Ent's roots", + "quest": true, + "weight": 0.3 + }, + "21799": { + "name": "Demon's heart", + "quest": true, + "weight": 0.3 + }, + "21800": { + "name": "Enchanted symbol", + "quest": true + }, + "21802": { + "name": "Revenant cave teleport" + }, + "21804": { + "name": "Ancient crystal", + "weight": 13.0 + }, + "21807": { + "name": "Ancient emblem" + }, + "21810": { + "name": "Ancient totem" + }, + "21813": { + "name": "Ancient statuette" + }, + "21816": { + "name": "Bracelet of ethereum", + "weight": 0.2 + }, + "21817": { + "name": "Bracelet of ethereum (uncharged)", + "weight": 0.2 + }, + "21820": { + "name": "Revenant ether" + }, + "21837": { + "name": "Ogre artefact", + "quest": true + }, + "21838": { + "name": "Shaman mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "21847": { + "name": "Snow imp costume head", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21849": { + "name": "Snow imp costume body", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "21851": { + "name": "Snow imp costume legs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "21853": { + "name": "Snow imp costume tail", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "21855": { + "name": "Snow imp costume gloves", + "equipable": true, + "equipment": { + "slot": 9 + } + }, + "21857": { + "name": "Snow imp costume feet", + "equipable": true, + "equipment": { + "slot": 10 + } + }, + "21859": { + "name": "Wise old man's santa hat", + "equipable": true, + "equipment": { + "slot": 0 + } + }, + "21861": { + "name": "Enchanted curtains" + }, + "21862": { + "name": "Enchanted snowy curtains" + }, + "21863": { + "name": "Wise old man's teleport tablet" + }, + "21864": { + "name": "Snow sprite" + }, + "21865": { + "name": "Fine mesh net", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "21866": { + "name": "Santa suit" + }, + "21867": { + "name": "Santa suit (wet)" + }, + "21868": { + "name": "Santa suit (dry)" + }, + "21869": { + "name": "Logs and kindling", + "weight": 2.0 + }, + "21870": { + "name": "Promissory note" + }, + "21871": { + "name": "Santa's seal" + }, + "21872": { + "name": "Vault key" + }, + "21873": { + "name": "Empty sack" + }, + "21874": { + "name": "Bulging sack" + }, + "21875": { + "name": "Kristmas kebab", + "weight": 0.25 + }, + "21880": { + "name": "Wrath rune" + }, + "21882": { + "name": "Dragon armour set (lg)", + "weight": 6.0 + }, + "21885": { + "name": "Dragon armour set (sk)", + "weight": 6.0 + }, + "21888": { + "name": "Turquoise slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "21890": { + "name": "Turquoise slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "21892": { + "name": "Dragon platebody", + "equipable": true, + "weight": 11.3, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 109, + "dslash": 107, + "dcrush": 97, + "dmagic": -6, + "drange": 106 + } + }, + "21895": { + "name": "Dragon kiteshield", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 56, + "dslash": 60, + "dcrush": 58, + "dmagic": -1, + "drange": 58 + } + }, + "21898": { + "name": "Assembler max cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "arange": 8, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 8, + "drange": 2, + "rstr": 2 + } + }, + "21900": { + "name": "Assembler max hood", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0 + } + }, + "21902": { + "name": "Dragon crossbow", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 3, + "arange": 94, + "aspeed": 6 + } + }, + "21905": { + "name": "Dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21907": { + "name": "Vorkath's head", + "weight": 10.0 + }, + "21909": { + "name": "Vorkath's stuffed head", + "weight": 10.0 + }, + "21914": { + "name": "Ava's assembler (broken)", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 1, + "arange": 8, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 8, + "drange": 2, + "rstr": 2 + } + }, + "21916": { + "name": "Assembler max cape (broken)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "arange": 8, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 8, + "drange": 2, + "rstr": 2 + } + }, + "21918": { + "name": "Dragon limbs", + "weight": 3.0 + }, + "21921": { + "name": "Dragon crossbow (u)", + "weight": 2.0 + }, + "21924": { + "name": "Dragon bolts (p)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21926": { + "name": "Dragon bolts (p+)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21928": { + "name": "Dragon bolts (p++)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21930": { + "name": "Dragon bolts (unf)" + }, + "21932": { + "name": "Opal dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21934": { + "name": "Jade dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21936": { + "name": "Pearl dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21938": { + "name": "Topaz dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21940": { + "name": "Sapphire dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21942": { + "name": "Emerald dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21944": { + "name": "Ruby dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21946": { + "name": "Diamond dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21948": { + "name": "Dragonstone dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21950": { + "name": "Onyx dragon bolts (e)", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21952": { + "name": "Magic stock", + "weight": 3.0 + }, + "21955": { + "name": "Opal dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21957": { + "name": "Jade dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21959": { + "name": "Pearl dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21961": { + "name": "Topaz dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21963": { + "name": "Sapphire dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21965": { + "name": "Emerald dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21967": { + "name": "Ruby dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21969": { + "name": "Diamond dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21971": { + "name": "Dragonstone dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21973": { + "name": "Onyx dragon bolts", + "equipable": true, + "equipment": { + "slot": 13, + "rstr": 122 + } + }, + "21975": { + "name": "Crushed superior dragon bones" + }, + "21978": { + "name": "Super antifire potion(4)" + }, + "21981": { + "name": "Super antifire potion(3)" + }, + "21984": { + "name": "Super antifire potion(2)" + }, + "21987": { + "name": "Super antifire potion(1)" + }, + "21994": { + "name": "Super antifire mix(2)" + }, + "21997": { + "name": "Super antifire mix(1)" + }, + "22000": { + "name": "Clue scroll (elite)" + }, + "22001": { + "name": "Clue scroll (easy)" + }, + "22002": { + "name": "Dragonfire ward", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "astab": -10, + "aslash": -10, + "acrush": -10, + "amagic": -10, + "arange": 15, + "dstab": -25, + "dslash": -20, + "dcrush": -22, + "dmagic": 28, + "drange": 18, + "str": -2 + } + }, + "22003": { + "name": "Dragonfire ward", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 5, + "astab": -10, + "aslash": -10, + "acrush": -10, + "amagic": -10, + "arange": 15, + "dstab": -25, + "dslash": -20, + "dcrush": -22, + "dmagic": 28, + "drange": 18, + "str": -2 + } + }, + "22006": { + "name": "Skeletal visage", + "weight": 1.8 + }, + "22009": { + "name": "Map piece", + "quest": true + }, + "22010": { + "name": "Map piece", + "quest": true + }, + "22011": { + "name": "Map piece", + "quest": true + }, + "22012": { + "name": "Map piece", + "quest": true + }, + "22013": { + "name": "Map piece", + "quest": true + }, + "22014": { + "name": "Map piece", + "quest": true + }, + "22015": { + "name": "Map piece", + "quest": true + }, + "22016": { + "name": "Map piece", + "quest": true + }, + "22017": { + "name": "Map piece", + "quest": true + }, + "22018": { + "name": "Map piece", + "quest": true + }, + "22019": { + "name": "Map piece", + "quest": true + }, + "22020": { + "name": "Map piece", + "quest": true + }, + "22021": { + "name": "Map piece", + "quest": true + }, + "22022": { + "name": "Map piece", + "quest": true + }, + "22023": { + "name": "Map piece", + "quest": true + }, + "22024": { + "name": "Map piece", + "quest": true + }, + "22025": { + "name": "Map piece", + "quest": true + }, + "22026": { + "name": "Map piece", + "quest": true + }, + "22027": { + "name": "Map piece", + "quest": true + }, + "22028": { + "name": "Map piece", + "quest": true + }, + "22029": { + "name": "Map piece", + "quest": true + }, + "22030": { + "name": "Map piece", + "quest": true + }, + "22031": { + "name": "Map piece", + "quest": true + }, + "22032": { + "name": "Map piece", + "quest": true + }, + "22033": { + "name": "Aivas' diary", + "quest": true + }, + "22035": { + "name": "Varrock census records", + "quest": true + }, + "22037": { + "name": "Malumac's journal", + "quest": true + }, + "22039": { + "name": "Ablenkian's escape" + }, + "22041": { + "name": "Imcandoria's fall" + }, + "22043": { + "name": "Imafore's betrayal" + }, + "22045": { + "name": "Lutwidge and the moonfly" + }, + "22047": { + "name": "Serafina" + }, + "22049": { + "name": "The weeping" + }, + "22051": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22053": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22055": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22057": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22059": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22061": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22063": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22065": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22067": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22069": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22071": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22073": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22075": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22077": { + "name": "Old notes", + "quest": true, + "weight": 0.1 + }, + "22079": { + "name": "Inert locator orb", + "quest": true + }, + "22081": { + "name": "Locator orb", + "quest": true + }, + "22083": { + "name": "Robert bust", + "quest": true + }, + "22084": { + "name": "Camorra bust", + "quest": true + }, + "22085": { + "name": "Tristan bust", + "quest": true + }, + "22086": { + "name": "Aivas bust", + "quest": true + }, + "22087": { + "name": "Dragon key", + "quest": true + }, + "22088": { + "name": "Dragon key piece", + "quest": true + }, + "22089": { + "name": "Dragon key piece", + "quest": true + }, + "22090": { + "name": "Dragon key piece", + "quest": true + }, + "22091": { + "name": "Dragon key piece", + "quest": true + }, + "22092": { + "name": "Dragon key", + "quest": true + }, + "22093": { + "name": "Ancient key", + "quest": true + }, + "22094": { + "name": "Water container", + "quest": true, + "weight": 2.0 + }, + "22096": { + "name": "Revitalisation potion", + "quest": true + }, + "22097": { + "name": "Dragon metal shard", + "weight": 2.0 + }, + "22100": { + "name": "Dragon metal slice", + "weight": 2.0 + }, + "22103": { + "name": "Dragon metal lump", + "weight": 2.0 + }, + "22106": { + "name": "Jar of decay", + "weight": 1.0 + }, + "22109": { + "name": "Ava's assembler", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 1, + "arange": 8, + "dstab": 1, + "dslash": 1, + "dcrush": 1, + "dmagic": 8, + "drange": 2, + "rstr": 2 + } + }, + "22111": { + "name": "Dragonbone necklace", + "equipable": true, + "equipment": { + "slot": 2, + "prayer": 12 + } + }, + "22114": { + "name": "Mythical cape", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 1, + "acrush": 6, + "dstab": 8, + "dslash": 8, + "dcrush": 8, + "dmagic": 8, + "drange": 8, + "str": 1, + "prayer": 1 + } + }, + "22116": { + "name": "Bonemeal", + "weight": 1.0 + }, + "22118": { + "name": "Wrath talisman" + }, + "22121": { + "name": "Wrath tiara", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 0 + } + }, + "22124": { + "name": "Superior dragon bones", + "weight": 1.0 + }, + "22127": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22129": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22131": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22133": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22135": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22137": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22139": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22141": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22143": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22145": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22147": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22149": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22151": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22153": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22155": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22157": { + "name": "Adamant kiteshield", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 27, + "dslash": 31, + "dcrush": 29, + "dmagic": -1, + "drange": 29 + } + }, + "22159": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22161": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22163": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22165": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22167": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22169": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22171": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22173": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22175": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22177": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22179": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22181": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22183": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22185": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22187": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22189": { + "name": "Adamant heraldic helm", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 19, + "dslash": 21, + "dcrush": 16, + "dmagic": -1, + "drange": 19 + } + }, + "22192": { + "name": "Maple bird house", + "weight": 0.4 + }, + "22195": { + "name": "Mahogany bird house", + "weight": 0.4 + }, + "22198": { + "name": "Yew bird house", + "weight": 0.4 + }, + "22201": { + "name": "Magic bird house", + "weight": 0.4 + }, + "22204": { + "name": "Redwood bird house", + "weight": 0.4 + }, + "22207": { + "name": "Glistening tear" + }, + "22209": { + "name": "Extended super antifire(4)" + }, + "22212": { + "name": "Extended super antifire(3)" + }, + "22215": { + "name": "Extended super antifire(2)" + }, + "22218": { + "name": "Extended super antifire(1)" + }, + "22221": { + "name": "Extended super antifire mix(2)" + }, + "22224": { + "name": "Extended super antifire mix(1)" + }, + "22227": { + "name": "Bullet arrow", + "equipable": true, + "equipment": { + "slot": 13, + "arange": 46, + "rstr": 125 + } + }, + "22228": { + "name": "Field arrow", + "equipable": true, + "equipment": { + "slot": 13, + "arange": 46, + "rstr": 125 + } + }, + "22229": { + "name": "Blunt arrow", + "equipable": true, + "equipment": { + "slot": 13, + "arange": 46, + "rstr": 125 + } + }, + "22230": { + "name": "Barbed arrow", + "equipable": true, + "equipment": { + "slot": 13, + "arange": 46, + "rstr": 125 + } + }, + "22231": { + "name": "Dragon boots ornament kit" + }, + "22234": { + "name": "Dragon boots (g)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dstab": 16, + "dslash": 17, + "dcrush": 18, + "str": 4 + } + }, + "22236": { + "name": "Dragon platebody ornament kit" + }, + "22239": { + "name": "Dragon kiteshield ornament kit" + }, + "22242": { + "name": "Dragon platebody (g)", + "equipable": true, + "weight": 11.3, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 109, + "dslash": 107, + "dcrush": 97, + "dmagic": -6, + "drange": 106 + } + }, + "22244": { + "name": "Dragon kiteshield (g)", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 5, + "amagic": -8, + "arange": -2, + "dstab": 56, + "dslash": 60, + "dcrush": 58, + "dmagic": -1, + "drange": 58 + } + }, + "22246": { + "name": "Anguish ornament kit" + }, + "22249": { + "name": "Necklace of anguish (or)", + "equipable": true, + "equipment": { + "slot": 2, + "arange": 15, + "rstr": 5, + "prayer": 2 + } + }, + "22251": { + "name": "Oak shield", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 5, + "dstab": 5, + "dslash": 6, + "dcrush": 4, + "dmagic": 1, + "drange": 5 + } + }, + "22254": { + "name": "Willow shield", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 5, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": 2, + "drange": 6 + } + }, + "22257": { + "name": "Maple shield", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 5, + "dstab": 7, + "dslash": 8, + "dcrush": 6, + "dmagic": 2, + "drange": 7 + } + }, + "22260": { + "name": "Yew shield", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 5, + "dstab": 8, + "dslash": 9, + "dcrush": 7, + "dmagic": 3, + "drange": 8 + } + }, + "22263": { + "name": "Magic shield", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 5, + "dstab": 10, + "dslash": 13, + "dcrush": 9, + "dmagic": 3, + "drange": 9 + } + }, + "22266": { + "name": "Redwood shield", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 5, + "dstab": 12, + "dslash": 15, + "dcrush": 11, + "dmagic": 4, + "drange": 10 + } + }, + "22269": { + "name": "Hard leather shield", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 2, + "dstab": 8, + "dslash": 7, + "dcrush": 7, + "dmagic": 5, + "drange": 9 + } + }, + "22272": { + "name": "Snakeskin shield", + "equipable": true, + "weight": 7.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 3, + "dstab": 10, + "dslash": 9, + "dcrush": 8, + "dmagic": 7, + "drange": 10 + } + }, + "22275": { + "name": "Green d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 4, + "dstab": 14, + "dslash": 12, + "dcrush": 11, + "dmagic": 9, + "drange": 11 + } + }, + "22278": { + "name": "Blue d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 5, + "dstab": 16, + "dslash": 14, + "dcrush": 12, + "dmagic": 12, + "drange": 12 + } + }, + "22281": { + "name": "Red d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 6, + "dstab": 18, + "dslash": 16, + "dcrush": 14, + "dmagic": 13, + "drange": 13 + } + }, + "22284": { + "name": "Black d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14 + } + }, + "22287": { + "name": "Leather shields flyer" + }, + "22288": { + "name": "Trident of the seas (e)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22290": { + "name": "Uncharged trident (e)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22292": { + "name": "Trident of the swamp (e)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 25, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22294": { + "name": "Uncharged toxic trident (e)", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 25, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22296": { + "name": "Staff of light", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 70, + "amagic": 17, + "dslash": 3, + "dcrush": 3, + "dmagic": 17, + "str": 72, + "mdmg": 15, + "aspeed": 4 + } + }, + "22299": { + "name": "Ancient medallion" + }, + "22302": { + "name": "Ancient effigy" + }, + "22305": { + "name": "Ancient relic" + }, + "22308": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "22309": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "22310": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "22311": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "22312": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22313": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22314": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22315": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22316": { + "name": "Prop sword", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "22320": { + "name": "Champion's lamp", + "weight": 0.1 + }, + "22321": { + "name": "Rotten cabbage" + }, + "22322": { + "name": "Avernic defender", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 5, + "astab": 30, + "aslash": 29, + "acrush": 28, + "amagic": -5, + "arange": -4, + "dstab": 30, + "dslash": 29, + "dcrush": 28, + "dmagic": -5, + "drange": -4, + "str": 8 + } + }, + "22323": { + "name": "Sanguinesti staff", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "amagic": 25, + "arange": -4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22324": { + "name": "Ghrazi rapier", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 94, + "aslash": 55, + "str": 89, + "aspeed": 4 + } + }, + "22325": { + "name": "Scythe of vitur", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 70, + "aslash": 110, + "acrush": 30, + "amagic": -6, + "dstab": -2, + "dslash": 8, + "dcrush": 10, + "str": 75, + "aspeed": 5 + } + }, + "22326": { + "name": "Justiciar faceguard", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 60, + "dslash": 63, + "dcrush": 59, + "dmagic": -6, + "drange": 67, + "prayer": 2 + } + }, + "22327": { + "name": "Justiciar chestguard", + "equipable": true, + "weight": 9.9, + "equipment": { + "slot": 4, + "amagic": -40, + "arange": -20, + "dstab": 132, + "dslash": 130, + "dcrush": 117, + "dmagic": -16, + "drange": 142, + "prayer": 4 + } + }, + "22328": { + "name": "Justiciar legguards", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -31, + "arange": -17, + "dstab": 95, + "dslash": 92, + "dcrush": 93, + "dmagic": -14, + "drange": 102, + "prayer": 4 + } + }, + "22330": { + "name": "Deadman starter pack", + "weight": 4.0 + }, + "22331": { + "name": "Starter sword", + "weight": 1.5 + }, + "22333": { + "name": "Starter bow", + "weight": 1.5 + }, + "22335": { + "name": "Starter staff", + "weight": 1.5 + }, + "22337": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22338": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22339": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22340": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22341": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22342": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22343": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22344": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22345": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22346": { + "name": "Attacker icon", + "equipable": true + }, + "22347": { + "name": "Attacker icon", + "equipable": true + }, + "22348": { + "name": "Attacker icon", + "equipable": true + }, + "22349": { + "name": "Attacker icon", + "equipable": true + }, + "22351": { + "name": "Eggshell platebody", + "equipable": true, + "equipment": { + "slot": 4 + } + }, + "22353": { + "name": "Eggshell platelegs", + "equipable": true, + "equipment": { + "slot": 7 + } + }, + "22355": { + "name": "Holy handegg", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "22358": { + "name": "Peaceful handegg", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "22361": { + "name": "Chaotic handegg", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "22364": { + "name": "Oculus orb" + }, + "22365": { + "name": "Shayzien favour certificate", + "quest": true + }, + "22366": { + "name": "Cyan crystal" + }, + "22367": { + "name": "Kourend favour certificate", + "quest": true + }, + "22368": { + "name": "Bryophyta's staff (uncharged)", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "str": 50, + "aspeed": 5 + } + }, + "22370": { + "name": "Bryophyta's staff", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "astab": 10, + "aslash": -1, + "acrush": 40, + "amagic": 15, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "str": 50, + "aspeed": 5 + } + }, + "22372": { + "name": "Bryophyta's essence" + }, + "22374": { + "name": "Mossy key" + }, + "22386": { + "name": "Metamorphic dust", + "weight": 0.1 + }, + "22388": { + "name": "Xeric's guard", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22390": { + "name": "Xeric's warrior", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22392": { + "name": "Xeric's sentinel", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22394": { + "name": "Xeric's general", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22396": { + "name": "Xeric's champion", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22398": { + "name": "Ivandis flail", + "quest": true, + "equipable": true, + "equipment": { + "slot": 3, + "astab": 24, + "aslash": 38, + "acrush": 62, + "amagic": 8, + "dstab": 4, + "dslash": 4, + "dcrush": 2, + "dmagic": 8, + "str": 42, + "prayer": 5, + "aspeed": 5 + } + }, + "22400": { + "name": "Drakan's medallion", + "quest": true, + "equipable": true, + "equipment": { + "slot": 2 + } + }, + "22402": { + "name": "Mysterious herb", + "quest": true + }, + "22403": { + "name": "Mysterious meat", + "quest": true + }, + "22404": { + "name": "Mysterious crushed meat", + "quest": true + }, + "22405": { + "name": "Vial of blood", + "quest": true + }, + "22406": { + "name": "Unfinished blood potion", + "quest": true + }, + "22407": { + "name": "Blood potion", + "quest": true + }, + "22408": { + "name": "Unfinished potion", + "quest": true + }, + "22409": { + "name": "Potion", + "quest": true + }, + "22410": { + "name": "Old notes", + "quest": true + }, + "22411": { + "name": "Old diary", + "quest": true + }, + "22413": { + "name": "Flaygian's notes", + "quest": true + }, + "22414": { + "name": "Chain", + "quest": true, + "weight": 3.0 + }, + "22415": { + "name": "Tome of experience", + "quest": true + }, + "22416": { + "name": "The turncloak" + }, + "22418": { + "name": "Explosive discovery" + }, + "22420": { + "name": "Bloody grimoire" + }, + "22422": { + "name": "Elixir of everlasting" + }, + "22424": { + "name": "Buried alive" + }, + "22426": { + "name": "Deed" + }, + "22428": { + "name": "Old key" + }, + "22430": { + "name": "Bloody bracer" + }, + "22433": { + "name": "Emerald sickle (b)", + "quest": true, + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 2, + "prayer": 5, + "aspeed": 4 + } + }, + "22435": { + "name": "Enchanted emerald sickle (b)", + "quest": true, + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "dmagic": 1, + "drange": 1, + "str": 3, + "prayer": 5, + "aspeed": 4 + } + }, + "22437": { + "name": "Rotten carrot" + }, + "22438": { + "name": "Justiciar armour set" + }, + "22441": { + "name": "Avernic defender (broken)", + "equipable": true, + "weight": 0.45, + "equipment": { + "slot": 5, + "astab": 30, + "aslash": 29, + "acrush": 28, + "amagic": -5, + "arange": -4, + "dstab": 30, + "dslash": 29, + "dcrush": 28, + "dmagic": -5, + "drange": -4, + "str": 8 + } + }, + "22443": { + "name": "Cadantine blood potion (unf)" + }, + "22446": { + "name": "Vial of blood", + "equipable": true + }, + "22449": { + "name": "Battlemage potion(4)" + }, + "22452": { + "name": "Battlemage potion(3)" + }, + "22455": { + "name": "Battlemage potion(2)" + }, + "22458": { + "name": "Battlemage potion(1)" + }, + "22461": { + "name": "Bastion potion(4)" + }, + "22464": { + "name": "Bastion potion(3)" + }, + "22467": { + "name": "Bastion potion(2)" + }, + "22470": { + "name": "Bastion potion(1)" + }, + "22475": { + "name": "Message" + }, + "22477": { + "name": "Avernic defender hilt", + "weight": 0.4 + }, + "22481": { + "name": "Sanguinesti staff (uncharged)", + "equipable": true, + "weight": 1.5, + "equipment": { + "slot": 3, + "amagic": 25, + "arange": -4, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22486": { + "name": "Scythe of vitur (uncharged)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "astab": 50, + "aslash": 75, + "acrush": 10, + "amagic": -6, + "dstab": -2, + "dslash": 6, + "str": 50, + "aspeed": 5 + } + }, + "22494": { + "name": "Sinhaza shroud tier 1", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22496": { + "name": "Sinhaza shroud tier 2", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22498": { + "name": "Sinhaza shroud tier 3", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22500": { + "name": "Sinhaza shroud tier 4", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22502": { + "name": "Sinhaza shroud tier 5", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22504": { + "name": "Serafina's diary", + "weight": 0.5 + }, + "22506": { + "name": "The butcher", + "weight": 0.5 + }, + "22508": { + "name": "Arachnids of vampyrium", + "weight": 0.5 + }, + "22510": { + "name": "The shadow realm", + "weight": 0.5 + }, + "22512": { + "name": "The wild hunt", + "weight": 0.5 + }, + "22514": { + "name": "Verzik vitur - patient record", + "weight": 0.5 + }, + "22516": { + "name": "Dawnbringer", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "amagic": 25, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 15, + "aspeed": 4 + } + }, + "22517": { + "name": "Verzik's crystal shard" + }, + "22519": { + "name": "Cabbage", + "weight": 0.453 + }, + "22520": { + "name": "Cabbage", + "weight": 0.453 + }, + "22521": { + "name": "Coin pouch" + }, + "22522": { + "name": "Coin pouch" + }, + "22523": { + "name": "Coin pouch" + }, + "22524": { + "name": "Coin pouch" + }, + "22525": { + "name": "Coin pouch" + }, + "22526": { + "name": "Coin pouch" + }, + "22527": { + "name": "Coin pouch" + }, + "22528": { + "name": "Coin pouch" + }, + "22529": { + "name": "Coin pouch" + }, + "22530": { + "name": "Coin pouch" + }, + "22531": { + "name": "Coin pouch" + }, + "22532": { + "name": "Coin pouch" + }, + "22533": { + "name": "Coin pouch" + }, + "22534": { + "name": "Coin pouch" + }, + "22535": { + "name": "Coin pouch" + }, + "22536": { + "name": "Coin pouch" + }, + "22537": { + "name": "Coin pouch" + }, + "22538": { + "name": "Coin pouch" + }, + "22541": { + "name": "Rotten strawberry" + }, + "22542": { + "name": "Viggora's chainmace (u)", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 53, + "aslash": -2, + "acrush": 67, + "dslash": 1, + "str": 66, + "prayer": 2, + "aspeed": 4 + } + }, + "22545": { + "name": "Viggora's chainmace", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 53, + "aslash": -2, + "acrush": 67, + "dslash": 1, + "str": 66, + "prayer": 2, + "aspeed": 4 + } + }, + "22547": { + "name": "Craw's bow (u)", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "arange": 75, + "rstr": 60, + "aspeed": 4 + } + }, + "22550": { + "name": "Craw's bow", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 3, + "arange": 75, + "rstr": 60, + "aspeed": 4 + } + }, + "22552": { + "name": "Thammaron's sceptre (u)", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 3, + "amagic": 20, + "dmagic": 20, + "aspeed": 4 + } + }, + "22555": { + "name": "Thammaron's sceptre", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 3, + "amagic": 20, + "dmagic": 20, + "aspeed": 4 + } + }, + "22557": { + "name": "Amulet of avarice", + "equipable": true, + "equipment": { + "slot": 2, + "astab": 10, + "aslash": 10, + "acrush": 10, + "amagic": 10, + "arange": 10, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "str": 6, + "prayer": 3 + } + }, + "22586": { + "name": "Looting bag" + }, + "22588": { + "name": "Old man's coffin", + "quest": true, + "weight": 32.0 + }, + "22589": { + "name": "Reduced cadava potion", + "quest": true + }, + "22590": { + "name": "Goat dung", + "quest": true, + "weight": 1.0 + }, + "22591": { + "name": "Weiss fire notes", + "quest": true + }, + "22593": { + "name": "Te salt" + }, + "22595": { + "name": "Efh salt" + }, + "22597": { + "name": "Urt salt" + }, + "22599": { + "name": "Icy basalt" + }, + "22601": { + "name": "Stony basalt" + }, + "22603": { + "name": "Basalt" + }, + "22610": { + "name": "Vesta's spear", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 133, + "aslash": 113, + "acrush": 120, + "dstab": 18, + "dslash": 21, + "dcrush": 21, + "str": 122, + "aspeed": 5 + } + }, + "22613": { + "name": "Vesta's longsword", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": 106, + "aslash": 121, + "acrush": -2, + "dstab": 1, + "dslash": 4, + "dcrush": 3, + "str": 118, + "aspeed": 5 + } + }, + "22616": { + "name": "Vesta's chainbody", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "astab": 5, + "aslash": 7, + "acrush": 7, + "amagic": -15, + "dstab": 120, + "dslash": 131, + "dcrush": 145, + "dmagic": -3, + "drange": 140, + "str": 6 + } + }, + "22619": { + "name": "Vesta's plateskirt", + "equipable": true, + "weight": 8.1, + "equipment": { + "slot": 7, + "astab": 3, + "aslash": 5, + "acrush": 5, + "amagic": -17, + "arange": -4, + "dstab": 86, + "dslash": 100, + "dcrush": 112, + "dmagic": -4, + "drange": 118, + "str": 3 + } + }, + "22622": { + "name": "Statius's warhammer", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "astab": -4, + "aslash": -4, + "acrush": 123, + "str": 114, + "aspeed": 5 + } + }, + "22625": { + "name": "Statius's full helm", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 0, + "astab": 3, + "aslash": 3, + "acrush": 4, + "amagic": -6, + "arange": -2, + "dstab": 65, + "dslash": 70, + "dcrush": 63, + "dmagic": -1, + "drange": 71, + "str": 3 + } + }, + "22628": { + "name": "Statius's platebody", + "equipable": true, + "weight": 9.9, + "equipment": { + "slot": 4, + "astab": 5, + "aslash": 5, + "acrush": 7, + "amagic": -30, + "arange": -10, + "dstab": 154, + "dslash": 145, + "dcrush": 121, + "dmagic": -6, + "drange": 157, + "str": 5 + } + }, + "22631": { + "name": "Statius's platelegs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "astab": 3, + "aslash": 3, + "acrush": 5, + "amagic": -21, + "arange": -7, + "dstab": 110, + "dslash": 106, + "dcrush": 97, + "dmagic": -4, + "drange": 121, + "str": 3 + } + }, + "22634": { + "name": "Morrigan's throwing axe", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 93, + "rstr": 117, + "aspeed": 5 + } + }, + "22636": { + "name": "Morrigan's javelin", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 105, + "rstr": 145, + "aspeed": 6 + } + }, + "22638": { + "name": "Morrigan's coif", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -5, + "arange": 13, + "dstab": 8, + "dslash": 11, + "dcrush": 14, + "dmagic": 8, + "drange": 12 + } + }, + "22641": { + "name": "Morrigan's leather body", + "equipable": true, + "weight": 6.8, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 36, + "dstab": 61, + "dslash": 53, + "dcrush": 66, + "dmagic": 75, + "drange": 62 + } + }, + "22644": { + "name": "Morrigan's leather chaps", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 23, + "dstab": 35, + "dslash": 29, + "dcrush": 37, + "dmagic": 46, + "drange": 35 + } + }, + "22647": { + "name": "Zuriel's staff", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 13, + "aslash": -1, + "acrush": 65, + "amagic": 18, + "dstab": 5, + "dslash": 7, + "dcrush": 4, + "dmagic": 18, + "str": 72, + "mdmg": 10, + "aspeed": 5 + } + }, + "22650": { + "name": "Zuriel's hood", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": 8, + "arange": -2, + "dstab": 20, + "dslash": 16, + "dcrush": 22, + "dmagic": 8 + } + }, + "22653": { + "name": "Zuriel's robe top", + "equipable": true, + "weight": 4.5, + "equipment": { + "slot": 4, + "amagic": 35, + "arange": -10, + "dstab": 63, + "dslash": 45, + "dcrush": 74, + "dmagic": 35 + } + }, + "22656": { + "name": "Zuriel's robe bottom", + "equipable": true, + "weight": 5.4, + "equipment": { + "slot": 7, + "amagic": 25, + "arange": -7, + "dstab": 38, + "dslash": 35, + "dcrush": 44, + "dmagic": 25 + } + }, + "22660": { + "name": "Empty bucket pack" + }, + "22671": { + "name": "Kq head (tattered)", + "weight": 10.0 + }, + "22673": { + "name": "Stuffed kq head (tattered)", + "weight": 10.0 + }, + "22675": { + "name": "Scroll sack", + "equipable": true, + "equipment": { + "slot": 1 + } + }, + "22684": { + "name": "Eek", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "22689": { + "name": "Clown mask", + "weight": 0.5 + }, + "22692": { + "name": "Clown bow tie", + "weight": 0.1 + }, + "22695": { + "name": "Clown gown", + "weight": 0.9 + }, + "22698": { + "name": "Clown trousers", + "weight": 0.8 + }, + "22701": { + "name": "Clown shoes", + "weight": 0.1 + }, + "22710": { + "name": "Curator's medallion", + "weight": 0.2 + }, + "22711": { + "name": "Collection log", + "weight": 0.5 + }, + "22713": { + "name": "Star-face", + "equipable": true, + "weight": 0.1, + "equipment": { + "slot": 0 + } + }, + "22715": { + "name": "Tree top", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 4 + } + }, + "22717": { + "name": "Tree skirt", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 7 + } + }, + "22719": { + "name": "Candy cane", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "22721": { + "name": "Attacker icon", + "equipable": true + }, + "22722": { + "name": "Attacker icon", + "equipable": true + }, + "22723": { + "name": "Attacker icon", + "equipable": true + }, + "22724": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "22725": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22726": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22727": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22728": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "22729": { + "name": "Attacker icon", + "equipable": true + }, + "22730": { + "name": "Attacker icon", + "equipable": true + }, + "22731": { + "name": "Dragon hasta", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": -15, + "dslash": -15, + "dcrush": -12, + "drange": -15, + "str": 60, + "aspeed": 4 + } + }, + "22734": { + "name": "Dragon hasta(p)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": -15, + "dslash": -15, + "dcrush": -12, + "drange": -15, + "str": 60, + "aspeed": 4 + } + }, + "22737": { + "name": "Dragon hasta(p+)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": -15, + "dslash": -15, + "dcrush": -12, + "drange": -15, + "str": 60, + "aspeed": 4 + } + }, + "22740": { + "name": "Dragon hasta(p++)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": -15, + "dslash": -15, + "dcrush": -12, + "drange": -15, + "str": 60, + "aspeed": 4 + } + }, + "22743": { + "name": "Dragon hasta(kp)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 3, + "astab": 55, + "aslash": 55, + "acrush": 55, + "dstab": -15, + "dslash": -15, + "dcrush": -12, + "drange": -15, + "str": 60, + "aspeed": 4 + } + }, + "22754": { + "name": "Bonemeal", + "weight": 1.0 + }, + "22756": { + "name": "Bonemeal", + "weight": 1.0 + }, + "22758": { + "name": "Bonemeal", + "weight": 1.0 + }, + "22760": { + "name": "Lovakengj favour certificate", + "quest": true + }, + "22761": { + "name": "Dinh's hammer", + "quest": true, + "weight": 0.9 + }, + "22762": { + "name": "Generator crank", + "quest": true, + "weight": 1.0 + }, + "22763": { + "name": "8-gallon jug", + "quest": true, + "weight": 0.5 + }, + "22764": { + "name": "5-gallon jug", + "quest": true, + "weight": 0.5 + }, + "22765": { + "name": "Energy disk (level 4)", + "quest": true + }, + "22766": { + "name": "Energy disk (level 3)", + "quest": true + }, + "22767": { + "name": "Energy disk (level 2)", + "quest": true + }, + "22768": { + "name": "Energy disk (level 1)", + "quest": true + }, + "22769": { + "name": "Unknown fluid 1", + "quest": true + }, + "22770": { + "name": "Unknown fluid 2", + "quest": true + }, + "22771": { + "name": "Unknown fluid 3", + "quest": true + }, + "22772": { + "name": "Unknown fluid 4", + "quest": true + }, + "22773": { + "name": "Unknown fluid 5", + "quest": true + }, + "22774": { + "name": "Old notes", + "quest": true + }, + "22775": { + "name": "Ancient letter", + "quest": true + }, + "22777": { + "name": "Arceuus favour certificate", + "quest": true + }, + "22778": { + "name": "Dark altar" + }, + "22780": { + "name": "Wyrm bones", + "weight": 1.8 + }, + "22783": { + "name": "Drake bones", + "weight": 1.8 + }, + "22786": { + "name": "Hydra bones", + "weight": 1.8 + }, + "22789": { + "name": "Uncooked dragonfruit pie", + "weight": 0.5 + }, + "22792": { + "name": "Half a dragonfruit pie", + "weight": 0.2 + }, + "22795": { + "name": "Dragonfruit pie", + "weight": 0.4 + }, + "22798": { + "name": "Bird nest" + }, + "22800": { + "name": "Bird nest" + }, + "22803": { + "name": "Rada's blessing 3", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "22804": { + "name": "Dragon knife", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 28, + "rstr": 30, + "aspeed": 3 + } + }, + "22806": { + "name": "Dragon knife(p)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 28, + "rstr": 30, + "aspeed": 3 + } + }, + "22808": { + "name": "Dragon knife(p+)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 28, + "rstr": 30, + "aspeed": 3 + } + }, + "22810": { + "name": "Dragon knife(p++)", + "equipable": true, + "equipment": { + "slot": 3, + "arange": 28, + "rstr": 30, + "aspeed": 3 + } + }, + "22816": { + "name": "Cormorant's glove", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "aspeed": 4 + } + }, + "22817": { + "name": "Cormorant's glove", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 3, + "dslash": 1, + "dcrush": 1, + "aspeed": 4 + } + }, + "22818": { + "name": "Fish chunks" + }, + "22820": { + "name": "Molch pearl" + }, + "22826": { + "name": "Bluegill", + "weight": 0.5 + }, + "22829": { + "name": "Common tench", + "weight": 0.5 + }, + "22832": { + "name": "Mottled eel", + "weight": 0.5 + }, + "22835": { + "name": "Greater siren", + "weight": 0.5 + }, + "22838": { + "name": "Fish sack", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "22840": { + "name": "Golden tench", + "equipable": true, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "22842": { + "name": "Pearl barbarian rod", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "22844": { + "name": "Pearl fly fishing rod", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "22846": { + "name": "Pearl fishing rod", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "22848": { + "name": "Celastrus seedling", + "weight": 0.66 + }, + "22850": { + "name": "Redwood seedling", + "weight": 0.66 + }, + "22852": { + "name": "Celastrus seedling (w)", + "weight": 0.907 + }, + "22854": { + "name": "Redwood seedling (w)", + "weight": 0.907 + }, + "22856": { + "name": "Celastrus sapling", + "weight": 0.9 + }, + "22859": { + "name": "Redwood sapling", + "weight": 0.9 + }, + "22862": { + "name": "Dragonfruit seedling", + "weight": 0.66 + }, + "22864": { + "name": "Dragonfruit seedling (w)", + "weight": 0.907 + }, + "22866": { + "name": "Dragonfruit sapling", + "weight": 0.9 + }, + "22869": { + "name": "Celastrus seed" + }, + "22871": { + "name": "Redwood tree seed" + }, + "22873": { + "name": "Potato cactus seed" + }, + "22875": { + "name": "Hespori seed" + }, + "22877": { + "name": "Dragonfruit tree seed" + }, + "22879": { + "name": "Snape grass seed" + }, + "22881": { + "name": "Attas seed" + }, + "22883": { + "name": "Iasor seed" + }, + "22885": { + "name": "Kronos seed" + }, + "22887": { + "name": "White lily seed" + }, + "22929": { + "name": "Dragonfruit", + "weight": 0.2 + }, + "22932": { + "name": "White lily" + }, + "22935": { + "name": "Celastrus bark" + }, + "22941": { + "name": "Rada's blessing 1", + "equipable": true, + "equipment": { + "slot": 13 + } + }, + "22943": { + "name": "Rada's blessing 2", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 1 + } + }, + "22947": { + "name": "Rada's blessing 4", + "equipable": true, + "equipment": { + "slot": 13, + "prayer": 2 + } + }, + "22949": { + "name": "Battlefront teleport" + }, + "22951": { + "name": "Boots of brimstone", + "equipable": true, + "weight": 3.1, + "equipment": { + "slot": 10, + "astab": 3, + "amagic": 3, + "arange": 5, + "dstab": 10, + "dslash": 10, + "dcrush": 10, + "dmagic": 5, + "drange": 5 + } + }, + "22954": { + "name": "Devout boots", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 10, + "prayer": 5 + } + }, + "22957": { + "name": "Drake's claw" + }, + "22960": { + "name": "Drake's tooth" + }, + "22963": { + "name": "Broken dragon hasta", + "weight": 2.2 + }, + "22966": { + "name": "Hydra's claw" + }, + "22969": { + "name": "Hydra's heart" + }, + "22971": { + "name": "Hydra's fang" + }, + "22973": { + "name": "Hydra's eye" + }, + "22975": { + "name": "Brimstone ring", + "equipable": true, + "equipment": { + "slot": 12, + "astab": 4, + "aslash": 4, + "acrush": 4, + "amagic": 6, + "arange": 4, + "dstab": 4, + "dslash": 4, + "dcrush": 4, + "dmagic": 6, + "drange": 4, + "str": 4 + } + }, + "22978": { + "name": "Dragon hunter lance", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": 85, + "aslash": 65, + "acrush": 65, + "str": 70, + "aspeed": 4 + } + }, + "22981": { + "name": "Ferocious gloves", + "equipable": true, + "equipment": { + "slot": 9, + "astab": 16, + "aslash": 16, + "acrush": 16, + "amagic": -16, + "arange": -16, + "str": 14 + } + }, + "22983": { + "name": "Hydra leather", + "weight": 0.2 + }, + "22986": { + "name": "Bonecrusher necklace", + "equipable": true, + "equipment": { + "slot": 2, + "prayer": 12 + } + }, + "22988": { + "name": "Hydra tail", + "weight": 0.2 + }, + "22991": { + "name": "Stone tablet", + "weight": 1.0 + }, + "22993": { + "name": "Seed pack" + }, + "22994": { + "name": "Bottomless compost bucket", + "weight": 3.0 + }, + "22997": { + "name": "Bottomless compost bucket", + "weight": 3.0 + }, + "22999": { + "name": "Bottled dragonbreath (unpowered)" + }, + "23002": { + "name": "Bottled dragonbreath" + }, + "23007": { + "name": "Tatty note" + }, + "23009": { + "name": "Gielinor's flora - flowers", + "weight": 0.5 + }, + "23011": { + "name": "Gielinor's flora - bushes", + "weight": 0.5 + }, + "23013": { + "name": "Gielinor's flora - hops", + "weight": 0.5 + }, + "23015": { + "name": "Gielinor's flora - allotments", + "weight": 0.5 + }, + "23017": { + "name": "Gielinor's flora - herbs", + "weight": 0.5 + }, + "23019": { + "name": "Gielinor's flora - trees", + "weight": 0.5 + }, + "23021": { + "name": "Gielinor's flora - fruit", + "weight": 0.5 + }, + "23023": { + "name": "Old notes", + "weight": 0.1 + }, + "23025": { + "name": "Old notes", + "weight": 0.1 + }, + "23027": { + "name": "Old notes", + "weight": 0.1 + }, + "23029": { + "name": "Old notes", + "weight": 0.1 + }, + "23031": { + "name": "Old notes", + "weight": 0.1 + }, + "23033": { + "name": "Old notes", + "weight": 0.1 + }, + "23035": { + "name": "Old notes", + "weight": 0.1 + }, + "23037": { + "name": "Boots of stone", + "equipable": true, + "weight": 3.175, + "equipment": { + "slot": 10, + "dstab": 1, + "dslash": 1, + "dcrush": 1 + } + }, + "23045": { + "name": "Clue scroll (hard)" + }, + "23046": { + "name": "Clue scroll (medium)" + }, + "23047": { + "name": "Mystic hat (dusk)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 0, + "amagic": 4, + "dmagic": 4 + } + }, + "23050": { + "name": "Mystic robe top (dusk)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": 20, + "dmagic": 20 + } + }, + "23053": { + "name": "Mystic robe bottom (dusk)", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 7, + "amagic": 15, + "dmagic": 15 + } + }, + "23056": { + "name": "Mystic gloves (dusk)", + "equipable": true, + "weight": 0.453, + "equipment": { + "slot": 9, + "amagic": 3, + "dmagic": 3 + } + }, + "23059": { + "name": "Mystic boots (dusk)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 10, + "amagic": 3, + "dmagic": 3 + } + }, + "23062": { + "name": "Nest box (seeds)", + "weight": 1.0 + }, + "23064": { + "name": "Jar of chemicals", + "weight": 1.0 + }, + "23067": { + "name": "Treasure scroll", + "quest": true + }, + "23068": { + "name": "Treasure scroll", + "quest": true + }, + "23069": { + "name": "Mysterious orb", + "quest": true + }, + "23070": { + "name": "Treasure scroll", + "quest": true + }, + "23071": { + "name": "Ancient casket", + "quest": true, + "weight": 5.0 + }, + "23072": { + "name": "Antique lamp", + "quest": true, + "weight": 0.1 + }, + "23073": { + "name": "Hydra slayer helmet", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": -1, + "drange": 30 + } + }, + "23075": { + "name": "Hydra slayer helmet (i)", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0, + "amagic": 3, + "arange": 3, + "dstab": 30, + "dslash": 32, + "dcrush": 27, + "dmagic": 10, + "drange": 30 + } + }, + "23077": { + "name": "Alchemical hydra heads", + "weight": 10.0 + }, + "23079": { + "name": "Stuffed hydra heads", + "weight": 10.0 + }, + "23082": { + "name": "Antique lamp", + "quest": true, + "weight": 0.1 + }, + "23083": { + "name": "Brimstone key" + }, + "23091": { + "name": "Ornate gloves", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 9, + "dslash": 1, + "dcrush": 2 + } + }, + "23093": { + "name": "Ornate boots", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 10, + "dslash": 1, + "dcrush": 1 + } + }, + "23095": { + "name": "Ornate legs", + "equipable": true, + "weight": 9.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10 + } + }, + "23097": { + "name": "Ornate top", + "equipable": true, + "weight": 11.0, + "equipment": { + "slot": 4, + "amagic": -15, + "dstab": 10, + "dslash": 15, + "dcrush": 19, + "dmagic": -3, + "drange": 12 + } + }, + "23099": { + "name": "Ornate cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dslash": 1, + "dcrush": 1, + "drange": 2 + } + }, + "23101": { + "name": "Ornate helm", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0, + "amagic": -6, + "arange": -2, + "dstab": 6, + "dslash": 7, + "dcrush": 5, + "dmagic": -1, + "drange": 6 + } + }, + "23108": { + "name": "Birthday cake", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "23110": { + "name": "Mystic set (light)" + }, + "23113": { + "name": "Mystic set (blue)" + }, + "23116": { + "name": "Mystic set (dark)" + }, + "23119": { + "name": "Mystic set (dusk)" + }, + "23122": { + "name": "Oily pearl fishing rod", + "equipable": true, + "equipment": { + "slot": 3, + "aspeed": 5 + } + }, + "23124": { + "name": "Gilded dragonhide set" + }, + "23127": { + "name": "Clue nest (beginner)" + }, + "23129": { + "name": "Clue bottle (beginner)" + }, + "23131": { + "name": "Clue scroll (medium)" + }, + "23132": { + "name": "Challenge scroll (medium)" + }, + "23133": { + "name": "Clue scroll (medium)" + }, + "23134": { + "name": "Challenge scroll (medium)" + }, + "23135": { + "name": "Clue scroll (medium)" + }, + "23136": { + "name": "Clue scroll (medium)" + }, + "23137": { + "name": "Clue scroll (medium)" + }, + "23138": { + "name": "Clue scroll (medium)" + }, + "23139": { + "name": "Clue scroll (medium)" + }, + "23140": { + "name": "Clue scroll (medium)" + }, + "23141": { + "name": "Clue scroll (medium)" + }, + "23142": { + "name": "Clue scroll (medium)" + }, + "23143": { + "name": "Clue scroll (medium)" + }, + "23144": { + "name": "Clue scroll (elite)" + }, + "23145": { + "name": "Clue scroll (elite)" + }, + "23146": { + "name": "Clue scroll (elite)" + }, + "23147": { + "name": "Clue scroll (elite)" + }, + "23148": { + "name": "Clue scroll (elite)" + }, + "23149": { + "name": "Clue scroll (easy)" + }, + "23150": { + "name": "Clue scroll (easy)" + }, + "23151": { + "name": "Clue scroll (easy)" + }, + "23152": { + "name": "Clue scroll (easy)" + }, + "23153": { + "name": "Clue scroll (easy)" + }, + "23154": { + "name": "Clue scroll (easy)" + }, + "23155": { + "name": "Clue scroll (easy)" + }, + "23156": { + "name": "Clue scroll (easy)" + }, + "23157": { + "name": "Clue scroll (easy)" + }, + "23158": { + "name": "Clue scroll (easy)" + }, + "23159": { + "name": "Clue scroll (easy)" + }, + "23160": { + "name": "Clue scroll (easy)" + }, + "23161": { + "name": "Clue scroll (easy)" + }, + "23162": { + "name": "Clue scroll (easy)" + }, + "23163": { + "name": "Clue scroll (easy)" + }, + "23164": { + "name": "Clue scroll (easy)" + }, + "23165": { + "name": "Clue scroll (easy)" + }, + "23166": { + "name": "Clue scroll (easy)" + }, + "23167": { + "name": "Clue scroll (hard)" + }, + "23168": { + "name": "Clue scroll (hard)" + }, + "23169": { + "name": "Clue scroll (hard)" + }, + "23170": { + "name": "Clue scroll (hard)" + }, + "23171": { + "name": "Puzzle box (hard)" + }, + "23172": { + "name": "Clue scroll (hard)" + }, + "23173": { + "name": "Puzzle box (hard)" + }, + "23174": { + "name": "Clue scroll (hard)" + }, + "23175": { + "name": "Clue scroll (hard)" + }, + "23176": { + "name": "Clue scroll (hard)" + }, + "23177": { + "name": "Clue scroll (hard)" + }, + "23178": { + "name": "Clue scroll (hard)" + }, + "23179": { + "name": "Clue scroll (hard)" + }, + "23180": { + "name": "Clue scroll (hard)" + }, + "23181": { + "name": "Clue scroll (hard)" + }, + "23182": { + "name": "Clue scroll (beginner)" + }, + "23183": { + "name": "Strange device", + "weight": 1.0 + }, + "23184": { + "name": "Mimic", + "weight": 5.0 + }, + "23185": { + "name": "Ring of 3rd age" + }, + "23188": { + "name": "Guthix d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14, + "prayer": 1 + } + }, + "23191": { + "name": "Saradomin d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14, + "prayer": 1 + } + }, + "23194": { + "name": "Zamorak d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14, + "prayer": 1 + } + }, + "23197": { + "name": "Ancient d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14, + "prayer": 1 + } + }, + "23200": { + "name": "Armadyl d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14, + "prayer": 1 + } + }, + "23203": { + "name": "Bandos d'hide shield", + "equipable": true, + "weight": 8.0, + "equipment": { + "slot": 5, + "astab": -15, + "aslash": -15, + "acrush": -11, + "amagic": -10, + "arange": 7, + "dstab": 21, + "dslash": 18, + "dcrush": 16, + "dmagic": 15, + "drange": 14, + "prayer": 1 + } + }, + "23206": { + "name": "Dual sai", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 3, + "astab": 11, + "aslash": 8, + "acrush": -4, + "amagic": -4, + "str": 14, + "aspeed": 4 + } + }, + "23209": { + "name": "Rune platebody (h1)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "23212": { + "name": "Rune platebody (h2)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "23215": { + "name": "Rune platebody (h3)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "23218": { + "name": "Rune platebody (h4)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "23221": { + "name": "Rune platebody (h5)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 82, + "dslash": 80, + "dcrush": 72, + "dmagic": -6, + "drange": 80 + } + }, + "23224": { + "name": "Thieving bag", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1 + } + }, + "23227": { + "name": "Rune defender ornament kit", + "equipable": true + }, + "23230": { + "name": "Rune defender (t)", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 5, + "astab": 20, + "aslash": 19, + "acrush": 18, + "amagic": -3, + "arange": -2, + "dstab": 20, + "dslash": 19, + "dcrush": 18, + "dmagic": -3, + "drange": -2, + "str": 5 + } + }, + "23232": { + "name": "Tzhaar-ket-om ornament kit", + "equipable": true + }, + "23235": { + "name": "Tzhaar-ket-om (t)", + "equipable": true, + "weight": 3.628, + "equipment": { + "slot": 3, + "acrush": 80, + "amagic": -4, + "str": 85, + "aspeed": 7 + } + }, + "23237": { + "name": "Berserker necklace ornament kit", + "equipable": true + }, + "23240": { + "name": "Berserker necklace (or)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": -10, + "aslash": -10, + "acrush": -10, + "dstab": -20, + "dslash": -20, + "dcrush": -20, + "dmagic": -20, + "drange": -20, + "str": 7, + "prayer": 3 + } + }, + "23242": { + "name": "3rd age plateskirt", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 7, + "amagic": -25, + "arange": -2, + "dstab": 78, + "dslash": 76, + "dcrush": 83, + "dmagic": -5, + "drange": 75 + } + }, + "23245": { + "name": "Reward casket (beginner)" + }, + "23246": { + "name": "Fremennik kilt", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 7, + "amagic": -21, + "arange": -7, + "dstab": 11, + "dslash": 10, + "dcrush": 10, + "dmagic": -4, + "drange": 10, + "str": 1 + } + }, + "23249": { + "name": "Rangers' tights", + "equipable": true, + "weight": 5.443, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 15 + } + }, + "23252": { + "name": "Giant boot", + "equipable": true, + "weight": 0.5, + "equipment": { + "slot": 0 + } + }, + "23255": { + "name": "Uri's hat", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0 + } + }, + "23258": { + "name": "Gilded coif", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0, + "amagic": -1, + "arange": 4, + "dstab": 4, + "dslash": 7, + "dcrush": 8, + "dmagic": 4, + "drange": 6 + } + }, + "23261": { + "name": "Gilded d'hide vambs", + "equipable": true, + "weight": 1.0, + "equipment": { + "slot": 9, + "amagic": -10, + "arange": 8, + "dstab": 3, + "dslash": 2, + "dcrush": 4, + "dmagic": 2 + } + }, + "23264": { + "name": "Gilded d'hide body", + "equipable": true, + "weight": 6.0, + "equipment": { + "slot": 4, + "amagic": -15, + "arange": 15, + "dstab": 40, + "dslash": 32, + "dcrush": 45, + "dmagic": 20, + "drange": 40 + } + }, + "23267": { + "name": "Gilded d'hide chaps", + "equipable": true, + "weight": 5.0, + "equipment": { + "slot": 7, + "amagic": -10, + "arange": 8, + "dstab": 22, + "dslash": 16, + "dcrush": 24, + "dmagic": 8, + "drange": 22 + } + }, + "23270": { + "name": "Adamant dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "23273": { + "name": "Rune dragon mask", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 0 + } + }, + "23276": { + "name": "Gilded pickaxe", + "equipable": true, + "weight": 2.267, + "equipment": { + "slot": 3, + "astab": 26, + "aslash": -2, + "acrush": 24, + "dslash": 1, + "str": 29, + "aspeed": 5 + } + }, + "23279": { + "name": "Gilded axe", + "equipable": true, + "weight": 1.3, + "equipment": { + "slot": 3, + "astab": -2, + "aslash": 26, + "acrush": 24, + "dslash": 1, + "str": 29, + "aspeed": 5 + } + }, + "23282": { + "name": "Gilded spade", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "23285": { + "name": "Mole slippers", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 10 + } + }, + "23288": { + "name": "Frog slippers", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 10 + } + }, + "23291": { + "name": "Bear feet", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 10 + } + }, + "23294": { + "name": "Demon feet", + "equipable": true, + "weight": 0.2, + "equipment": { + "slot": 10 + } + }, + "23297": { + "name": "Jester cape", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1 + } + }, + "23300": { + "name": "Shoulder parrot", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1 + } + }, + "23303": { + "name": "Monk's robe top (t)", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 4, + "prayer": 6 + } + }, + "23306": { + "name": "Monk's robe (t)", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7, + "prayer": 5 + } + }, + "23309": { + "name": "Amulet of defence (t)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "dstab": 7, + "dslash": 7, + "dcrush": 7, + "dmagic": 7, + "drange": 7 + } + }, + "23312": { + "name": "Sandwich lady hat", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 0 + } + }, + "23315": { + "name": "Sandwich lady top", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 4 + } + }, + "23318": { + "name": "Sandwich lady bottom", + "equipable": true, + "weight": 0.9, + "equipment": { + "slot": 7 + } + }, + "23321": { + "name": "Rune scimitar ornament kit (guthix)", + "equipable": true + }, + "23324": { + "name": "Rune scimitar ornament kit (saradomin)", + "equipable": true + }, + "23327": { + "name": "Rune scimitar ornament kit (zamorak)", + "equipable": true + }, + "23330": { + "name": "Rune scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "23332": { + "name": "Rune scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "23334": { + "name": "Rune scimitar", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": 45, + "acrush": -2, + "dslash": 1, + "str": 44, + "aspeed": 4 + } + }, + "23336": { + "name": "3rd age druidic robe top", + "equipable": true, + "weight": 1.8, + "equipment": { + "slot": 4, + "prayer": 8 + } + }, + "23339": { + "name": "3rd age druidic robe bottoms", + "equipable": true, + "weight": 2.7, + "equipment": { + "slot": 7, + "prayer": 6 + } + }, + "23342": { + "name": "3rd age druidic staff", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 7, + "aslash": -1, + "acrush": 25, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 32, + "prayer": 6, + "aspeed": 5 + } + }, + "23345": { + "name": "3rd age druidic cloak", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "amagic": 1, + "dstab": 3, + "dslash": 3, + "dcrush": 3, + "dmagic": 3, + "drange": 3, + "prayer": 6 + } + }, + "23348": { + "name": "Tormented ornament kit" + }, + "23351": { + "name": "Cape of skulls", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1, + "dstab": 9, + "dslash": 9, + "dcrush": 9, + "dmagic": 9, + "drange": 9 + } + }, + "23354": { + "name": "Amulet of power (t)", + "equipable": true, + "weight": 0.01, + "equipment": { + "slot": 2, + "astab": 6, + "aslash": 6, + "acrush": 6, + "amagic": 6, + "arange": 6, + "dstab": 6, + "dslash": 6, + "dcrush": 6, + "dmagic": 6, + "drange": 6, + "str": 6, + "prayer": 1 + } + }, + "23357": { + "name": "Rain bow", + "equipable": true, + "weight": 1.36, + "equipment": { + "slot": 3, + "arange": 8, + "aspeed": 4 + } + }, + "23360": { + "name": "Ham joint", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "aspeed": 3 + } + }, + "23363": { + "name": "Staff of bob the cat", + "equipable": true, + "weight": 2.0, + "equipment": { + "slot": 3, + "astab": 2, + "aslash": -1, + "acrush": 10, + "amagic": 10, + "dstab": 2, + "dslash": 3, + "dcrush": 1, + "dmagic": 10, + "str": 7, + "aspeed": 5 + } + }, + "23366": { + "name": "Black platebody (h1)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "23369": { + "name": "Black platebody (h2)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "23372": { + "name": "Black platebody (h3)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "23375": { + "name": "Black platebody (h4)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "23378": { + "name": "Black platebody (h5)", + "equipable": true, + "weight": 9.979, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 41, + "dslash": 40, + "dcrush": 30, + "dmagic": -6, + "drange": 40 + } + }, + "23381": { + "name": "Leather body (g)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 4, + "amagic": -2, + "arange": 2, + "dstab": 8, + "dslash": 9, + "dcrush": 10, + "dmagic": 4, + "drange": 9 + } + }, + "23384": { + "name": "Leather chaps (g)", + "equipable": true, + "weight": 2.721, + "equipment": { + "slot": 7, + "arange": 4, + "dstab": 2, + "dslash": 2, + "dcrush": 1 + } + }, + "23387": { + "name": "Watson teleport" + }, + "23389": { + "name": "Spiked manacles", + "equipable": true, + "weight": 3.0, + "equipment": { + "slot": 10, + "amagic": -3, + "arange": -1, + "dmagic": -4, + "str": 4 + } + }, + "23392": { + "name": "Adamant platebody (h1)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "23395": { + "name": "Adamant platebody (h2)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "23398": { + "name": "Adamant platebody (h3)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "23401": { + "name": "Adamant platebody (h4)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "23404": { + "name": "Adamant platebody (h5)", + "equipable": true, + "weight": 11.339, + "equipment": { + "slot": 4, + "amagic": -30, + "arange": -10, + "dstab": 65, + "dslash": 63, + "dcrush": 55, + "dmagic": -6, + "drange": 63 + } + }, + "23407": { + "name": "Wolf mask", + "equipable": true, + "weight": 2.2, + "equipment": { + "slot": 0 + } + }, + "23410": { + "name": "Wolf cloak", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 1 + } + }, + "23413": { + "name": "Climbing boots (g)", + "equipable": true, + "weight": 0.34, + "equipment": { + "slot": 10, + "dslash": 2, + "dcrush": 2, + "str": 2 + } + }, + "23417": { + "name": "Puzzle box (master)" + }, + "23442": { + "name": "Clue geode (beginner)" + }, + "23444": { + "name": "Tormented bracelet (or)", + "equipable": true, + "equipment": { + "slot": 9, + "amagic": 10, + "mdmg": 5, + "prayer": 2 + } + }, + "23446": { + "name": "Giant easter egg", + "equipable": true, + "weight": 15.0, + "equipment": { + "slot": 3, + "astab": -100, + "aslash": -100, + "acrush": -50, + "str": -10, + "aspeed": 4 + } + }, + "23448": { + "name": "Bunnyman mask", + "weight": 0.3 + }, + "23458": { + "name": "Enchanted lyre(i)", + "equipable": true, + "weight": 1.814, + "equipment": { + "slot": 3, + "aspeed": 4 + } + }, + "23460": { + "name": "Attacker icon", + "equipable": true + }, + "23461": { + "name": "Attacker icon", + "equipable": true + }, + "23462": { + "name": "Attacker icon", + "equipable": true + }, + "23463": { + "name": "Attacker icon", + "equipable": true + }, + "23464": { + "name": "Attacker icon", + "equipable": true + }, + "23465": { + "name": "Attacker icon", + "equipable": true + }, + "23466": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "23467": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "23468": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "23469": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "23470": { + "name": "Defender icon", + "equipable": true, + "weight": 0.001 + }, + "23471": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23472": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23473": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23474": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23475": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23476": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23477": { + "name": "Collector icon", + "equipable": true, + "weight": 0.001 + }, + "23478": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23479": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23480": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23481": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23482": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23483": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23484": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23485": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23486": { + "name": "Healer icon", + "equipable": true, + "weight": 0.001 + }, + "23490": { + "name": "Larran's key" + }, + "23497": { + "name": "Temple coin", + "quest": true + }, + "23499": { + "name": "Grubby key" + }, + "23502": { + "name": "Temple key" + }, + "23504": { + "name": "Tome of the moon", + "quest": true, + "weight": 1.0 + }, + "23506": { + "name": "Tome of the sun", + "quest": true, + "weight": 1.0 + }, + "23508": { + "name": "Tome of the temple", + "quest": true, + "weight": 1.0 + }, + "23510": { + "name": "Tattered moon page" + }, + "23512": { + "name": "Tattered sun page" + }, + "23514": { + "name": "Tattered temple page" + }, + "23516": { + "name": "Lamp of knowledge", + "quest": true, + "weight": 0.1 + }, + "23517": { + "name": "Giant egg sac(full)", + "weight": 5.0 + }, + "23520": { + "name": "Giant egg sac", + "weight": 3.0 + }, + "23522": { + "name": "Mask of ranul", + "equipable": true, + "weight": 0.3, + "equipment": { + "slot": 0, + "amagic": 2, + "dmagic": 2 + } + }, + "23525": { + "name": "Jar of eyes", + "weight": 1.0 + }, + "23528": { + "name": "Sarachnis cudgel", + "equipable": true, + "weight": 0.4, + "equipment": { + "slot": 3, + "astab": 30, + "acrush": 70, + "str": 70, + "aspeed": 4 + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json b/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json index 37072ae9b1..bba7233ee1 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/ge_limits.json @@ -3088,6 +3088,7 @@ "19627": 10000, "19629": 10000, "19631": 10000, + "19653": 100, "19656": 13000, "19662": 10000, "19665": 13000, diff --git a/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm b/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm index c9a0d99f8d..b5f275eab2 100644 --- a/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm +++ b/runelite-client/src/main/scripts/ScrollWheelZoomHandler.rs2asm @@ -11,9 +11,9 @@ iconst 0 iload 0 iconst 25 - sconst "scrollWheelZoomIncrement" + sconst "scrollWheelZoomIncrement" runelite_callback - multiply + multiply sub istore 1 iconst 512 diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java index c0b81a9665..472e2dfcb8 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java @@ -50,7 +50,6 @@ import net.runelite.client.RuneLite; import net.runelite.client.RuneLiteModule; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigItem; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.rs.ClientUpdateCheckMode; import static org.junit.Assert.assertEquals; import org.junit.Before; @@ -129,10 +128,6 @@ public class PluginManagerTest pluginManager.loadCorePlugins(); plugins = pluginManager.getPlugins(); - // Check that the plugins register with the eventbus without errors - EventBus eventBus = new EventBus(); - plugins.forEach(eventBus::register); - expected = pluginClasses.stream() .map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class)) .filter(Objects::nonNull) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java index d14e3ae301..a3183e83f2 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/motherlode/MotherlodePluginTest.java @@ -116,7 +116,7 @@ public class MotherlodePluginTest { // set inMlm GameStateChanged gameStateChanged = new GameStateChanged(); - gameStateChanged.setGameState(GameState.LOGGED_IN); + gameStateChanged.setGameState(GameState.LOADING); motherlodePlugin.onGameStateChanged(gameStateChanged); // Initial sack count @@ -178,4 +178,4 @@ public class MotherlodePluginTest when(item.getQuantity()).thenReturn(quantity); return item; } -} \ No newline at end of file +} 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 index 169caac2a9..07cb08987b 100644 --- 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 @@ -34,8 +34,10 @@ import net.runelite.api.ChatMessageType; import static net.runelite.api.ChatMessageType.GAMEMESSAGE; import net.runelite.api.Client; import net.runelite.api.MessageNode; +import net.runelite.api.Skill; import net.runelite.api.Varbits; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.Widget; @@ -362,6 +364,9 @@ public class SlayerPluginTest slayerPlugin.getCurrentTask().setTaskName("cows"); slayerPlugin.getCurrentTask().setAmount(42); + final ExperienceChanged experienceChanged = new ExperienceChanged(); + experienceChanged.setSkill(Skill.SLAYER); + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Perterter", TASK_COMPLETE, null, 0); slayerPlugin.onChatMessage(chatMessageEvent); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java index 65951bc9c5..09aaf32a92 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSActorMixin.java @@ -188,7 +188,7 @@ public abstract class RSActorMixin implements RSActor { AnimationChanged animationChange = new AnimationChanged(); animationChange.setActor(this); - client.getCallbacks().post(animationChange); + client.getCallbacks().post(AnimationChanged.class, animationChange); } @FieldHook("spotAnimation") @@ -197,7 +197,7 @@ public abstract class RSActorMixin implements RSActor { SpotAnimationChanged spotAnimationChanged = new SpotAnimationChanged(); spotAnimationChanged.setActor(this); - client.getCallbacks().post(spotAnimationChanged); + client.getCallbacks().post(SpotAnimationChanged.class, spotAnimationChanged); } @FieldHook("targetIndex") @@ -205,7 +205,7 @@ public abstract class RSActorMixin implements RSActor public void interactingChanged(int idx) { InteractingChanged interactingChanged = new InteractingChanged(this, getInteracting()); - client.getCallbacks().post(interactingChanged); + client.getCallbacks().post(InteractingChanged.class, interactingChanged); } @FieldHook("overheadText") @@ -216,7 +216,7 @@ public abstract class RSActorMixin implements RSActor if (overheadText != null) { OverheadTextChanged overheadTextChanged = new OverheadTextChanged(this, overheadText); - client.getCallbacks().post(overheadTextChanged); + client.getCallbacks().post(OverheadTextChanged.class, overheadTextChanged); } } @@ -252,7 +252,7 @@ public abstract class RSActorMixin implements RSActor client.getLogger().debug("You died!"); LocalPlayerDeath event = LocalPlayerDeath.INSTANCE; - client.getCallbacks().post(event); + client.getCallbacks().post(LocalPlayerDeath.class, event); } else if (this instanceof RSNPC) { @@ -281,6 +281,6 @@ public abstract class RSActorMixin implements RSActor final HitsplatApplied event = new HitsplatApplied(); event.setActor(this); event.setHitsplat(hitsplat); - client.getCallbacks().post(event); + client.getCallbacks().post(HitsplatApplied.class, event); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClanChatMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClanChatMixin.java index beacf0eec4..3b2fba39bc 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClanChatMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClanChatMixin.java @@ -28,7 +28,7 @@ public abstract class RSClanChatMixin implements RSClanChat } ClanMemberJoined event = new ClanMemberJoined(member); - client.getCallbacks().postDeferred(event); + client.getCallbacks().postDeferred(ClanMemberJoined.class, event); } @Inject @@ -42,6 +42,6 @@ public abstract class RSClanChatMixin implements RSClanChat } ClanMemberLeft event = new ClanMemberLeft(member); - client.getCallbacks().postDeferred(event); + client.getCallbacks().postDeferred(ClanMemberLeft.class, event); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index cca4cae90d..43094bc482 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -208,9 +208,15 @@ public abstract class RSClientMixin implements RSClient @Inject private static boolean hideFriendAttackOptions = false; + @Inject + private static boolean hideClanmateAttackOptions = false; + @Inject private static boolean hideFriendCastOptions = false; + @Inject + private static boolean hideClanmateCastOptions = false; + @Inject private static Set unhiddenCasts = new HashSet(); @@ -228,6 +234,20 @@ public abstract class RSClientMixin implements RSClient hideFriendCastOptions = yes; } + @Inject + @Override + public void setHideClanmateAttackOptions(boolean yes) + { + hideClanmateAttackOptions = yes; + } + + @Inject + @Override + public void setHideClanmateCastOptions(boolean yes) + { + hideClanmateCastOptions = yes; + } + @Inject @Override public void setUnhiddenCasts(Set casts) @@ -698,7 +718,7 @@ public abstract class RSClientMixin implements RSClient ) ); - client.getCallbacks().post(event); + client.getCallbacks().post(MenuEntryAdded.class, event); } } @@ -909,7 +929,7 @@ public abstract class RSClientMixin implements RSClient { DraggingWidgetChanged draggingWidgetChanged = new DraggingWidgetChanged(); draggingWidgetChanged.setDraggingWidget(client.isDraggingWidget()); - client.getCallbacks().post(draggingWidgetChanged); + client.getCallbacks().post(DraggingWidgetChanged.class, draggingWidgetChanged); } @Inject @@ -947,7 +967,7 @@ public abstract class RSClientMixin implements RSClient { WidgetLoaded event = new WidgetLoaded(); event.setGroupId(groupId); - client.getCallbacks().post(event); + client.getCallbacks().post(WidgetLoaded.class, event); } } @@ -985,7 +1005,7 @@ public abstract class RSClientMixin implements RSClient { Skill updatedSkill = possibleSkills[idx]; experienceChanged.setSkill(updatedSkill); - client.getCallbacks().post(experienceChanged); + client.getCallbacks().post(ExperienceChanged.class, experienceChanged); } } @@ -1000,7 +1020,7 @@ public abstract class RSClientMixin implements RSClient Skill updatedSkill = skills[idx]; BoostedLevelChanged boostedLevelChanged = new BoostedLevelChanged(); boostedLevelChanged.setSkill(updatedSkill); - client.getCallbacks().post(boostedLevelChanged); + client.getCallbacks().post(BoostedLevelChanged.class, boostedLevelChanged); } } @@ -1019,7 +1039,7 @@ public abstract class RSClientMixin implements RSClient PlayerMenuOptionsChanged optionsChanged = new PlayerMenuOptionsChanged(); optionsChanged.setIndex(idx); - client.getCallbacks().post(optionsChanged); + client.getCallbacks().post(PlayerMenuOptionsChanged.class, optionsChanged); } @FieldHook("gameState") @@ -1028,7 +1048,7 @@ public abstract class RSClientMixin implements RSClient { GameStateChanged gameStateChange = new GameStateChanged(); gameStateChange.setGameState(client.getGameState()); - client.getCallbacks().post(gameStateChange); + client.getCallbacks().post(GameStateChanged.class, gameStateChange); } @@ -1047,7 +1067,7 @@ public abstract class RSClientMixin implements RSClient { npc.setIndex(idx); - client.getCallbacks().postDeferred(new NpcSpawned(npc)); + client.getCallbacks().postDeferred(NpcSpawned.class, new NpcSpawned(npc)); } } @@ -1067,11 +1087,11 @@ public abstract class RSClientMixin implements RSClient if (oldPlayer != null) { - client.getCallbacks().post(new PlayerDespawned(oldPlayer)); + client.getCallbacks().post(PlayerDespawned.class, new PlayerDespawned(oldPlayer)); } if (player != null) { - client.getCallbacks().postDeferred(new PlayerSpawned(player)); + client.getCallbacks().postDeferred(PlayerSpawned.class, new PlayerSpawned(player)); } } @@ -1094,7 +1114,7 @@ public abstract class RSClientMixin implements RSClient GrandExchangeOfferChanged offerChangedEvent = new GrandExchangeOfferChanged(); offerChangedEvent.setOffer(internalOffer); offerChangedEvent.setSlot(idx); - client.getCallbacks().post(offerChangedEvent); + client.getCallbacks().post(GrandExchangeOfferChanged.class, offerChangedEvent); } @FieldHook("Varps_main") @@ -1103,7 +1123,7 @@ public abstract class RSClientMixin implements RSClient { VarbitChanged varbitChanged = new VarbitChanged(); varbitChanged.setIndex(idx); - client.getCallbacks().post(varbitChanged); + client.getCallbacks().post(VarbitChanged.class, varbitChanged); } @FieldHook("isResizable") @@ -1117,7 +1137,7 @@ public abstract class RSClientMixin implements RSClient { ResizeableChanged resizeableChanged = new ResizeableChanged(); resizeableChanged.setResized(isResized); - client.getCallbacks().post(resizeableChanged); + client.getCallbacks().post(ResizeableChanged.class, resizeableChanged); oldIsResized = isResized; } @@ -1127,21 +1147,21 @@ public abstract class RSClientMixin implements RSClient @Inject public static void clanMemberManagerChanged(int idx) { - client.getCallbacks().post(new ClanChanged(client.getClanMemberManager() != null)); + client.getCallbacks().post(ClanChanged.class, new ClanChanged(client.getClanMemberManager() != null)); } @FieldHook("canvasWidth") @Inject public static void canvasWidthChanged(int idx) { - client.getCallbacks().post(CanvasSizeChanged.INSTANCE); + client.getCallbacks().post(CanvasSizeChanged.class, CanvasSizeChanged.INSTANCE); } @FieldHook("canvasHeight") @Inject public static void canvasHeightChanged(int idx) { - client.getCallbacks().post(CanvasSizeChanged.INSTANCE); + client.getCallbacks().post(CanvasSizeChanged.class, CanvasSizeChanged.INSTANCE); } @Inject @@ -1305,7 +1325,7 @@ public abstract class RSClientMixin implements RSClient authentic ); - client.getCallbacks().post(menuOptionClicked); + client.getCallbacks().post(MenuOptionClicked.class, menuOptionClicked); if (menuOptionClicked.isConsumed()) { @@ -1329,7 +1349,7 @@ public abstract class RSClientMixin implements RSClient { if (client.getTempMenuAction() != null) { - client.getCallbacks().post(WidgetPressed.INSTANCE); + client.getCallbacks().post(WidgetPressed.class, WidgetPressed.INSTANCE); } } @@ -1337,7 +1357,7 @@ public abstract class RSClientMixin implements RSClient @Inject public static void onUsernameChanged(int idx) { - client.getCallbacks().post(UsernameChanged.INSTANCE); + client.getCallbacks().post(UsernameChanged.class, UsernameChanged.INSTANCE); } @Override @@ -1368,7 +1388,7 @@ public abstract class RSClientMixin implements RSClient { final MenuOpened event = new MenuOpened(); event.setMenuEntries(getMenuEntries()); - callbacks.post(event); + callbacks.post(MenuOpened.class, event); } @Inject @@ -1395,7 +1415,7 @@ public abstract class RSClientMixin implements RSClient final ChatMessageType chatMessageType = ChatMessageType.of(type); final ChatMessage chatMessage = new ChatMessage(messageNode, chatMessageType, name, message, sender, messageNode.getTimestamp()); - client.getCallbacks().post(chatMessage); + client.getCallbacks().post(ChatMessage.class, chatMessage); } @Inject @@ -1579,7 +1599,7 @@ public abstract class RSClientMixin implements RSClient @FieldHook("cycleCntr") public static void onCycleCntrChanged(int idx) { - client.getCallbacks().post(ClientTick.INSTANCE); + client.getCallbacks().post(ClientTick.class, ClientTick.INSTANCE); } @Copy("shouldLeftClickOpenMenu") @@ -1597,7 +1617,7 @@ public abstract class RSClientMixin implements RSClient } MenuShouldLeftClick menuShouldLeftClick = new MenuShouldLeftClick(); - client.getCallbacks().post(menuShouldLeftClick); + client.getCallbacks().post(MenuShouldLeftClick.class, menuShouldLeftClick); if (menuShouldLeftClick.isForceRightClick()) { @@ -1644,12 +1664,11 @@ public abstract class RSClientMixin implements RSClient { if (client.isSpellSelected()) { - return hideFriendCastOptions - && (p.isFriended() || p.isClanMember()) - && !unhiddenCasts.contains(client.getSelectedSpellName()); + return ((hideFriendCastOptions && p.isFriended()) || (hideClanmateCastOptions && p.isClanMember())) + && !unhiddenCasts.contains(client.getSelectedSpellName().replaceAll("<[^>]*>", "").toLowerCase()); } - return hideFriendAttackOptions && (p.isFriended() || p.isClanMember()); + return ((hideFriendAttackOptions && p.isFriended()) || (hideClanmateAttackOptions && p.isClanMember())); } @Inject diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSDynamicObjectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSDynamicObjectMixin.java index ed1a4a70b9..6d6ba9711f 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSDynamicObjectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSDynamicObjectMixin.java @@ -96,7 +96,7 @@ public abstract class RSDynamicObjectMixin implements RSDynamicObject DynamicObjectAnimationChanged dynamicObjectAnimationChanged = new DynamicObjectAnimationChanged(); dynamicObjectAnimationChanged.setObject(id); dynamicObjectAnimationChanged.setAnimation(animationID); - client.getCallbacks().post(dynamicObjectAnimationChanged); + client.getCallbacks().post(DynamicObjectAnimationChanged.class, dynamicObjectAnimationChanged); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendSystemMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendSystemMixin.java index d273a3bf33..f8237649c5 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendSystemMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSFriendSystemMixin.java @@ -20,7 +20,7 @@ public abstract class RSFriendSystemMixin implements RSFriendSystem public void rl$removeFriend(String friendName) { FriendRemoved friendRemoved = new FriendRemoved(friendName); - client.getCallbacks().post(friendRemoved); + client.getCallbacks().post(FriendRemoved.class, friendRemoved); } @MethodHook("addFriend") @@ -28,6 +28,6 @@ public abstract class RSFriendSystemMixin implements RSFriendSystem public void rl$addFriend(String friendName) { FriendAdded friendAdded = new FriendAdded(friendName); - client.getCallbacks().post(friendAdded); + client.getCallbacks().post(FriendAdded.class, friendAdded); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java index e45d2612e7..2f01378803 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java @@ -72,7 +72,7 @@ public abstract class RSGameShellMixin implements RSGameShell { final FocusChanged focusChanged = new FocusChanged(); focusChanged.setFocused(true); - client.getCallbacks().post(focusChanged); + client.getCallbacks().post(FocusChanged.class, focusChanged); } @Inject diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGraphicsObjectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGraphicsObjectMixin.java index c7757732ba..4d5b4d9371 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGraphicsObjectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGraphicsObjectMixin.java @@ -18,7 +18,7 @@ public abstract class RSGraphicsObjectMixin implements RSGraphicsObject RSGraphicsObjectMixin() { final GraphicsObjectCreated event = new GraphicsObjectCreated(this); - client.getCallbacks().post(event); + client.getCallbacks().post(GraphicsObjectCreated.class, event); } @Override diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGroundItemMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGroundItemMixin.java index 23d0ce6586..f85f894617 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGroundItemMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGroundItemMixin.java @@ -67,7 +67,7 @@ public abstract class RSGroundItemMixin implements RSGroundItem client.getLogger().debug("Item quantity changed: {} ({} -> {})", getId(), getQuantity(), quantity); ItemQuantityChanged itemQuantityChanged = new ItemQuantityChanged(this, getTile(), getQuantity(), quantity); - client.getCallbacks().post(itemQuantityChanged); + client.getCallbacks().post(ItemQuantityChanged.class, itemQuantityChanged); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarDefinitionMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarDefinitionMixin.java index 383892e7b5..6c1090bf30 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarDefinitionMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarDefinitionMixin.java @@ -21,6 +21,6 @@ public abstract class RSHealthBarDefinitionMixin implements RSHealthBarDefinitio { PostHealthBar postHealthBar = new PostHealthBar(); postHealthBar.setHealthBar(this); - client.getCallbacks().post(postHealthBar); + client.getCallbacks().post(PostHealthBar.class, postHealthBar); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSItemContainerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSItemContainerMixin.java index fe1149b101..a2d807e09c 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSItemContainerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSItemContainerMixin.java @@ -97,6 +97,6 @@ public abstract class RSItemContainerMixin implements RSItemContainer rl$lastContainer = itemContainerId; ItemContainerChanged event = new ItemContainerChanged(itemContainerId, client.getItemContainer(container)); - client.getCallbacks().postDeferred(event); + client.getCallbacks().postDeferred(ItemContainerChanged.class, event); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSItemDefinitionMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSItemDefinitionMixin.java index 68105f05bc..69d0a0cf27 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSItemDefinitionMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSItemDefinitionMixin.java @@ -62,6 +62,6 @@ public abstract class RSItemDefinitionMixin implements RSItemDefinition { final PostItemDefinition event = new PostItemDefinition(); event.setItemDefinition(this); - client.getCallbacks().post(event); + client.getCallbacks().post(PostItemDefinition.class, event); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSKeyHandlerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSKeyHandlerMixin.java index a7879dee08..d5e4a71392 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSKeyHandlerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSKeyHandlerMixin.java @@ -66,6 +66,6 @@ public abstract class RSKeyHandlerMixin implements RSKeyHandler { final FocusChanged focusChanged = new FocusChanged(); focusChanged.setFocused(false); - client.getCallbacks().post(focusChanged); + client.getCallbacks().post(FocusChanged.class, focusChanged); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCDefinitionMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCDefinitionMixin.java index 07d16f949a..345605597a 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCDefinitionMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCDefinitionMixin.java @@ -45,6 +45,6 @@ public abstract class RSNPCDefinitionMixin implements RSNPCDefinition NpcActionChanged npcActionChanged = new NpcActionChanged(); npcActionChanged.setNpcDefinition(this); npcActionChanged.setIdx(idx); - client.getCallbacks().post(npcActionChanged); + client.getCallbacks().post(NpcActionChanged.class, npcActionChanged); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java index e33afa700b..bb7932fe63 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java @@ -110,11 +110,11 @@ public abstract class RSNPCMixin implements RSNPC { if (composition == null) { - client.getCallbacks().post(new NpcDespawned(this)); + client.getCallbacks().post(NpcDespawned.class, new NpcDespawned(this)); } else if (this.getId() != -1) { - client.getCallbacks().post(new NpcDefinitionChanged(this)); + client.getCallbacks().post(NpcDefinitionChanged.class, new NpcDefinitionChanged(this)); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSProjectileMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSProjectileMixin.java index 1c10eeb835..c7ea22cac6 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSProjectileMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSProjectileMixin.java @@ -48,7 +48,7 @@ public abstract class RSProjectileMixin implements RSProjectile { final ProjectileSpawned projectileSpawned = new ProjectileSpawned(); projectileSpawned.setProjectile(this); - client.getCallbacks().post(projectileSpawned); + client.getCallbacks().post(ProjectileSpawned.class, projectileSpawned); } @Inject @@ -109,6 +109,6 @@ public abstract class RSProjectileMixin implements RSProjectile projectileMoved.setProjectile(this); projectileMoved.setPosition(position); projectileMoved.setZ(targetZ); - client.getCallbacks().post(projectileMoved); + client.getCallbacks().post(ProjectileMoved.class, projectileMoved); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java index ed17140360..7e7f158253 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSTileMixin.java @@ -129,14 +129,14 @@ public abstract class RSTileMixin implements RSTile WallObjectDespawned wallObjectDespawned = new WallObjectDespawned(); wallObjectDespawned.setTile(this); wallObjectDespawned.setWallObject(previous); - client.getCallbacks().post(wallObjectDespawned); + client.getCallbacks().post(WallObjectDespawned.class, wallObjectDespawned); } else if (current != null && previous == null) { WallObjectSpawned wallObjectSpawned = new WallObjectSpawned(); wallObjectSpawned.setTile(this); wallObjectSpawned.setWallObject(current); - client.getCallbacks().post(wallObjectSpawned); + client.getCallbacks().post(WallObjectSpawned.class, wallObjectSpawned); } else if (current != null) { @@ -144,7 +144,7 @@ public abstract class RSTileMixin implements RSTile wallObjectChanged.setTile(this); wallObjectChanged.setPrevious(previous); wallObjectChanged.setWallObject(current); - client.getCallbacks().post(wallObjectChanged); + client.getCallbacks().post(WallObjectChanged.class, wallObjectChanged); } } @@ -162,14 +162,14 @@ public abstract class RSTileMixin implements RSTile DecorativeObjectDespawned decorativeObjectDespawned = new DecorativeObjectDespawned(); decorativeObjectDespawned.setTile(this); decorativeObjectDespawned.setDecorativeObject(previous); - client.getCallbacks().post(decorativeObjectDespawned); + client.getCallbacks().post(DecorativeObjectDespawned.class, decorativeObjectDespawned); } else if (current != null && previous == null) { DecorativeObjectSpawned decorativeObjectSpawned = new DecorativeObjectSpawned(); decorativeObjectSpawned.setTile(this); decorativeObjectSpawned.setDecorativeObject(current); - client.getCallbacks().post(decorativeObjectSpawned); + client.getCallbacks().post(DecorativeObjectSpawned.class, decorativeObjectSpawned); } else if (current != null) { @@ -177,7 +177,7 @@ public abstract class RSTileMixin implements RSTile decorativeObjectChanged.setTile(this); decorativeObjectChanged.setPrevious(previous); decorativeObjectChanged.setDecorativeObject(current); - client.getCallbacks().post(decorativeObjectChanged); + client.getCallbacks().post(DecorativeObjectChanged.class, decorativeObjectChanged); } } @@ -195,14 +195,14 @@ public abstract class RSTileMixin implements RSTile GroundObjectDespawned groundObjectDespawned = new GroundObjectDespawned(); groundObjectDespawned.setTile(this); groundObjectDespawned.setGroundObject(previous); - client.getCallbacks().post(groundObjectDespawned); + client.getCallbacks().post(GroundObjectDespawned.class, groundObjectDespawned); } else if (current != null && previous == null) { GroundObjectSpawned groundObjectSpawned = new GroundObjectSpawned(); groundObjectSpawned.setTile(this); groundObjectSpawned.setGroundObject(current); - client.getCallbacks().post(groundObjectSpawned); + client.getCallbacks().post(GroundObjectSpawned.class, groundObjectSpawned); } else if (current != null) { @@ -210,7 +210,7 @@ public abstract class RSTileMixin implements RSTile groundObjectChanged.setTile(this); groundObjectChanged.setPrevious(previous); groundObjectChanged.setGroundObject(current); - client.getCallbacks().post(groundObjectChanged); + client.getCallbacks().post(GroundObjectChanged.class, groundObjectChanged); } } @@ -285,7 +285,7 @@ public abstract class RSTileMixin implements RSTile GameObjectDespawned gameObjectDespawned = new GameObjectDespawned(); gameObjectDespawned.setTile(this); gameObjectDespawned.setGameObject(previous); - client.getCallbacks().post(gameObjectDespawned); + client.getCallbacks().post(GameObjectDespawned.class, gameObjectDespawned); } else if (previous == null) { @@ -299,7 +299,7 @@ public abstract class RSTileMixin implements RSTile GameObjectSpawned gameObjectSpawned = new GameObjectSpawned(); gameObjectSpawned.setTile(this); gameObjectSpawned.setGameObject(current); - client.getCallbacks().post(gameObjectSpawned); + client.getCallbacks().post(GameObjectSpawned.class, gameObjectSpawned); } else { @@ -314,7 +314,7 @@ public abstract class RSTileMixin implements RSTile gameObjectsChanged.setTile(this); gameObjectsChanged.setPrevious(previous); gameObjectsChanged.setGameObject(current); - client.getCallbacks().post(gameObjectsChanged); + client.getCallbacks().post(GameObjectChanged.class, gameObjectsChanged); } } @@ -340,7 +340,7 @@ public abstract class RSTileMixin implements RSTile { RSGroundItem item = (RSGroundItem) cur; ItemDespawned itemDespawned = new ItemDespawned(this, item); - client.getCallbacks().post(itemDespawned); + client.getCallbacks().post(ItemDespawned.class, itemDespawned); } } lastGroundItems[z][x][y] = newQueue; @@ -358,7 +358,7 @@ public abstract class RSTileMixin implements RSTile if (lastUnlink != null) { ItemDespawned itemDespawned = new ItemDespawned(this, lastUnlink); - client.getCallbacks().post(itemDespawned); + client.getCallbacks().post(ItemDespawned.class, itemDespawned); } return; } @@ -370,7 +370,7 @@ public abstract class RSTileMixin implements RSTile if (lastUnlink != null) { ItemDespawned itemDespawned = new ItemDespawned(this, lastUnlink); - client.getCallbacks().post(itemDespawned); + client.getCallbacks().post(ItemDespawned.class, itemDespawned); } return; } @@ -403,7 +403,7 @@ public abstract class RSTileMixin implements RSTile if (lastUnlink != null && lastUnlink != previous && lastUnlink != next) { ItemDespawned itemDespawned = new ItemDespawned(this, lastUnlink); - client.getCallbacks().post(itemDespawned); + client.getCallbacks().post(ItemDespawned.class, itemDespawned); } if (current == null) @@ -418,7 +418,7 @@ public abstract class RSTileMixin implements RSTile item.setY(y); ItemSpawned itemSpawned = new ItemSpawned(this, item); - client.getCallbacks().post(itemSpawned); + client.getCallbacks().post(ItemSpawned.class, itemSpawned); current = forward ? current.getNext() : current.getPrevious(); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java index 86a757092b..ecb48f919c 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSVarcsMixin.java @@ -19,13 +19,13 @@ public abstract class RSVarcsMixin implements RSVarcs @Inject public void onVarCIntChanged(int id, int value) { - client.getCallbacks().post(new VarClientIntChanged(id)); + client.getCallbacks().post(VarClientIntChanged.class, new VarClientIntChanged(id)); } @MethodHook(value = "setString", end = true) @Inject public void onVarCStrChanged(int id, String value) { - client.getCallbacks().post(new VarClientStrChanged(id)); + client.getCallbacks().post(VarClientStrChanged.class, new VarClientStrChanged(id)); } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java index 55db558d24..543bdf5c48 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWidgetMixin.java @@ -417,7 +417,7 @@ public abstract class RSWidgetMixin implements RSWidget event.setWidget(this); event.setHidden(hidden); - client.getCallbacks().post(event); + client.getCallbacks().post(WidgetHiddenChanged.class, event); RSWidget[] children = getChildren(); @@ -502,7 +502,7 @@ public abstract class RSWidgetMixin implements RSWidget client.getLogger().trace("Posting widget position changed"); WidgetPositioned widgetPositioned = WidgetPositioned.INSTANCE; - client.getCallbacks().postDeferred(widgetPositioned); + client.getCallbacks().postDeferred(WidgetPositioned.class, widgetPositioned); } @Inject diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSWorldMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSWorldMixin.java index eefb479963..902e0fd96c 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSWorldMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSWorldMixin.java @@ -63,7 +63,7 @@ public abstract class RSWorldMixin implements RSWorld { // this is the last world in the list. WorldListLoad worldLoad = new WorldListLoad(worlds); - client.getCallbacks().post(worldLoad); + client.getCallbacks().post(WorldListLoad.class, worldLoad); } } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java index ab372ca932..b6c439d9fb 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/ScriptVMMixin.java @@ -101,7 +101,7 @@ public abstract class ScriptVMMixin implements RSClient ScriptCallbackEvent event = new ScriptCallbackEvent(); event.setScript(currentScript); event.setEventName(stringOp); - client.getCallbacks().post(event); + client.getCallbacks().post(ScriptCallbackEvent.class, event); return true; } return false; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java index 6338d07521..92738df760 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java @@ -123,7 +123,7 @@ public abstract class SoundEffectMixin implements RSClient SoundEffectPlayed event = new SoundEffectPlayed(); event.setSoundId(client.getQueuedSoundEffectIDs()[soundIndex]); event.setDelay(client.getQueuedSoundEffectDelays()[soundIndex]); - client.getCallbacks().post(event); + client.getCallbacks().post(SoundEffectPlayed.class, event); } else { @@ -139,7 +139,7 @@ public abstract class SoundEffectMixin implements RSClient event.setSceneY(y); event.setRange(range); event.setDelay(client.getQueuedSoundEffectDelays()[soundIndex]); - client.getCallbacks().post(event); + client.getCallbacks().post(AreaSoundEffectPlayed.class, event); } }