Merge remote-tracking branch 'Owain/2310-merge'

This commit is contained in:
Owain van Brakel
2019-10-31 18:54:24 +01:00
105 changed files with 1629 additions and 632 deletions

View File

@@ -1,6 +1,6 @@
name: OpenOSRS - CI name: OpenOSRS - CI (PR)
on: [pull_request, push] on: pull_request
jobs: jobs:
pr-lint: pr-lint:
@@ -76,3 +76,15 @@ jobs:
uses: hmarr/auto-approve-action@v2.0.0 uses: hmarr/auto-approve-action@v2.0.0
with: with:
github-token: "${{ secrets.GITHUB_TOKEN }}" github-token: "${{ secrets.GITHUB_TOKEN }}"
automerge:
name: Automerge
needs: approve
runs-on: ubuntu-latest
steps:
- name: automerge
uses: pascalgn/automerge-action@f84dd310ea4a19890c70a4ff11ab282a872fb94b
env:
AUTOMERGE: "automated pull request"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

58
.github/workflows/pr.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: OpenOSRS - CI (push)
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
name: Build
steps:
- uses: actions/checkout@v1
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Assembling
run: ./gradlew assemble --console=plain
- name: Building
run: ./gradlew build --stacktrace -x test -x checkstyleMain --console=plain
test:
runs-on: ubuntu-latest
name: Test
steps:
- uses: actions/checkout@v1
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Assembling
run: ./gradlew assemble --console=plain
- name: Testing
run: ./gradlew test --stacktrace --console=plain
checkstyle:
name: Checkstyle
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Assembling
run: ./gradlew assemble --console=plain
- name: Checking code conventions
run: ./gradlew checkstyleMain --console=plain

View File

@@ -31,38 +31,37 @@ import lombok.Data;
@Data @Data
public class NpcDefinition public class NpcDefinition
{ {
public final int id; public final int id;
public short[] recolorToFind;
public int rotation = 32;
public String name = "null"; public String name = "null";
public short[] recolorToReplace; public int size = 1;
public int[] models; public int[] models;
public int[] models_2; public int[] chatheadModels;
public int stanceAnimation = -1; public int standingAnimation = -1;
public int anInt2165 = -1; public int rotateLeftAnimation = -1;
public int tileSpacesOccupied = 1; public int rotateRightAnimation = -1;
public int walkAnimation = -1; public int walkingAnimation = -1;
public short[] retextureToReplace;
public int rotate90RightAnimation = -1;
public boolean aBool2170 = true;
public int resizeX = 128;
public int contrast = 0;
public int rotate180Animation = -1; public int rotate180Animation = -1;
public int varbitIndex = -1; public int rotate90RightAnimation = -1;
public String[] options = new String[5];
public boolean renderOnMinimap = true;
public int combatLevel = -1;
public int rotate90LeftAnimation = -1; public int rotate90LeftAnimation = -1;
public int resizeY = 128; public short[] recolorToFind;
public boolean hasRenderPriority = false; public short[] recolorToReplace;
public int ambient = 0;
public int headIcon = -1;
public int[] configs;
public short[] retextureToFind; public short[] retextureToFind;
public short[] retextureToReplace;
public String[] actions = new String[5];
public boolean isMinimapVisible = true;
public int combatLevel = -1;
public int widthScale = 128;
public int heightScale = 128;
public boolean hasRenderPriority;
public int ambient;
public int contrast;
public int headIcon = -1;
public int rotationSpeed = 32;
public int[] configs;
public int varbitId = -1;
public int varpIndex = -1; public int varpIndex = -1;
public boolean isClickable = true; public boolean isInteractable = true;
public int anInt2189 = -1; public boolean rotationFlag = true;
public boolean aBool2190 = false; public boolean isPet;
public Map<Integer, Object> params = null; public Map<Integer, Object> params;
} }

View File

@@ -24,13 +24,12 @@
*/ */
package net.runelite.cache.definitions.loaders; package net.runelite.cache.definitions.loaders;
import java.util.HashMap;
import net.runelite.cache.definitions.NpcDefinition; import net.runelite.cache.definitions.NpcDefinition;
import net.runelite.cache.io.InputStream; import net.runelite.cache.io.InputStream;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.HashMap;
public class NpcLoader public class NpcLoader
{ {
private static final Logger logger = LoggerFactory.getLogger(NpcLoader.class); private static final Logger logger = LoggerFactory.getLogger(NpcLoader.class);
@@ -67,7 +66,6 @@ public class NpcLoader
{ {
def.models[index] = stream.readUnsignedShort(); def.models[index] = stream.readUnsignedShort();
} }
} }
else if (opcode == 2) else if (opcode == 2)
{ {
@@ -75,37 +73,37 @@ public class NpcLoader
} }
else if (opcode == 12) else if (opcode == 12)
{ {
def.tileSpacesOccupied = stream.readUnsignedByte(); def.size = stream.readUnsignedByte();
} }
else if (opcode == 13) else if (opcode == 13)
{ {
def.stanceAnimation = stream.readUnsignedShort(); def.standingAnimation = stream.readUnsignedShort();
} }
else if (opcode == 14) else if (opcode == 14)
{ {
def.walkAnimation = stream.readUnsignedShort(); def.walkingAnimation = stream.readUnsignedShort();
} }
else if (opcode == 15) else if (opcode == 15)
{ {
def.anInt2165 = stream.readUnsignedShort(); def.rotateLeftAnimation = stream.readUnsignedShort();
} }
else if (opcode == 16) else if (opcode == 16)
{ {
def.anInt2189 = stream.readUnsignedShort(); def.rotateRightAnimation = stream.readUnsignedShort();
} }
else if (opcode == 17) else if (opcode == 17)
{ {
def.walkAnimation = stream.readUnsignedShort(); def.walkingAnimation = stream.readUnsignedShort();
def.rotate180Animation = stream.readUnsignedShort(); def.rotate180Animation = stream.readUnsignedShort();
def.rotate90RightAnimation = stream.readUnsignedShort(); def.rotate90RightAnimation = stream.readUnsignedShort();
def.rotate90LeftAnimation = stream.readUnsignedShort(); def.rotate90LeftAnimation = stream.readUnsignedShort();
} }
else if (opcode >= 30 && opcode < 35) else if (opcode >= 30 && opcode < 35)
{ {
def.options[opcode - 30] = stream.readString(); def.actions[opcode - 30] = stream.readString();
if (def.options[opcode - 30].equalsIgnoreCase("Hidden")) if (def.actions[opcode - 30].equalsIgnoreCase("Hidden"))
{ {
def.options[opcode - 30] = null; def.actions[opcode - 30] = null;
} }
} }
else if (opcode == 40) else if (opcode == 40)
@@ -137,17 +135,17 @@ public class NpcLoader
else if (opcode == 60) else if (opcode == 60)
{ {
length = stream.readUnsignedByte(); length = stream.readUnsignedByte();
def.models_2 = new int[length]; def.chatheadModels = new int[length];
for (index = 0; index < length; ++index) for (index = 0; index < length; ++index)
{ {
def.models_2[index] = stream.readUnsignedShort(); def.chatheadModels[index] = stream.readUnsignedShort();
} }
} }
else if (opcode == 93) else if (opcode == 93)
{ {
def.renderOnMinimap = false; def.isMinimapVisible = false;
} }
else if (opcode == 95) else if (opcode == 95)
{ {
@@ -155,11 +153,11 @@ public class NpcLoader
} }
else if (opcode == 97) else if (opcode == 97)
{ {
def.resizeX = stream.readUnsignedShort(); def.widthScale = stream.readUnsignedShort();
} }
else if (opcode == 98) else if (opcode == 98)
{ {
def.resizeY = stream.readUnsignedShort(); def.heightScale = stream.readUnsignedShort();
} }
else if (opcode == 99) else if (opcode == 99)
{ {
@@ -179,18 +177,18 @@ public class NpcLoader
} }
else if (opcode == 103) else if (opcode == 103)
{ {
def.rotation = stream.readUnsignedShort(); def.rotationSpeed = stream.readUnsignedShort();
} }
else if (opcode == 106) else if (opcode == 106)
{ {
def.varbitIndex = stream.readUnsignedShort(); def.varbitId = stream.readUnsignedShort();
if ('\uffff' == def.varbitIndex) if (def.varbitId == 65535)
{ {
def.varbitIndex = -1; def.varbitId = -1;
} }
def.varpIndex = stream.readUnsignedShort(); def.varpIndex = stream.readUnsignedShort();
if ('\uffff' == def.varpIndex) if (def.varpIndex == 65535)
{ {
def.varpIndex = -1; def.varpIndex = -1;
} }
@@ -212,26 +210,26 @@ public class NpcLoader
} }
else if (opcode == 107) else if (opcode == 107)
{ {
def.isClickable = false; def.isInteractable = false;
} }
else if (opcode == 109) else if (opcode == 109)
{ {
def.aBool2170 = false; def.rotationFlag = false;
} }
else if (opcode == 111) else if (opcode == 111)
{ {
def.aBool2190 = true; def.isPet = true;
} }
else if (opcode == 118) else if (opcode == 118)
{ {
def.varbitIndex = stream.readUnsignedShort(); def.varbitId = stream.readUnsignedShort();
if ('\uffff' == def.varbitIndex) if (def.varbitId == 65535)
{ {
def.varbitIndex = -1; def.varbitId = -1;
} }
def.varpIndex = stream.readUnsignedShort(); def.varpIndex = stream.readUnsignedShort();
if ('\uffff' == def.varpIndex) if (def.varpIndex == 65535)
{ {
def.varpIndex = -1; def.varpIndex = -1;
} }

View File

@@ -47,45 +47,45 @@ public class NpcSaver
out.writeByte(2); out.writeByte(2);
out.writeString(npc.name); out.writeString(npc.name);
} }
if (npc.tileSpacesOccupied != 1) if (npc.size != 1)
{ {
out.writeByte(12); out.writeByte(12);
out.writeByte(npc.tileSpacesOccupied); out.writeByte(npc.size);
} }
if (npc.stanceAnimation != -1) if (npc.standingAnimation != -1)
{ {
out.writeByte(13); out.writeByte(13);
out.writeShort(npc.stanceAnimation); out.writeShort(npc.standingAnimation);
} }
if (npc.walkAnimation != -1) if (npc.walkingAnimation != -1)
{ {
out.writeByte(14); out.writeByte(14);
out.writeShort(npc.walkAnimation); out.writeShort(npc.walkingAnimation);
} }
if (npc.anInt2165 != -1) if (npc.rotateLeftAnimation != -1)
{ {
out.writeByte(15); out.writeByte(15);
out.writeShort(npc.anInt2165); out.writeShort(npc.rotateLeftAnimation);
} }
if (npc.anInt2189 != -1) if (npc.rotateRightAnimation != -1)
{ {
out.writeByte(16); out.writeByte(16);
out.writeShort(npc.anInt2189); out.writeShort(npc.rotateRightAnimation);
} }
if (npc.rotate180Animation != -1 || npc.rotate90LeftAnimation != -1 || npc.rotate90RightAnimation != -1) if (npc.rotate180Animation != -1 || npc.rotate90LeftAnimation != -1 || npc.rotate90RightAnimation != -1)
{ {
out.writeByte(17); out.writeByte(17);
out.writeShort(npc.walkAnimation); out.writeShort(npc.walkingAnimation);
out.writeShort(npc.rotate180Animation); out.writeShort(npc.rotate180Animation);
out.writeShort(npc.rotate90RightAnimation); out.writeShort(npc.rotate90RightAnimation);
out.writeShort(npc.rotate90LeftAnimation); out.writeShort(npc.rotate90LeftAnimation);
} }
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
if (npc.options[i] != null) if (npc.actions[i] != null)
{ {
out.writeByte(30 + i); out.writeByte(30 + i);
out.writeString(npc.options[i]); out.writeString(npc.actions[i]);
} }
} }
if (npc.recolorToFind != null && npc.recolorToReplace != null) if (npc.recolorToFind != null && npc.recolorToReplace != null)
@@ -108,16 +108,16 @@ public class NpcSaver
out.writeShort(npc.retextureToReplace[i]); out.writeShort(npc.retextureToReplace[i]);
} }
} }
if (npc.models_2 != null) if (npc.chatheadModels != null)
{ {
out.writeByte(60); out.writeByte(60);
out.writeByte(npc.models_2.length); out.writeByte(npc.chatheadModels.length);
for (int modelId : npc.models_2) for (int modelId : npc.chatheadModels)
{ {
out.writeShort(modelId); out.writeShort(modelId);
} }
} }
if (!npc.renderOnMinimap) if (!npc.isMinimapVisible)
{ {
out.writeByte(93); out.writeByte(93);
} }
@@ -127,9 +127,9 @@ public class NpcSaver
out.writeShort(npc.combatLevel); out.writeShort(npc.combatLevel);
} }
out.writeByte(97); out.writeByte(97);
out.writeShort(npc.resizeX); out.writeShort(npc.widthScale);
out.writeByte(98); out.writeByte(98);
out.writeShort(npc.resizeY); out.writeShort(npc.heightScale);
if (npc.hasRenderPriority) if (npc.hasRenderPriority)
{ {
out.writeByte(99); out.writeByte(99);
@@ -144,23 +144,23 @@ public class NpcSaver
out.writeShort(npc.headIcon); out.writeShort(npc.headIcon);
} }
out.writeByte(103); out.writeByte(103);
out.writeShort(npc.rotation); out.writeShort(npc.rotationSpeed);
if (!npc.isClickable) if (!npc.isInteractable)
{ {
out.writeByte(107); out.writeByte(107);
} }
if (!npc.aBool2170) if (!npc.rotationFlag)
{ {
out.writeByte(109); out.writeByte(109);
} }
if (npc.aBool2190) if (npc.isPet)
{ {
out.writeByte(111); out.writeByte(111);
} }
if (npc.configs != null) if (npc.configs != null)
{ {
out.writeByte(118); out.writeByte(118);
out.writeShort(npc.varbitIndex); out.writeShort(npc.varbitId);
out.writeShort(npc.varpIndex); out.writeShort(npc.varpIndex);
int[] c = npc.configs; int[] c = npc.configs;

View File

@@ -25,13 +25,9 @@
package net.runelite.http.api; package net.runelite.http.api;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.runelite.http.api.item.ItemEquipmentStats;
import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.ItemStats;
import net.runelite.http.api.util.TypeAdapters;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@@ -60,12 +56,9 @@ public class RuneLiteAPI
public static final String RUNELITE_AUTH = "RUNELITE-AUTH"; public static final String RUNELITE_AUTH = "RUNELITE-AUTH";
public static final OkHttpClient CLIENT; public static final OkHttpClient CLIENT;
public static final Gson GSON = new GsonBuilder() public static final Gson GSON = new Gson();
.setPrettyPrinting() public static final MediaType JSON = MediaType.parse("application/json");
.registerTypeAdapter(ItemStats.class, TypeAdapters.ITEMSTATS) public static String userAgent;
.registerTypeAdapter(ItemEquipmentStats.class, TypeAdapters.EQUIPMENTSTATS)
.registerTypeAdapter(ItemPrice.class, TypeAdapters.ITEMPRICE)
.create();
private static final String BASE = "https://api.runelite.net"; private static final String BASE = "https://api.runelite.net";
private static final String WSBASE = "https://api.runelite.net/ws"; private static final String WSBASE = "https://api.runelite.net/ws";
@@ -76,8 +69,6 @@ public class RuneLiteAPI
private static final String MAVEN_METADATA = "http://repo.runelite.net/net/runelite/runelite-parent/maven-metadata.xml"; private static final String MAVEN_METADATA = "http://repo.runelite.net/net/runelite/runelite-parent/maven-metadata.xml";
private static final Properties properties = new Properties(); private static final Properties properties = new Properties();
private static String userAgent;
private static String version; private static String version;
private static String upstreamVersion; private static String upstreamVersion;
private static int rsVersion; private static int rsVersion;

View File

@@ -30,10 +30,10 @@ import java.util.UUID;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import static net.runelite.http.api.RuneLiteAPI.JSON;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@@ -42,7 +42,6 @@ import okhttp3.Response;
@AllArgsConstructor @AllArgsConstructor
public class GrandExchangeClient public class GrandExchangeClient
{ {
private static final MediaType JSON = MediaType.parse("application/json");
private static final Gson GSON = RuneLiteAPI.GSON; private static final Gson GSON = RuneLiteAPI.GSON;
private final UUID uuid; private final UUID uuid;

View File

@@ -36,10 +36,10 @@ import java.util.UUID;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import static net.runelite.http.api.RuneLiteAPI.JSON;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@@ -48,7 +48,6 @@ import okhttp3.Response;
@AllArgsConstructor @AllArgsConstructor
public class LootTrackerClient public class LootTrackerClient
{ {
private static final MediaType JSON = MediaType.parse("application/json");
private static final Gson GSON = RuneLiteAPI.GSON; private static final Gson GSON = RuneLiteAPI.GSON;
private final UUID uuid; private final UUID uuid;

View File

@@ -31,10 +31,10 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.List; import java.util.List;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import static net.runelite.http.api.RuneLiteAPI.JSON;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
@@ -43,8 +43,6 @@ import org.slf4j.LoggerFactory;
public class XteaClient public class XteaClient
{ {
private static final MediaType JSON = MediaType.parse("application/json");
private static final Logger logger = LoggerFactory.getLogger(XteaClient.class); private static final Logger logger = LoggerFactory.getLogger(XteaClient.class);
public void submit(XteaRequest xteaRequest) public void submit(XteaRequest xteaRequest)

View File

@@ -51,6 +51,7 @@ import net.runelite.http.api.config.ConfigEntry;
import net.runelite.http.api.config.Configuration; import net.runelite.http.api.config.Configuration;
import org.bson.Document; import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
@@ -66,11 +67,12 @@ public class ConfigService
@Autowired @Autowired
public ConfigService( public ConfigService(
MongoClient mongoClient MongoClient mongoClient,
@Value("${mongo.database}") String databaseName
) )
{ {
MongoDatabase database = mongoClient.getDatabase("config"); MongoDatabase database = mongoClient.getDatabase(databaseName);
MongoCollection<Document> collection = database.getCollection("config"); MongoCollection<Document> collection = database.getCollection("config");
this.mongoCollection = collection; this.mongoCollection = collection;

View File

@@ -32,10 +32,11 @@ redis:
mongo: mongo:
jndiName: java:comp/env/mongodb/runelite jndiName: java:comp/env/mongodb/runelite
database: runelite
# Twitter client for feed # Twitter client for feed
runelite: runelite:
twitter: twitter:
consumerkey: consumerkey:
secretkey: secretkey:
listid: 968949795153948673 listid: 1185897074786742273

View File

@@ -955,6 +955,42 @@ public interface Client extends GameShell
*/ */
List<GraphicsObject> getGraphicsObjects(); List<GraphicsObject> getGraphicsObjects();
/**
* Gets the music volume
* @return volume 0-255 inclusive
*/
int getMusicVolume();
/**
* Sets the music volume
* @param volume 0-255 inclusive
*/
void setMusicVolume(int volume);
/**
* Gets the sound effect volume
* @return volume 0-127 inclusive
*/
int getSoundEffectVolume();
/**
* Sets the sound effect volume
* @param volume 0-127 inclusive
*/
void setSoundEffectVolume(int volume);
/**
* Gets the area sound effect volume
* @return volume 0-127 inclusive
*/
int getAreaSoundEffectVolume();
/**
* Sets the area sound effect volume
* @param volume 0-127 inclusive
*/
void setAreaSoundEffectVolume(int volume);
/** /**
* Play a sound effect at the player's current location. This is how UI, * Play a sound effect at the player's current location. This is how UI,
* and player-generated (e.g. mining, woodcutting) sound effects are * and player-generated (e.g. mining, woodcutting) sound effects are

View File

@@ -29,6 +29,10 @@ package net.runelite.api;
*/ */
public enum InventoryID public enum InventoryID
{ {
/**
* Reward from fishing trawler
*/
FISHING_TRAWLER_REWARD(0),
/** /**
* Standard player inventory. * Standard player inventory.
*/ */

View File

@@ -25,170 +25,173 @@
package net.runelite.api; package net.runelite.api;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum Quest public enum Quest
{ {
//Free Quests //Free Quests
BLACK_KNIGHTS_FORTRESS(299, "Black Knights' Fortress", VarPlayer.QUEST_BLACK_KNIGHTS_FORTRESS), BLACK_KNIGHTS_FORTRESS(299, "Black Knights' Fortress"),
COOKS_ASSISTANT(300, "Cook's Assistant", VarPlayer.QUEST_COOKS_ASSISTANT), COOKS_ASSISTANT(300, "Cook's Assistant"),
THE_CORSAIR_CURSE(301, "The Corsair Curse", Varbits.QUEST_THE_CORSAIR_CURSE), THE_CORSAIR_CURSE(301, "The Corsair Curse"),
DEMON_SLAYER(302, "Demon Slayer", Varbits.QUEST_DEMON_SLAYER), DEMON_SLAYER(302, "Demon Slayer"),
DORICS_QUEST(303, "Doric's Quest", VarPlayer.QUEST_DORICS_QUEST), DORICS_QUEST(303, "Doric's Quest"),
DRAGON_SLAYER(304, "Dragon Slayer", VarPlayer.QUEST_DRAGON_SLAYER), DRAGON_SLAYER(304, "Dragon Slayer"),
ERNEST_THE_CHICKEN(305, "Ernest the Chicken", VarPlayer.QUEST_ERNEST_THE_CHICKEN), ERNEST_THE_CHICKEN(305, "Ernest the Chicken"),
GOBLIN_DIPLOMACY(306, "Goblin Diplomacy", Varbits.QUEST_GOBLIN_DIPLOMACY), GOBLIN_DIPLOMACY(306, "Goblin Diplomacy"),
IMP_CATCHER(307, "Imp Catcher", VarPlayer.QUEST_IMP_CATCHER), IMP_CATCHER(307, "Imp Catcher"),
THE_KNIGHTS_SWORD(308, "The Knight's Sword", VarPlayer.QUEST_THE_KNIGHTS_SWORD), THE_KNIGHTS_SWORD(308, "The Knight's Sword"),
MISTHALIN_MYSTERY(309, "Misthalin Mystery", Varbits.QUEST_MISTHALIN_MYSTERY), MISTHALIN_MYSTERY(309, "Misthalin Mystery"),
PIRATES_TREASURE(310, "Pirate's Treasure", VarPlayer.QUEST_PIRATES_TREASURE), PIRATES_TREASURE(310, "Pirate's Treasure"),
PRINCE_ALI_RESCUE(311, "Prince Ali Rescue", VarPlayer.QUEST_PRINCE_ALI_RESCUE), PRINCE_ALI_RESCUE(311, "Prince Ali Rescue"),
THE_RESTLESS_GHOST(312, "The Restless Ghost", VarPlayer.QUEST_THE_RESTLESS_GHOST), THE_RESTLESS_GHOST(312, "The Restless Ghost"),
ROMEO__JULIET(313, "Romeo & Juliet", VarPlayer.QUEST_ROMEO_AND_JULIET), ROMEO__JULIET(313, "Romeo & Juliet"),
RUNE_MYSTERIES(314, "Rune Mysteries", VarPlayer.QUEST_RUNE_MYSTERIES), RUNE_MYSTERIES(314, "Rune Mysteries"),
SHEEP_SHEARER(315, "Sheep Shearer", VarPlayer.QUEST_SHEEP_SHEARER), SHEEP_SHEARER(315, "Sheep Shearer"),
SHIELD_OF_ARRAV(316, "Shield of Arrav", VarPlayer.QUEST_SHIELD_OF_ARRAV), SHIELD_OF_ARRAV(316, "Shield of Arrav"),
VAMPIRE_SLAYER(317, "Vampire Slayer", VarPlayer.QUEST_VAMPIRE_SLAYER), VAMPIRE_SLAYER(317, "Vampire Slayer"),
WITCHS_POTION(318, "Witch's Potion", VarPlayer.QUEST_WITCHS_POTION), WITCHS_POTION(318, "Witch's Potion"),
X_MARKS_THE_SPOT(550, "X Marks the Spot", Varbits.QUEST_X_MARKS_THE_SPOT), X_MARKS_THE_SPOT(550, "X Marks the Spot"),
//Members' Quests //Members' Quests
ANIMAL_MAGNETISM(331, "Animal Magnetism", Varbits.QUEST_ANIMAL_MAGNETISM), ANIMAL_MAGNETISM(331, "Animal Magnetism"),
ANOTHER_SLICE_OF_HAM(332, "Another Slice of H.A.M.", Varbits.QUEST_ANOTHER_SLICE_OF_HAM), ANOTHER_SLICE_OF_HAM(332, "Another Slice of H.A.M."),
BETWEEN_A_ROCK(333, "Between a Rock...", Varbits.QUEST_BETWEEN_A_ROCK), BETWEEN_A_ROCK(333, "Between a Rock..."),
BIG_CHOMPY_BIRD_HUNTING(334, "Big Chompy Bird Hunting", VarPlayer.QUEST_BIG_CHOMPY_BIRD_HUNTING), BIG_CHOMPY_BIRD_HUNTING(334, "Big Chompy Bird Hunting"),
BIOHAZARD(335, "Biohazard", VarPlayer.QUEST_BIOHAZARD), BIOHAZARD(335, "Biohazard"),
CABIN_FEVER(336, "Cabin Fever", VarPlayer.QUEST_CABIN_FEVER), CABIN_FEVER(336, "Cabin Fever"),
CLOCK_TOWER(337, "Clock Tower", VarPlayer.QUEST_CLOCK_TOWER), CLOCK_TOWER(337, "Clock Tower"),
COLD_WAR(338, "Cold War", Varbits.QUEST_COLD_WAR), COLD_WAR(338, "Cold War"),
CONTACT(339, "Contact!", Varbits.QUEST_CONTACT), CONTACT(339, "Contact!"),
CREATURE_OF_FENKENSTRAIN(340, "Creature of Fenkenstrain", VarPlayer.QUEST_CREATURE_OF_FENKENSTRAIN), CREATURE_OF_FENKENSTRAIN(340, "Creature of Fenkenstrain"),
DARKNESS_OF_HALLOWVALE(341, "Darkness of Hallowvale", Varbits.QUEST_DARKNESS_OF_HALLOWVALE), DARKNESS_OF_HALLOWVALE(341, "Darkness of Hallowvale"),
DEATH_PLATEAU(342, "Death Plateau", VarPlayer.QUEST_DEATH_PLATEAU), DEATH_PLATEAU(342, "Death Plateau"),
DEATH_TO_THE_DORGESHUUN(343, "Death to the Dorgeshuun", Varbits.QUEST_DEATH_TO_THE_DORGESHUUN), DEATH_TO_THE_DORGESHUUN(343, "Death to the Dorgeshuun"),
THE_DEPTHS_OF_DESPAIR(344, "The Depths of Despair", Varbits.QUEST_THE_DEPTHS_OF_DESPAIR), THE_DEPTHS_OF_DESPAIR(344, "The Depths of Despair"),
DESERT_TREASURE(345, "Desert Treasure", Varbits.QUEST_DESERT_TREASURE), DESERT_TREASURE(345, "Desert Treasure"),
DEVIOUS_MINDS(346, "Devious Minds", Varbits.QUEST_DEVIOUS_MINDS), DEVIOUS_MINDS(346, "Devious Minds"),
THE_DIG_SITE(347, "The Dig Site", VarPlayer.QUEST_THE_DIG_SITE), THE_DIG_SITE(347, "The Dig Site"),
DRAGON_SLAYER_II(348, "Dragon Slayer II", Varbits.QUEST_DRAGON_SLAYER_II), DRAGON_SLAYER_II(348, "Dragon Slayer II"),
DREAM_MENTOR(349, "Dream Mentor", Varbits.QUEST_DREAM_MENTOR), DREAM_MENTOR(349, "Dream Mentor"),
DRUIDIC_RITUAL(350, "Druidic Ritual", VarPlayer.QUEST_DRUIDIC_RITUAL), DRUIDIC_RITUAL(350, "Druidic Ritual"),
DWARF_CANNON(351, "Dwarf Cannon", Varbits.QUEST_THE_GIANT_DWARF), DWARF_CANNON(351, "Dwarf Cannon"),
EADGARS_RUSE(352, "Eadgar's Ruse", VarPlayer.QUEST_EADGARS_RUSE), EADGARS_RUSE(352, "Eadgar's Ruse"),
EAGLES_PEAK(353, "Eagles' Peak", Varbits.QUEST_EAGLES_PEAK), EAGLES_PEAK(353, "Eagles' Peak"),
ELEMENTAL_WORKSHOP_I(354, "Elemental Workshop I", VarPlayer.QUEST_ELEMENTAL_WORKSHOP_I), ELEMENTAL_WORKSHOP_I(354, "Elemental Workshop I"),
ELEMENTAL_WORKSHOP_II(355, "Elemental Workshop II", Varbits.QUEST_ELEMENTAL_WORKSHOP_II), ELEMENTAL_WORKSHOP_II(355, "Elemental Workshop II"),
ENAKHRAS_LAMENT(356, "Enakhra's Lament", Varbits.QUEST_ENAKHRAS_LAMENT), ENAKHRAS_LAMENT(356, "Enakhra's Lament"),
ENLIGHTENED_JOURNEY(357, "Enlightened Journey", Varbits.QUEST_ENLIGHTENED_JOURNEY), ENLIGHTENED_JOURNEY(357, "Enlightened Journey"),
THE_EYES_OF_GLOUPHRIE(358, "The Eyes of Glouphrie", Varbits.QUEST_THE_EYES_OF_GLOUPHRIE), THE_EYES_OF_GLOUPHRIE(358, "The Eyes of Glouphrie"),
FAIRYTALE_I__GROWING_PAINS(359, "Fairytale I - Growing Pains", Varbits.QUEST_FAIRYTALE_I_GROWING_PAINS), FAIRYTALE_I__GROWING_PAINS(359, "Fairytale I - Growing Pains"),
FAIRYTALE_II__CURE_A_QUEEN(360, "Fairytale II - Cure a Queen", Varbits.QUEST_FAIRYTALE_II_CURE_A_QUEEN), FAIRYTALE_II__CURE_A_QUEEN(360, "Fairytale II - Cure a Queen"),
FAMILY_CREST(361, "Family Crest", VarPlayer.QUEST_FAMILY_CREST), FAMILY_CREST(361, "Family Crest"),
THE_FEUD(362, "The Feud", Varbits.QUEST_THE_FEUD), THE_FEUD(362, "The Feud"),
FIGHT_ARENA(363, "Fight Arena", VarPlayer.QUEST_FIGHT_ARENA), FIGHT_ARENA(363, "Fight Arena"),
FISHING_CONTEST(364, "Fishing Contest", VarPlayer.QUEST_FISHING_CONTEST), FISHING_CONTEST(364, "Fishing Contest"),
FORGETTABLE_TALE(365, "Forgettable Tale...", Varbits.QUEST_FORGETTABLE_TALE), FORGETTABLE_TALE(365, "Forgettable Tale..."),
BONE_VOYAGE(366, "Bone Voyage", Varbits.QUEST_BONE_VOYAGE), BONE_VOYAGE(366, "Bone Voyage"),
THE_FREMENNIK_ISLES(367, "The Fremennik Isles", Varbits.QUEST_THE_FREMENNIK_ISLES), THE_FREMENNIK_ISLES(367, "The Fremennik Isles"),
THE_FREMENNIK_TRIALS(368, "The Fremennik Trials", VarPlayer.QUEST_THE_FREMENNIK_TRIALS), THE_FREMENNIK_TRIALS(368, "The Fremennik Trials"),
GARDEN_OF_TRANQUILLITY(369, "Garden of Tranquillity", Varbits.QUEST_GARDEN_OF_TRANQUILLITY), GARDEN_OF_TRANQUILLITY(369, "Garden of Tranquillity"),
GERTRUDES_CAT(370, "Gertrude's Cat", VarPlayer.QUEST_GERTRUDES_CAT), GERTRUDES_CAT(370, "Gertrude's Cat"),
GHOSTS_AHOY(371, "Ghosts Ahoy", Varbits.QUEST_GHOSTS_AHOY), GHOSTS_AHOY(371, "Ghosts Ahoy"),
THE_GIANT_DWARF(372, "The Giant Dwarf", Varbits.QUEST_THE_GIANT_DWARF), THE_GIANT_DWARF(372, "The Giant Dwarf"),
THE_GOLEM(373, "The Golem", Varbits.QUEST_THE_GOLEM), THE_GOLEM(373, "The Golem"),
THE_GRAND_TREE(374, "The Grand Tree", VarPlayer.QUEST_THE_GRAND_TREE), THE_GRAND_TREE(374, "The Grand Tree"),
THE_GREAT_BRAIN_ROBBERY(375, "The Great Brain Robbery", VarPlayer.QUEST_THE_GREAT_BRAIN_ROBBERY), THE_GREAT_BRAIN_ROBBERY(375, "The Great Brain Robbery"),
GRIM_TALES(376, "Grim Tales", Varbits.QUEST_GRIM_TALES), GRIM_TALES(376, "Grim Tales"),
THE_HAND_IN_THE_SAND(377, "The Hand in the Sand", Varbits.QUEST_THE_HAND_IN_THE_SAND), THE_HAND_IN_THE_SAND(377, "The Hand in the Sand"),
HAUNTED_MINE(378, "Haunted Mine", VarPlayer.QUEST_HAUNTED_MINE), HAUNTED_MINE(378, "Haunted Mine"),
HAZEEL_CULT(379, "Hazeel Cult", VarPlayer.QUEST_HAZEEL_CULT), HAZEEL_CULT(379, "Hazeel Cult"),
HEROES_QUEST(380, "Heroes' Quest", VarPlayer.QUEST_HEROES_QUEST), HEROES_QUEST(380, "Heroes' Quest"),
HOLY_GRAIL(381, "Holy Grail", VarPlayer.QUEST_HOLY_GRAIL), HOLY_GRAIL(381, "Holy Grail"),
HORROR_FROM_THE_DEEP(382, "Horror from the Deep", Varbits.QUEST_HORROR_FROM_THE_DEEP), HORROR_FROM_THE_DEEP(382, "Horror from the Deep"),
ICTHLARINS_LITTLE_HELPER(383, "Icthlarin's Little Helper", Varbits.QUEST_ICTHLARINS_LITTLE_HELPER), ICTHLARINS_LITTLE_HELPER(383, "Icthlarin's Little Helper"),
IN_AID_OF_THE_MYREQUE(384, "In Aid of the Myreque", Varbits.QUEST_IN_AID_OF_THE_MYREQUE), IN_AID_OF_THE_MYREQUE(384, "In Aid of the Myreque"),
IN_SEARCH_OF_THE_MYREQUE(385, "In Search of the Myreque", VarPlayer.QUEST_IN_SEARCH_OF_THE_MYREQUE), IN_SEARCH_OF_THE_MYREQUE(385, "In Search of the Myreque"),
JUNGLE_POTION(386, "Jungle Potion", VarPlayer.QUEST_JUNGLE_POTION), JUNGLE_POTION(386, "Jungle Potion"),
KINGS_RANSOM(387, "King's Ransom", Varbits.QUEST_KINGS_RANSOM), KINGS_RANSOM(387, "King's Ransom"),
LEGENDS_QUEST(388, "Legends' Quest", VarPlayer.QUEST_LEGENDS_QUEST), LEGENDS_QUEST(388, "Legends' Quest"),
LOST_CITY(389, "Lost City", VarPlayer.QUEST_LOST_CITY), LOST_CITY(389, "Lost City"),
THE_LOST_TRIBE(390, "The Lost Tribe", Varbits.QUEST_THE_LOST_TRIBE), THE_LOST_TRIBE(390, "The Lost Tribe"),
LUNAR_DIPLOMACY(391, "Lunar Diplomacy", Varbits.QUEST_LUNAR_DIPLOMACY), LUNAR_DIPLOMACY(391, "Lunar Diplomacy"),
MAKING_FRIENDS_WITH_MY_ARM(392, "Making Friends with My Arm", Varbits.QUEST_MAKING_FRIENDS_WITH_MY_ARM), MAKING_FRIENDS_WITH_MY_ARM(392, "Making Friends with My Arm"),
MAKING_HISTORY(393, "Making History", Varbits.QUEST_MAKING_HISTORY), MAKING_HISTORY(393, "Making History"),
MERLINS_CRYSTAL(394, "Merlin's Crystal", VarPlayer.QUEST_MERLINS_CRYSTAL), MERLINS_CRYSTAL(394, "Merlin's Crystal"),
MONKEY_MADNESS_I(395, "Monkey Madness I", VarPlayer.QUEST_MONKEY_MADNESS_I), MONKEY_MADNESS_I(395, "Monkey Madness I"),
MONKEY_MADNESS_II(396, "Monkey Madness II", Varbits.QUEST_MONKEY_MADNESS_II), MONKEY_MADNESS_II(396, "Monkey Madness II"),
MONKS_FRIEND(397, "Monk's Friend", VarPlayer.QUEST_MONKS_FRIEND), MONKS_FRIEND(397, "Monk's Friend"),
MOUNTAIN_DAUGHTER(398, "Mountain Daughter", Varbits.QUEST_MOUNTAIN_DAUGHTER), MOUNTAIN_DAUGHTER(398, "Mountain Daughter"),
MOURNINGS_END_PART_I(399, "Mourning's End Part I", VarPlayer.QUEST_MOURNINGS_END_PART_I), MOURNINGS_END_PART_I(399, "Mourning's End Part I"),
MOURNINGS_END_PART_II(400, "Mourning's End Part II", Varbits.QUEST_MOURNINGS_END_PART_II), MOURNINGS_END_PART_II(400, "Mourning's End Part II"),
MURDER_MYSTERY(401, "Murder Mystery", VarPlayer.QUEST_MURDER_MYSTERY), MURDER_MYSTERY(401, "Murder Mystery"),
MY_ARMS_BIG_ADVENTURE(402, "My Arm's Big Adventure", Varbits.QUEST_MY_ARMS_BIG_ADVENTURE), MY_ARMS_BIG_ADVENTURE(402, "My Arm's Big Adventure"),
NATURE_SPIRIT(403, "Nature Spirit", VarPlayer.QUEST_NATURE_SPIRIT), NATURE_SPIRIT(403, "Nature Spirit"),
OBSERVATORY_QUEST(404, "Observatory Quest", VarPlayer.QUEST_OBSERVATORY_QUEST), OBSERVATORY_QUEST(404, "Observatory Quest"),
OLAFS_QUEST(405, "Olaf's Quest", Varbits.QUEST_OLAFS_QUEST), OLAFS_QUEST(405, "Olaf's Quest"),
ONE_SMALL_FAVOUR(406, "One Small Favour", VarPlayer.QUEST_ONE_SMALL_FAVOUR), ONE_SMALL_FAVOUR(406, "One Small Favour"),
PLAGUE_CITY(407, "Plague City", VarPlayer.QUEST_PLAGUE_CITY), PLAGUE_CITY(407, "Plague City"),
PRIEST_IN_PERIL(408, "Priest in Peril", VarPlayer.QUEST_PRIEST_IN_PERIL), PRIEST_IN_PERIL(408, "Priest in Peril"),
THE_QUEEN_OF_THIEVES(409, "The Queen of Thieves", Varbits.QUEST_THE_QUEEN_OF_THIEVES), THE_QUEEN_OF_THIEVES(409, "The Queen of Thieves"),
RAG_AND_BONE_MAN(410, "Rag and Bone Man", VarPlayer.QUEST_RAG_AND_BONE_MAN), RAG_AND_BONE_MAN(410, "Rag and Bone Man"),
RAG_AND_BONE_MAN_II(411, "Rag and Bone Man II", VarPlayer.QUEST_RAG_AND_BONE_MAN_II), RAG_AND_BONE_MAN_II(411, "Rag and Bone Man II"),
RATCATCHERS(412, "Ratcatchers", Varbits.QUEST_RATCATCHERS), RATCATCHERS(412, "Ratcatchers"),
RECIPE_FOR_DISASTER(413, "Recipe for Disaster", Varbits.QUEST_RECIPE_FOR_DISASTER), RECIPE_FOR_DISASTER(413, "Recipe for Disaster"),
RECRUITMENT_DRIVE(414, "Recruitment Drive", Varbits.QUEST_RECRUITMENT_DRIVE), RECRUITMENT_DRIVE(414, "Recruitment Drive"),
REGICIDE(415, "Regicide", VarPlayer.QUEST_REGICIDE), REGICIDE(415, "Regicide"),
ROVING_ELVES(416, "Roving Elves", VarPlayer.QUEST_ROVING_ELVES), ROVING_ELVES(416, "Roving Elves"),
ROYAL_TROUBLE(417, "Royal Trouble", Varbits.QUEST_ROYAL_TROUBLE), ROYAL_TROUBLE(417, "Royal Trouble"),
RUM_DEAL(418, "Rum Deal", VarPlayer.QUEST_RUM_DEAL), RUM_DEAL(418, "Rum Deal"),
SCORPION_CATCHER(419, "Scorpion Catcher", VarPlayer.QUEST_SCORPION_CATCHER), SCORPION_CATCHER(419, "Scorpion Catcher"),
SEA_SLUG(420, "Sea Slug", VarPlayer.QUEST_SEA_SLUG), SEA_SLUG(420, "Sea Slug"),
SHADES_OF_MORTTON(421, "Shades of Mort'ton", VarPlayer.QUEST_SHADES_OF_MORTTON), SHADES_OF_MORTTON(421, "Shades of Mort'ton"),
SHADOW_OF_THE_STORM(422, "Shadow of the Storm", Varbits.QUEST_SHADOW_OF_THE_STORM), SHADOW_OF_THE_STORM(422, "Shadow of the Storm"),
SHEEP_HERDER(423, "Sheep Herder", VarPlayer.QUEST_SHEEP_HERDER), SHEEP_HERDER(423, "Sheep Herder"),
SHILO_VILLAGE(424, "Shilo Village", VarPlayer.QUEST_SHILO_VILLAGE), SHILO_VILLAGE(424, "Shilo Village"),
THE_SLUG_MENACE(425, "The Slug Menace", Varbits.QUEST_THE_SLUG_MENACE), THE_SLUG_MENACE(425, "The Slug Menace"),
A_SOULS_BANE(426, "A Soul's Bane", Varbits.QUEST_A_SOULS_BANE), A_SOULS_BANE(426, "A Soul's Bane"),
SPIRITS_OF_THE_ELID(427, "Spirits of the Elid", Varbits.QUEST_SPIRITS_OF_THE_ELID), SPIRITS_OF_THE_ELID(427, "Spirits of the Elid"),
SWAN_SONG(428, "Swan Song", Varbits.QUEST_SWAN_SONG), SWAN_SONG(428, "Swan Song"),
TAI_BWO_WANNAI_TRIO(429, "Tai Bwo Wannai Trio", VarPlayer.QUEST_TAI_BWO_WANNAI_TRIO), TAI_BWO_WANNAI_TRIO(429, "Tai Bwo Wannai Trio"),
A_TAIL_OF_TWO_CATS(430, "A Tail of Two Cats", Varbits.QUEST_A_TAIL_OF_TWO_CATS), A_TAIL_OF_TWO_CATS(430, "A Tail of Two Cats"),
TALE_OF_THE_RIGHTEOUS(431, "Tale of the Righteous", Varbits.QUEST_TALE_OF_THE_RIGHTEOUS), TALE_OF_THE_RIGHTEOUS(431, "Tale of the Righteous"),
A_TASTE_OF_HOPE(432, "A Taste of Hope", Varbits.QUEST_A_TASTE_OF_HOPE), A_TASTE_OF_HOPE(432, "A Taste of Hope"),
TEARS_OF_GUTHIX(433, "Tears of Guthix", Varbits.QUEST_TEARS_OF_GUTHIX), TEARS_OF_GUTHIX(433, "Tears of Guthix"),
TEMPLE_OF_IKOV(434, "Temple of Ikov", VarPlayer.QUEST_TEMPLE_OF_IKOV), TEMPLE_OF_IKOV(434, "Temple of Ikov"),
THRONE_OF_MISCELLANIA(435, "Throne of Miscellania", VarPlayer.QUEST_THRONE_OF_MISCELLANIA), THRONE_OF_MISCELLANIA(435, "Throne of Miscellania"),
THE_TOURIST_TRAP(436, "The Tourist Trap", VarPlayer.QUEST_THE_TOURIST_TRAP), THE_TOURIST_TRAP(436, "The Tourist Trap"),
TOWER_OF_LIFE(437, "Tower of Life", Varbits.QUEST_TOWER_OF_LIFE), TOWER_OF_LIFE(437, "Tower of Life"),
TREE_GNOME_VILLAGE(438, "Tree Gnome Village", VarPlayer.QUEST_TREE_GNOME_VILLAGE), TREE_GNOME_VILLAGE(438, "Tree Gnome Village"),
TRIBAL_TOTEM(439, "Tribal Totem", VarPlayer.QUEST_TRIBAL_TOTEM), TRIBAL_TOTEM(439, "Tribal Totem"),
TROLL_ROMANCE(440, "Troll Romance", VarPlayer.QUEST_TROLL_ROMANCE), TROLL_ROMANCE(440, "Troll Romance"),
TROLL_STRONGHOLD(441, "Troll Stronghold", VarPlayer.QUEST_TROLL_STRONGHOLD), TROLL_STRONGHOLD(441, "Troll Stronghold"),
UNDERGROUND_PASS(442, "Underground Pass", VarPlayer.QUEST_UNDERGROUND_PASS), UNDERGROUND_PASS(442, "Underground Pass"),
CLIENT_OF_KOUREND(443, "Client of Kourend", Varbits.QUEST_CLIENT_OF_KOUREND), CLIENT_OF_KOUREND(443, "Client of Kourend"),
WANTED(444, "Wanted!", Varbits.QUEST_WANTED), WANTED(444, "Wanted!"),
WATCHTOWER(445, "Watchtower", VarPlayer.QUEST_WATCHTOWER), WATCHTOWER(445, "Watchtower"),
WATERFALL_QUEST(446, "Waterfall Quest", VarPlayer.QUEST_WATERFALL_QUEST), WATERFALL_QUEST(446, "Waterfall Quest"),
WHAT_LIES_BELOW(447, "What Lies Below", Varbits.QUEST_WHAT_LIES_BELOW), WHAT_LIES_BELOW(447, "What Lies Below"),
WITCHS_HOUSE(448, "Witch's House", VarPlayer.QUEST_WITCHS_HOUSE), WITCHS_HOUSE(448, "Witch's House"),
ZOGRE_FLESH_EATERS(449, "Zogre Flesh Eaters", Varbits.QUEST_ZOGRE_FLESH_EATERS), ZOGRE_FLESH_EATERS(449, "Zogre Flesh Eaters"),
THE_ASCENT_OF_ARCEUUS(542, "The Ascent of Arceuus", Varbits.QUEST_THE_ASCENT_OF_ARCEUUS), THE_ASCENT_OF_ARCEUUS(542, "The Ascent of Arceuus"),
THE_FORSAKEN_TOWER(543, "The Forsaken Tower", Varbits.QUEST_THE_FORSAKEN_TOWER), THE_FORSAKEN_TOWER(543, "The Forsaken Tower"),
SONG_OF_THE_ELVES(603, "Song of the Elves", Varbits.QUEST_SONG_OF_THE_ELVES), SONG_OF_THE_ELVES(603, "Song of the Elves"),
THE_FREMENNIK_EXILES(718, "The Fremennik Exiles"),
//Miniquests //Miniquests
ENTER_THE_ABYSS(319, "Enter the Abyss", VarPlayer.QUEST_ENTER_THE_ABYSS), ENTER_THE_ABYSS(319, "Enter the Abyss"),
ARCHITECTURAL_ALLIANCE(320, "Architectural Alliance", Varbits.QUEST_ARCHITECTURAL_ALLIANCE), ARCHITECTURAL_ALLIANCE(320, "Architectural Alliance"),
BEAR_YOUR_SOUL(321, "Bear your Soul", Varbits.QUEST_BEAR_YOUR_SOUL), BEAR_YOUR_SOUL(321, "Bear your Soul"),
ALFRED_GRIMHANDS_BARCRAWL(322, "Alfred Grimhand's Barcrawl", VarPlayer.QUEST_ALFRED_GRIMHANDS_BARCRAWL), ALFRED_GRIMHANDS_BARCRAWL(322, "Alfred Grimhand's Barcrawl"),
CURSE_OF_THE_EMPTY_LORD(323, "Curse of the Empty Lord", Varbits.QUEST_CURSE_OF_THE_EMPTY_LORD), CURSE_OF_THE_EMPTY_LORD(323, "Curse of the Empty Lord"),
ENCHANTED_KEY(324, "Enchanted Key", Varbits.QUEST_ENCHANTED_KEY), ENCHANTED_KEY(324, "Enchanted Key"),
THE_GENERALS_SHADOW(325, "The General's Shadow", Varbits.QUEST_THE_GENERALS_SHADOW), THE_GENERALS_SHADOW(325, "The General's Shadow"),
SKIPPY_AND_THE_MOGRES(326, "Skippy and the Mogres", Varbits.QUEST_SKIPPY_AND_THE_MOGRES), SKIPPY_AND_THE_MOGRES(326, "Skippy and the Mogres"),
THE_MAGE_ARENA(327, "The Mage Arena", VarPlayer.QUEST_THE_MAGE_ARENA), THE_MAGE_ARENA(327, "The Mage Arena"),
LAIR_OF_TARN_RAZORLOR(328, "Lair of Tarn Razorlor", Varbits.QUEST_LAIR_OF_TARN_RAZORLOR), LAIR_OF_TARN_RAZORLOR(328, "Lair of Tarn Razorlor"),
FAMILY_PEST(329, "Family Pest", Varbits.QUEST_FAMILY_PEST), FAMILY_PEST(329, "Family Pest"),
THE_MAGE_ARENA_II(330, "The Mage Arena II", Varbits.QUEST_THE_MAGE_ARENA_II), THE_MAGE_ARENA_II(330, "The Mage Arena II"),
IN_SEARCH_OF_KNOWLEDGE(602, "In Search of Knowledge", Varbits.QUEST_IN_SEARCH_OF_KNOWLEDGE); IN_SEARCH_OF_KNOWLEDGE(602, "In Search of Knowledge");
@Getter @Getter
private final int id; private final int id;
@@ -196,26 +199,6 @@ public enum Quest
@Getter @Getter
private final String name; private final String name;
private final Varbits varbit;
private final VarPlayer varPlayer;
Quest(int id, String name, Varbits varbit)
{
this.id = id;
this.name = name;
this.varbit = varbit;
this.varPlayer = null;
}
Quest(int id, String name, VarPlayer varPlayer)
{
this.id = id;
this.name = name;
this.varbit = null;
this.varPlayer = varPlayer;
}
public QuestState getState(Client client) public QuestState getState(Client client)
{ {
client.runScript(ScriptID.QUESTLIST_PROGRESS, id); client.runScript(ScriptID.QUESTLIST_PROGRESS, id);
@@ -229,16 +212,4 @@ public enum Quest
return QuestState.IN_PROGRESS; return QuestState.IN_PROGRESS;
} }
} }
public int getVar(Client client)
{
if (varbit != null)
{
return client.getVar(varbit);
}
else
{
return client.getVar(varPlayer);
}
}
} }

View File

@@ -61,4 +61,9 @@ public interface ScriptEvent
* @see net.runelite.api.events.MenuOptionClicked * @see net.runelite.api.events.MenuOptionClicked
*/ */
String getOpbase(); String getOpbase();
/**
* Parent relative x coordinate for mouse related events
*/
int getMouseX();
} }

View File

@@ -101,6 +101,16 @@ public final class ScriptID
@ScriptArguments(integer = 2) @ScriptArguments(integer = 2)
public static final int MESSAGE_LAYER_CLOSE = 299; public static final int MESSAGE_LAYER_CLOSE = 299;
/**
* Sets the background for sound option bars
* <ul>
* <li> int Value of the slider (0-4) </li>
* <li> int (WidgetID) * 5, segments of the slider </li>
* </ul>
*/
@ScriptArguments(integer = 6)
public static final int OPTIONS_ALLSOUNDS = 358;
/** /**
* Readies the chatbox panel for things like the chatbox input * Readies the chatbox panel for things like the chatbox input
* Inverse of MESSAGE_LAYER_CLOSE * Inverse of MESSAGE_LAYER_CLOSE

View File

@@ -34,4 +34,11 @@ public class AreaSoundEffectPlayed implements Event
private int sceneY; private int sceneY;
private int range; private int range;
private int delay; private int delay;
private boolean consumed;
public void consume()
{
consumed = true;
}
} }

View File

@@ -31,4 +31,11 @@ public class SoundEffectPlayed implements Event
{ {
private int soundId; private int soundId;
private int delay; private int delay;
private boolean consumed;
public void consume()
{
consumed = true;
}
} }

View File

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

View File

@@ -555,7 +555,7 @@ public interface Widget
void setOnMouseOverListener(Object... args); void setOnMouseOverListener(Object... args);
/** /**
* Sets a script to be ran every frame when the mouse is in the widget bounds * Sets a script to be ran every client tick when the mouse is in the widget bounds
* *
* @param args A ScriptID, then the args for the script * @param args A ScriptID, then the args for the script
*/ */
@@ -569,7 +569,7 @@ public interface Widget
void setOnMouseLeaveListener(Object... args); void setOnMouseLeaveListener(Object... args);
/** /**
* Sets a script to be ran every frame * Sets a script to be ran every client tick
* *
* @param args A ScriptID, then the args for the script * @param args A ScriptID, then the args for the script
*/ */
@@ -857,4 +857,31 @@ public interface Widget
* Gets the image which is (or should be) drawn on this widget * Gets the image which is (or should be) drawn on this widget
*/ */
Sprite getSprite(); Sprite getSprite();
/**
* {@link net.runelite.api.VarPlayer}s that triggers this widgets varTransmitListener
*/
void setVarTransmitTrigger(int ...trigger);
/**
* Sets a script to be ran the first client tick the mouse is held ontop of this widget
*
* @param args A ScriptID, then the args for the script
*/
void setOnClickListener(Object ...args);
/**
* Sets a script to be ran the every client tick the mouse is held ontop of this widget,
* except the first client tick.
*
* @param args A ScriptID, then the args for the script
*/
void setOnHoldListener(Object ...args);
/**
* Sets a script to be ran the first client tick the mouse is not held ontop of this widget
*
* @param args A ScriptID, then the args for the script
*/
void setOnReleaseListener(Object ...args);
} }

View File

@@ -46,6 +46,8 @@ public class WidgetID
public static final int GRAND_EXCHANGE_GROUP_ID = 465; public static final int GRAND_EXCHANGE_GROUP_ID = 465;
public static final int DEPOSIT_BOX_GROUP_ID = 192; public static final int DEPOSIT_BOX_GROUP_ID = 192;
public static final int INVENTORY_GROUP_ID = 149; public static final int INVENTORY_GROUP_ID = 149;
public static final int PLAYER_TRADE_SCREEN_GROUP_ID = 335;
public static final int PLAYER_TRADE_INVENTORY_GROUP_ID = 336;
public static final int FRIENDS_LIST_GROUP_ID = 429; public static final int FRIENDS_LIST_GROUP_ID = 429;
public static final int IGNORE_LIST_GROUP_ID = 432; public static final int IGNORE_LIST_GROUP_ID = 432;
public static final int RAIDING_PARTY_GROUP_ID = 500; public static final int RAIDING_PARTY_GROUP_ID = 500;
@@ -53,7 +55,7 @@ public class WidgetID
public static final int EQUIPMENT_INVENTORY_GROUP_ID = 85; public static final int EQUIPMENT_INVENTORY_GROUP_ID = 85;
public static final int EMOTES_GROUP_ID = 216; public static final int EMOTES_GROUP_ID = 216;
public static final int RUNE_POUCH_GROUP_ID = 190; public static final int RUNE_POUCH_GROUP_ID = 190;
public static final int DIARY_GROUP_ID = 259; public static final int ACHIEVEMENT_DIARY_GROUP_ID = 259;
public static final int PEST_CONTROL_BOAT_GROUP_ID = 407; public static final int PEST_CONTROL_BOAT_GROUP_ID = 407;
public static final int PEST_CONTROL_GROUP_ID = 408; public static final int PEST_CONTROL_GROUP_ID = 408;
public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243; public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243;
@@ -127,6 +129,7 @@ public class WidgetID
public static final int PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID = 364; public static final int PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID = 364;
public static final int PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID = 50; public static final int PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID = 50;
public static final int FISHING_TRAWLER_GROUP_ID = 366; public static final int FISHING_TRAWLER_GROUP_ID = 366;
public static final int FISHING_TRAWLER_REWARD_GROUP_ID = 367;
public static final int ZEAH_MESS_HALL_GROUP_ID = 235; public static final int ZEAH_MESS_HALL_GROUP_ID = 235;
public static final int KOUREND_FAVOUR_GROUP_ID = 246; public static final int KOUREND_FAVOUR_GROUP_ID = 246;
public static final int LOOTING_BAG_GROUP_ID = 81; public static final int LOOTING_BAG_GROUP_ID = 81;
@@ -157,6 +160,7 @@ public class WidgetID
public static final int LMS_GROUP_ID = 333; public static final int LMS_GROUP_ID = 333;
public static final int LMS_INGAME_GROUP_ID = 328; public static final int LMS_INGAME_GROUP_ID = 328;
public static final int JEWELLERY_BOX_GROUP_ID = 590; public static final int JEWELLERY_BOX_GROUP_ID = 590;
public static final int OPTIONS_GROUP_ID = 261;
static class WorldMap static class WorldMap
{ {
@@ -990,7 +994,7 @@ public class WidgetID
static final int KILLDEATH_RATIO = 33; static final int KILLDEATH_RATIO = 33;
static final int SKULL_CONTAINER = 53; static final int SKULL_CONTAINER = 53;
static final int SAFE_ZONE = 55; static final int SAFE_ZONE = 55;
static final int WILDERNESS_LEVEL = 57; // this can also be the Deadman Mode "Protection" text static final int WILDERNESS_LEVEL = 58; // this can also be the Deadman Mode "Protection" text
} }
static class KourendFavour static class KourendFavour
@@ -1165,4 +1169,21 @@ public class WidgetID
static final int RING_OFGP = 6; static final int RING_OFGP = 6;
static final int AMUL_GLOR = 7; // yes static final int AMUL_GLOR = 7; // yes
} }
static class Options
{
static final int MUSIC_SLIDER = 44;
static final int SOUND_EFFECT_SLIDER = 50;
static final int AREA_SOUND_SLIDER = 56;
}
static class AchievementDiary
{
static final int CONTAINER = 2;
}
static class Skills
{
static final int CONTAINER = 0;
}
} }

View File

@@ -774,7 +774,15 @@ public enum WidgetInfo
JEWELLERY_BOX_COMB_BRAC(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.COMB_BRAC), JEWELLERY_BOX_COMB_BRAC(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.COMB_BRAC),
JEWELLERY_BOX_SKIL_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.SKIL_NECK), JEWELLERY_BOX_SKIL_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.SKIL_NECK),
JEWELLERY_BOX_RING_OFGP(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.RING_OFGP), JEWELLERY_BOX_RING_OFGP(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.RING_OFGP),
JEWELLERY_BOX_AMUL_GLOR(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.AMUL_GLOR); JEWELLERY_BOX_AMUL_GLOR(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.AMUL_GLOR),
OPTIONS_MUSIC_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.MUSIC_SLIDER),
OPTIONS_SOUND_EFFECT_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.SOUND_EFFECT_SLIDER),
OPTIONS_AREA_SOUND_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.AREA_SOUND_SLIDER),
ACHIEVEMENT_DIARY_CONTAINER(WidgetID.ACHIEVEMENT_DIARY_GROUP_ID, WidgetID.AchievementDiary.CONTAINER),
SKILLS_CONTAINER(WidgetID.SKILLS_GROUP_ID, WidgetID.Skills.CONTAINER);
private final int groupId; private final int groupId;
private final int childId; private final int childId;

View File

@@ -164,7 +164,7 @@ public interface ChatColorConfig extends Config
position = 45, position = 45,
keyName = "opaqueServerMessage", keyName = "opaqueServerMessage",
name = "Server message", name = "Server message",
description = "Color of Server Messages (eg. 'Welcome to Runescape')" description = "Color of Server Messages (eg. 'Welcome to RuneScape')"
) )
Color opaqueServerMessage(); Color opaqueServerMessage();
@@ -404,7 +404,7 @@ public interface ChatColorConfig extends Config
position = 75, position = 75,
keyName = "transparentServerMessage", keyName = "transparentServerMessage",
name = "Server message (transparent)", name = "Server message (transparent)",
description = "Color of Server Messages (eg. 'Welcome to Runescape') (transparent)" description = "Color of Server Messages (eg. 'Welcome to RuneScape') (transparent)"
) )
Color transparentServerMessage(); Color transparentServerMessage();

View File

@@ -106,6 +106,8 @@ public enum ItemMapping
ITEM_FURY_ORNAMENT_KIT(FURY_ORNAMENT_KIT, AMULET_OF_FURY_OR), ITEM_FURY_ORNAMENT_KIT(FURY_ORNAMENT_KIT, AMULET_OF_FURY_OR),
ITEM_TORMENTED_BRACELET(TORMENTED_BRACELET, TORMENTED_BRACELET_OR), ITEM_TORMENTED_BRACELET(TORMENTED_BRACELET, TORMENTED_BRACELET_OR),
ITEM_TORMENTED_ORNAMENT_KIT(TORMENTED_ORNAMENT_KIT, TORMENTED_BRACELET_OR), ITEM_TORMENTED_ORNAMENT_KIT(TORMENTED_ORNAMENT_KIT, TORMENTED_BRACELET_OR),
ITEM_BERSERKER_NECKLACE(BERSERKER_NECKLACE, BERSERKER_NECKLACE_OR),
ITEM_BERSERKER_NECKLACE_ORNAMENT_KIT(BERSERKER_NECKLACE_ORNAMENT_KIT, BERSERKER_NECKLACE_OR),
// Ensouled heads // Ensouled heads
ITEM_ENSOULED_GOBLIN_HEAD(ENSOULED_GOBLIN_HEAD_13448, ENSOULED_GOBLIN_HEAD), ITEM_ENSOULED_GOBLIN_HEAD(ENSOULED_GOBLIN_HEAD_13448, ENSOULED_GOBLIN_HEAD),

View File

@@ -120,9 +120,6 @@ public class KaramjaDiaryRequirement extends GenericDiaryRequirement
new CombatLevelRequirement(100), new CombatLevelRequirement(100),
new SkillRequirement(Skill.SLAYER, 50), new SkillRequirement(Skill.SLAYER, 50),
new QuestRequirement(Quest.SHILO_VILLAGE)); new QuestRequirement(Quest.SHILO_VILLAGE));
add("Kill a metal dragon in Brimhaven Dungeon.",
new SkillRequirement(Skill.AGILITY, 12),
new SkillRequirement(Skill.WOODCUTTING, 34));
// ELITE // ELITE
add("Craft 56 Nature runes at once.", add("Craft 56 Nature runes at once.",

View File

@@ -599,9 +599,11 @@ public class TabInterface
chatboxPanelManager.close(); chatboxPanelManager.close();
} }
if (event.getIdentifier() == WidgetInfo.BANK_ITEM_CONTAINER.getId() if ((event.getIdentifier() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|| event.getIdentifier() == WidgetInfo.BANK_INVENTORY_ITEMS_CONTAINER.getId())
&& event.getMenuOpcode() == MenuOpcode.EXAMINE_ITEM_BANK_EQ && event.getMenuOpcode() == MenuOpcode.EXAMINE_ITEM_BANK_EQ
&& event.getOption().equalsIgnoreCase("withdraw-x")) && (event.getOption().equalsIgnoreCase("withdraw-x")
|| event.getOption().equalsIgnoreCase("deposit-x")))
{ {
waitSearchTick = true; waitSearchTick = true;
rememberedSearch = client.getVar(VarClientStr.INPUT_TEXT); rememberedSearch = client.getVar(VarClientStr.INPUT_TEXT);

View File

@@ -168,6 +168,7 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati
.put(new WorldPoint(3051, 3736, 0), "East of the Wilderness Obelisk in 28 Wilderness.") .put(new WorldPoint(3051, 3736, 0), "East of the Wilderness Obelisk in 28 Wilderness.")
.put(new WorldPoint(2316, 3814, 0), "West of Neitiznot, near the bridge.") .put(new WorldPoint(2316, 3814, 0), "West of Neitiznot, near the bridge.")
.put(new WorldPoint(2872, 3937, 0), "Weiss.") .put(new WorldPoint(2872, 3937, 0), "Weiss.")
.put(new WorldPoint(2835, 2998, 0), "Northeast corner of the Island of Stone.")
// Master // Master
.put(new WorldPoint(2178, 3209, 0), "South of Elf Camp.") .put(new WorldPoint(2178, 3209, 0), "South of Elf Camp.")
.put(new WorldPoint(2155, 3100, 0), "South of Port Tyras (BJS).") .put(new WorldPoint(2155, 3100, 0), "South of Port Tyras (BJS).")

View File

@@ -144,7 +144,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll
new SkillChallengeClue("Craft multiple cosmic runes from a single essence.", item(ItemID.PURE_ESSENCE)), new SkillChallengeClue("Craft multiple cosmic runes from a single essence.", item(ItemID.PURE_ESSENCE)),
new SkillChallengeClue("Plant a watermelon seed.", item(ItemID.RAKE), item(ItemID.SEED_DIBBER), xOfItem(ItemID.WATERMELON_SEED, 3)), new SkillChallengeClue("Plant a watermelon seed.", item(ItemID.RAKE), item(ItemID.SEED_DIBBER), xOfItem(ItemID.WATERMELON_SEED, 3)),
new SkillChallengeClue("Activate the Chivalry prayer."), new SkillChallengeClue("Activate the Chivalry prayer."),
new SkillChallengeClue("Hand in a Tier 2 or higher set of Shayzien supply armour", "hand in a boxed set of shayzien supply armour at tier 2 or above.", any("Shayzien Supply Set (Tier 2 or higher)", item(ItemID.SHAYZIEN_SUPPLY_SET_2), item(ItemID.SHAYZIEN_SUPPLY_SET_3), item(ItemID.SHAYZIEN_SUPPLY_SET_4), item(ItemID.SHAYZIEN_SUPPLY_SET_5))), new SkillChallengeClue("Hand in a Tier 2 or higher set of Shayzien supply armour", "take the lovakengj armourers a boxed set of shayzien supply armour at tier 2 or above.", any("Shayzien Supply Set (Tier 2 or higher)", item(ItemID.SHAYZIEN_SUPPLY_SET_2), item(ItemID.SHAYZIEN_SUPPLY_SET_3), item(ItemID.SHAYZIEN_SUPPLY_SET_4), item(ItemID.SHAYZIEN_SUPPLY_SET_5))),
// Master Sherlock Tasks // Master Sherlock Tasks
new SkillChallengeClue("Equip an abyssal whip in front of the abyssal demons of the Slayer Tower.", true, any("Abyssal Whip", item(ItemID.ABYSSAL_WHIP), item(ItemID.FROZEN_ABYSSAL_WHIP), item(ItemID.VOLCANIC_ABYSSAL_WHIP))), new SkillChallengeClue("Equip an abyssal whip in front of the abyssal demons of the Slayer Tower.", true, any("Abyssal Whip", item(ItemID.ABYSSAL_WHIP), item(ItemID.FROZEN_ABYSSAL_WHIP), item(ItemID.VOLCANIC_ABYSSAL_WHIP))),
new SkillChallengeClue("Smith a runite med helm.", item(ItemID.HAMMER), item(ItemID.RUNITE_BAR)), new SkillChallengeClue("Smith a runite med helm.", item(ItemID.HAMMER), item(ItemID.RUNITE_BAR)),

View File

@@ -38,7 +38,7 @@ import net.runelite.api.coords.WorldPoint;
* <p> * <p>
* These puzzles are established by having some way to test the distance from the solution via "warmth", where being * These puzzles are established by having some way to test the distance from the solution via "warmth", where being
* colder means one is farther away from the target, and being warmer means one is closer to it, with the goal being to * colder means one is farther away from the target, and being warmer means one is closer to it, with the goal being to
* reach the most warm value to discover the solution point. Hot-cold puzzles in Old School Runescape are implemented * reach the most warm value to discover the solution point. Hot-cold puzzles in Old School RuneScape are implemented
* with specific set of solution points, so this solver will filter from a provided set of possible solutions as new * with specific set of solution points, so this solver will filter from a provided set of possible solutions as new
* signals of temperatures and temperature changes are provided. * signals of temperatures and temperature changes are provided.
*/ */

View File

@@ -48,13 +48,18 @@ public class MultipleOfItemRequirement implements ItemRequirement
@Override @Override
public boolean fulfilledBy(Item[] items) public boolean fulfilledBy(Item[] items)
{ {
int quantityFound = 0;
for (Item item : items) for (Item item : items)
{ {
if (item.getId() == itemId && item.getQuantity() >= quantity) if (item.getId() == itemId)
{
quantityFound += item.getQuantity();
if (quantityFound >= quantity)
{ {
return true; return true;
} }
} }
}
return false; return false;
} }

View File

@@ -312,7 +312,9 @@ public class ExaminePlugin extends Plugin
|| WidgetInfo.CLUE_SCROLL_REWARD_ITEM_CONTAINER.getGroupId() == widgetGroup || WidgetInfo.CLUE_SCROLL_REWARD_ITEM_CONTAINER.getGroupId() == widgetGroup
|| WidgetInfo.LOOTING_BAG_CONTAINER.getGroupId() == widgetGroup || WidgetInfo.LOOTING_BAG_CONTAINER.getGroupId() == widgetGroup
|| WidgetID.SEED_VAULT_INVENTORY_GROUP_ID == widgetGroup || WidgetID.SEED_VAULT_INVENTORY_GROUP_ID == widgetGroup
|| WidgetID.SEED_BOX_GROUP_ID == widgetGroup) || WidgetID.SEED_BOX_GROUP_ID == widgetGroup
|| WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID == widgetGroup
|| WidgetID.PLAYER_TRADE_INVENTORY_GROUP_ID == widgetGroup)
{ {
Widget[] children = widget.getDynamicChildren(); Widget[] children = widget.getDynamicChildren();
if (actionParam < children.length) if (actionParam < children.length)

View File

@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.plugins.fishing; package net.runelite.client.plugins.fishing;
import java.awt.Color;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
@@ -76,7 +77,40 @@ public interface FishingConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 4, keyName = "overlayColor",
name = "Overlay Color",
description = "Color of overlays",
position = 4
)
default Color getOverlayColor()
{
return Color.CYAN;
}
@ConfigItem(
keyName = "minnowsOverlayColor",
name = "Minnows Overlay Color",
description = "Color of overlays for Minnows",
position = 5
)
default Color getMinnowsOverlayColor()
{
return Color.RED;
}
@ConfigItem(
keyName = "aerialOverlayColor",
name = "Aerial Overlay Color",
description = "Color of overlays when 1-tick aerial fishing",
position = 6
)
default Color getAerialOverlayColor()
{
return Color.GREEN;
}
@ConfigItem(
position = 7,
keyName = "statTimeout", keyName = "statTimeout",
name = "Reset stats (minutes)", name = "Reset stats (minutes)",
description = "The time until fishing session data is reset in minutes." description = "The time until fishing session data is reset in minutes."
@@ -87,7 +121,7 @@ public interface FishingConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 5, position = 8,
keyName = "showFishingStats", keyName = "showFishingStats",
name = "Show Fishing session stats", name = "Show Fishing session stats",
description = "Display the fishing session stats." description = "Display the fishing session stats."
@@ -98,7 +132,7 @@ public interface FishingConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 6, position = 9,
keyName = "showMinnowOverlay", keyName = "showMinnowOverlay",
name = "Show Minnow Movement overlay", name = "Show Minnow Movement overlay",
description = "Display the minnow progress pie overlay." description = "Display the minnow progress pie overlay."
@@ -109,7 +143,7 @@ public interface FishingConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 7, position = 10,
keyName = "trawlerNotification", keyName = "trawlerNotification",
name = "Trawler activity notification", name = "Trawler activity notification",
description = "Send a notification when fishing trawler activity drops below 15%." description = "Send a notification when fishing trawler activity drops below 15%."
@@ -120,7 +154,7 @@ public interface FishingConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 8, position = 11,
keyName = "trawlerTimer", keyName = "trawlerTimer",
name = "Trawler timer in MM:SS", name = "Trawler timer in MM:SS",
description = "Trawler Timer will display a more accurate timer in MM:SS format." description = "Trawler Timer will display a more accurate timer in MM:SS format."

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.fishing;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
@@ -157,6 +158,12 @@ public class FishingPlugin extends Plugin
private boolean showMinnowOverlay; private boolean showMinnowOverlay;
private boolean trawlerNotification; private boolean trawlerNotification;
private boolean trawlerTimer; private boolean trawlerTimer;
@Getter(AccessLevel.PACKAGE)
private Color overlayColor;
@Getter(AccessLevel.PACKAGE)
private Color minnowsOverlayColor;
@Getter(AccessLevel.PACKAGE)
private Color aerialOverlayColor;
@Override @Override
protected void startUp() throws Exception protected void startUp() throws Exception
@@ -404,6 +411,7 @@ public class FishingPlugin extends Plugin
if (regionID != TRAWLER_SHIP_REGION_NORMAL && regionID != TRAWLER_SHIP_REGION_SINKING) if (regionID != TRAWLER_SHIP_REGION_NORMAL && regionID != TRAWLER_SHIP_REGION_SINKING)
{ {
log.debug("Trawler session ended"); log.debug("Trawler session ended");
trawlerStartTime = null;
return; return;
} }
@@ -477,5 +485,8 @@ public class FishingPlugin extends Plugin
this.showMinnowOverlay = config.showMinnowOverlay(); this.showMinnowOverlay = config.showMinnowOverlay();
this.trawlerNotification = config.trawlerNotification(); this.trawlerNotification = config.trawlerNotification();
this.trawlerTimer = config.trawlerTimer(); this.trawlerTimer = config.trawlerTimer();
this.overlayColor = config.getOverlayColor();
this.minnowsOverlayColor = config.getMinnowsOverlayColor();
this.aerialOverlayColor = config.getAerialOverlayColor();
} }
} }

View File

@@ -76,7 +76,9 @@ class FishingSpotMinimapOverlay extends Overlay
continue; continue;
} }
Color color = npc.getSpotAnimation() == GraphicID.FLYING_FISH ? Color.RED : Color.CYAN; Color color = npc.getSpotAnimation() == GraphicID.FLYING_FISH
? plugin.getMinnowsOverlayColor()
: plugin.getOverlayColor();
net.runelite.api.Point minimapLocation = npc.getMinimapLocation(); net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
if (minimapLocation != null) if (minimapLocation != null)

View File

@@ -107,15 +107,15 @@ class FishingSpotOverlay extends Overlay
Color color; Color color;
if (npc.getSpotAnimation() == GraphicID.FLYING_FISH) if (npc.getSpotAnimation() == GraphicID.FLYING_FISH)
{ {
color = Color.RED; color = plugin.getMinnowsOverlayColor();
} }
else if (spot == FishingSpot.COMMON_TENCH && npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING) else if (spot == FishingSpot.COMMON_TENCH && npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
{ {
color = Color.GREEN; color = plugin.getAerialOverlayColor();
} }
else else
{ {
color = Color.CYAN; color = plugin.getOverlayColor();
} }
if (spot == FishingSpot.MINNOW && plugin.isShowMinnowOverlay()) if (spot == FishingSpot.MINNOW && plugin.isShowMinnowOverlay())
@@ -161,7 +161,7 @@ class FishingSpotOverlay extends Overlay
if (spot == FishingSpot.COMMON_TENCH if (spot == FishingSpot.COMMON_TENCH
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING) && npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
{ {
fishImage = ImageUtil.outlineImage(itemManager.getImage(spot.getFishSpriteId()), Color.GREEN); fishImage = ImageUtil.outlineImage(itemManager.getImage(spot.getFishSpriteId()), color);
} }
if (fishImage != null) if (fishImage != null)

View File

@@ -27,7 +27,9 @@ package net.runelite.client.plugins.gpu;
import com.jogamp.opengl.GL4; import com.jogamp.opengl.GL4;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner; import java.util.Scanner;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class GLUtil class GLUtil
{ {
private static final int ERR_LEN = 1024; private static final int ERR_LEN = 1024;
@@ -197,6 +199,7 @@ class GLUtil
else else
{ {
String err = glGetShaderInfoLog(gl, shader); String err = glGetShaderInfoLog(gl, shader);
log.info(String.valueOf(program));
throw new ShaderException(err); throw new ShaderException(err);
} }
} }

View File

@@ -99,7 +99,7 @@ import net.runelite.http.api.hiscore.Skill;
@Singleton @Singleton
public class HiscorePanel extends PluginPanel public class HiscorePanel extends PluginPanel
{ {
/* The maximum allowed username length in runescape accounts */ /* The maximum allowed username length in RuneScape accounts */
private static final int MAX_USERNAME_LENGTH = 12; private static final int MAX_USERNAME_LENGTH = 12;
/** /**
@@ -344,7 +344,7 @@ public class HiscorePanel extends PluginPanel
return; return;
} }
/* Runescape usernames can't be longer than 12 characters long */ /* RuneScape usernames can't be longer than 12 characters long */
if (lookup.length() > MAX_USERNAME_LENGTH) if (lookup.length() > MAX_USERNAME_LENGTH)
{ {
searchBar.setIcon(IconTextField.Icon.ERROR); searchBar.setIcon(IconTextField.Icon.ERROR);

View File

@@ -34,23 +34,17 @@ import java.awt.GridLayout;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.io.File; import java.io.File;
import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.swing.Box;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.event.HyperlinkEvent;
import net.runelite.api.Client; import net.runelite.api.Client;
import static net.runelite.client.RuneLite.LOGS_DIR; import static net.runelite.client.RuneLite.LOGS_DIR;
import net.runelite.client.RuneLiteProperties; import net.runelite.client.RuneLiteProperties;
import net.runelite.client.account.SessionManager;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.SessionClose;
import net.runelite.client.events.SessionOpen;
import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.PluginPanel;
@@ -58,10 +52,8 @@ import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.LinkBrowser;
@Singleton @Singleton
public class InfoPanel extends PluginPanel class InfoPanel extends PluginPanel
{ {
private static final String RUNELITE_LOGIN = "https://runelite_login/";
private static final ImageIcon ARROW_RIGHT_ICON; private static final ImageIcon ARROW_RIGHT_ICON;
private static final ImageIcon GITHUB_ICON; private static final ImageIcon GITHUB_ICON;
private static final ImageIcon FOLDER_ICON; private static final ImageIcon FOLDER_ICON;
@@ -69,21 +61,12 @@ public class InfoPanel extends PluginPanel
private static final ImageIcon PATREON_ICON; private static final ImageIcon PATREON_ICON;
private static final ImageIcon IMPORT_ICON; private static final ImageIcon IMPORT_ICON;
private final JLabel loggedLabel = new JLabel();
private final JRichTextPane emailLabel = new JRichTextPane();
private JPanel syncPanel; private JPanel syncPanel;
private JPanel actionsContainer;
@Inject @Inject
@Nullable @Nullable
private Client client; private Client client;
@Inject
private SessionManager sessionManager;
@Inject
private ScheduledExecutorService executor;
@Inject @Inject
private ConfigManager configManager; private ConfigManager configManager;
@@ -127,28 +110,11 @@ public class InfoPanel extends PluginPanel
revision.setText(htmlLabel("Oldschool revision: ", engineVer)); revision.setText(htmlLabel("Oldschool revision: ", engineVer));
loggedLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
loggedLabel.setFont(smallFont);
emailLabel.setForeground(Color.WHITE);
emailLabel.setFont(smallFont);
emailLabel.enableAutoLinkHandler(false);
emailLabel.addHyperlinkListener(e ->
{
if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType()) && e.getURL() != null && e.getURL().toString().equals(RUNELITE_LOGIN))
{
executor.execute(sessionManager::login);
}
});
versionPanel.add(version); versionPanel.add(version);
versionPanel.add(plusVersion); versionPanel.add(plusVersion);
versionPanel.add(revision); versionPanel.add(revision);
versionPanel.add(Box.createGlue());
versionPanel.add(loggedLabel);
versionPanel.add(emailLabel);
actionsContainer = new JPanel(); JPanel actionsContainer = new JPanel();
actionsContainer.setBorder(new EmptyBorder(10, 0, 0, 0)); actionsContainer.setBorder(new EmptyBorder(10, 0, 0, 0));
actionsContainer.setLayout(new GridLayout(5, 1, 0, 10)); actionsContainer.setLayout(new GridLayout(5, 1, 0, 10));
@@ -173,8 +139,6 @@ public class InfoPanel extends PluginPanel
add(versionPanel, BorderLayout.NORTH); add(versionPanel, BorderLayout.NORTH);
add(actionsContainer, BorderLayout.CENTER); add(actionsContainer, BorderLayout.CENTER);
updateLoggedIn();
} }
/** /**
@@ -267,40 +231,8 @@ public class InfoPanel extends PluginPanel
return container; return container;
} }
private void updateLoggedIn()
{
final String name = sessionManager.getAccountSession() != null
? sessionManager.getAccountSession().getUsername()
: null;
if (name != null)
{
emailLabel.setContentType("text/plain");
emailLabel.setText(name);
loggedLabel.setText("Logged in as");
actionsContainer.add(syncPanel, 0);
}
else
{
//emailLabel.setContentType("text/html");
//emailLabel.setText("<a href=\"" + RUNELITE_LOGIN + "\">Login</a> to sync settings to the cloud.");
//loggedLabel.setText("Not logged in");
actionsContainer.remove(syncPanel);
}
}
private static String htmlLabel(String key, String value) private static String htmlLabel(String key, String value)
{ {
return "<html><body style = 'color:#a5a5a5'>" + key + "<span style = 'color:white'>" + value + "</span></body></html>"; return "<html><body style = 'color:#a5a5a5'>" + key + "<span style = 'color:white'>" + value + "</span></body></html>";
} }
public void onSessionOpen(SessionOpen sessionOpen)
{
updateLoggedIn();
}
public void onSessionClose(SessionClose e)
{
updateLoggedIn();
}
} }

View File

@@ -28,8 +28,6 @@ import java.awt.image.BufferedImage;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import net.runelite.client.eventbus.EventBus; 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.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.ClientToolbar;
@@ -53,12 +51,10 @@ public class InfoPlugin extends Plugin
private NavigationButton navButton; private NavigationButton navButton;
private InfoPanel panel;
@Override @Override
protected void startUp() throws Exception protected void startUp() throws Exception
{ {
panel = injector.getInstance(InfoPanel.class); InfoPanel panel = injector.getInstance(InfoPanel.class);
panel.init(); panel.init();
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "info_icon.png"); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "info_icon.png");
@@ -71,8 +67,6 @@ public class InfoPlugin extends Plugin
.build(); .build();
clientToolbar.addNavigation(navButton); clientToolbar.addNavigation(navButton);
addSubscriptions();
} }
@Override @Override
@@ -82,10 +76,4 @@ public class InfoPlugin extends Plugin
clientToolbar.removeNavigation(navButton); clientToolbar.removeNavigation(navButton);
} }
private void addSubscriptions()
{
eventbus.subscribe(SessionOpen.class, this, event -> panel.onSessionOpen(event));
eventbus.subscribe(SessionClose.class, this, event -> panel.onSessionClose(event));
}
} }

View File

@@ -30,17 +30,40 @@ public enum LootRecordSortType implements Comparator<LootTrackerRecord>
if (o1.getSubTitle().equals(LootRecordType.DEATH.name())) if (o1.getSubTitle().equals(LootRecordType.DEATH.name()))
{ {
return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem -> return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum(); IntStream.of((int) lootTrackerItem.getGePrice() * lootTrackerItem.getQuantity())).sum();
} }
if (o2.getSubTitle().equals(LootRecordType.DEATH.name())) if (o2.getSubTitle().equals(LootRecordType.DEATH.name()))
{ {
return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem -> return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum(); IntStream.of((int) lootTrackerItem.getGePrice() * lootTrackerItem.getQuantity())).sum();
} }
int sum = Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem -> int sum = Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum(); IntStream.of((int) lootTrackerItem.getGePrice() * lootTrackerItem.getQuantity())).sum();
return sum + Arrays.stream(o2.getItems()).flatMapToInt(lootTrackerItem -> return sum + Arrays.stream(o2.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum(); IntStream.of((int) lootTrackerItem.getGePrice() * lootTrackerItem.getQuantity())).sum();
}
},
TOTAL_HA_VALUE
{
@Override
public int compare(LootTrackerRecord o1, LootTrackerRecord o2)
{
// We want deaths at the bottom of the list
if (o1.getSubTitle().equals(LootRecordType.DEATH.name()))
{
return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getHaPrice() * lootTrackerItem.getQuantity())).sum();
}
if (o2.getSubTitle().equals(LootRecordType.DEATH.name()))
{
return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getHaPrice() * lootTrackerItem.getQuantity())).sum();
}
int sum = Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getHaPrice() * lootTrackerItem.getQuantity())).sum();
return sum + Arrays.stream(o2.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getHaPrice() * lootTrackerItem.getQuantity())).sum();
} }
}, },
ITEM_COUNT ITEM_COUNT

View File

@@ -72,6 +72,8 @@ class LootTrackerBox extends JPanel
private final ItemManager itemManager; private final ItemManager itemManager;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private final String id; private final String id;
private final LootTrackerPriceType priceType;
private final boolean showPriceType;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private final List<LootTrackerRecord> records = new ArrayList<>(); private final List<LootTrackerRecord> records = new ArrayList<>();
@@ -87,6 +89,8 @@ class LootTrackerBox extends JPanel
final String id, final String id,
@Nullable final String subtitle, @Nullable final String subtitle,
final boolean hideIgnoredItems, final boolean hideIgnoredItems,
final LootTrackerPriceType priceType,
final boolean showPriceType,
@Nullable final Boolean showDate, @Nullable final Boolean showDate,
final BiConsumer<String, Boolean> onItemToggle) final BiConsumer<String, Boolean> onItemToggle)
{ {
@@ -95,6 +99,8 @@ class LootTrackerBox extends JPanel
this.itemManager = itemManager; this.itemManager = itemManager;
this.onItemToggle = onItemToggle; this.onItemToggle = onItemToggle;
this.hideIgnoredItems = hideIgnoredItems; this.hideIgnoredItems = hideIgnoredItems;
this.priceType = priceType;
this.showPriceType = showPriceType;
setLayout(new BorderLayout(0, 1)); setLayout(new BorderLayout(0, 1));
setBorder(new EmptyBorder(5, 0, 0, 0)); setBorder(new EmptyBorder(5, 0, 0, 0));
@@ -200,7 +206,13 @@ class LootTrackerBox extends JPanel
{ {
buildItems(); buildItems();
priceLabel.setText(QuantityFormatter.quantityToStackSize(totalPrice) + " gp"); String priceTypeString = " ";
if (showPriceType)
{
priceTypeString = priceType == LootTrackerPriceType.HIGH_ALCHEMY ? "HA: " : "GE: ";
}
priceLabel.setText(priceTypeString + QuantityFormatter.quantityToStackSize(totalPrice) + " gp");
priceLabel.setToolTipText(QuantityFormatter.formatNumber(totalPrice) + " gp"); priceLabel.setToolTipText(QuantityFormatter.formatNumber(totalPrice) + " gp");
final long kills = getTotalKills(); final long kills = getTotalKills();
@@ -280,7 +292,7 @@ class LootTrackerBox extends JPanel
continue; continue;
} }
totalPrice += entry.getPrice(); totalPrice += priceType == LootTrackerPriceType.HIGH_ALCHEMY ? entry.getHaPrice() : entry.getGePrice();
int quantity = 0; int quantity = 0;
for (final LootTrackerItem i : items) for (final LootTrackerItem i : items)
@@ -296,9 +308,10 @@ class LootTrackerBox extends JPanel
if (quantity != 0) if (quantity != 0)
{ {
int newQuantity = entry.getQuantity() + quantity; int newQuantity = entry.getQuantity() + quantity;
long pricePerItem = entry.getPrice() == 0 ? 0 : (entry.getPrice() / entry.getQuantity()); long gePricePerItem = entry.getGePrice() == 0 ? 0 : (entry.getGePrice() / entry.getQuantity());
long haPricePerItem = entry.getHaPrice() == 0 ? 0 : (entry.getHaPrice() / entry.getQuantity());
items.add(new LootTrackerItem(entry.getId(), entry.getName(), newQuantity, pricePerItem * newQuantity, entry.isIgnored())); items.add(new LootTrackerItem(entry.getId(), entry.getName(), newQuantity, gePricePerItem * newQuantity, haPricePerItem * newQuantity, entry.isIgnored()));
} }
else else
{ {
@@ -306,7 +319,14 @@ class LootTrackerBox extends JPanel
} }
} }
items.sort((i1, i2) -> Long.compare(i2.getPrice(), i1.getPrice())); if (priceType == LootTrackerPriceType.HIGH_ALCHEMY)
{
items.sort((i1, i2) -> Long.compare(i2.getHaPrice(), i1.getHaPrice()));
}
else
{
items.sort((i1, i2) -> Long.compare(i2.getGePrice(), i1.getGePrice()));
}
// Calculates how many rows need to be display to fit all items // Calculates how many rows need to be display to fit all items
final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW; final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW;
@@ -371,8 +391,11 @@ class LootTrackerBox extends JPanel
{ {
final String name = item.getName(); final String name = item.getName();
final int quantity = item.getQuantity(); final int quantity = item.getQuantity();
final long price = item.getPrice(); final long gePrice = item.getGePrice();
final long haPrice = item.getHaPrice();
final String ignoredLabel = item.isIgnored() ? " - Ignored" : ""; final String ignoredLabel = item.isIgnored() ? " - Ignored" : "";
return name + " x " + quantity + " (" + QuantityFormatter.quantityToStackSize(price) + ") " + ignoredLabel; return "<html>" + name + " x " + quantity + ignoredLabel
+ "<br>GE: " + QuantityFormatter.quantityToStackSize(gePrice)
+ "<br>HA: " + QuantityFormatter.quantityToStackSize(haPrice) + "</html>";
} }
} }

View File

@@ -220,4 +220,23 @@ public interface LootTrackerConfig extends Config
return true; return true;
} }
@ConfigItem(
keyName = "priceType",
name = "Price Type",
description = "What type of price to use for calculating value."
)
default LootTrackerPriceType priceType()
{
return LootTrackerPriceType.GRAND_EXCHANGE;
}
@ConfigItem(
keyName = "showPriceType",
name = "Show Price Type",
description = "Whether to show a GE: or HA: next to the total values in the tracker"
)
default boolean showPriceType()
{
return false;
}
} }

View File

@@ -39,7 +39,9 @@ class LootTrackerItem
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private final int quantity; private final int quantity;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private final long price; private final long gePrice;
@Getter
private final long haPrice;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private boolean ignored; private boolean ignored;

View File

@@ -46,6 +46,7 @@ import javax.swing.ImageIcon;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
@@ -90,6 +91,10 @@ class LootTrackerPanel extends PluginPanel
private static final String HTML_LABEL_TEMPLATE = private static final String HTML_LABEL_TEMPLATE =
"<html><body style='color:%s'>%s<span style='color:white'>%s</span></body></html>"; "<html><body style='color:%s'>%s<span style='color:white'>%s</span></body></html>";
private static final String SYNC_RESET_ALL_WARNING_TEXT =
"This will permanently delete the current loot from both the client and the RuneLite website.";
private static final String NO_SYNC_RESET_ALL_WARNING_TEXT =
"This will permanently delete the current loot from the client.";
// When there is no loot, display this // When there is no loot, display this
private final PluginErrorPanel errorPanel = new PluginErrorPanel(); private final PluginErrorPanel errorPanel = new PluginErrorPanel();
@@ -385,6 +390,18 @@ class LootTrackerPanel extends PluginPanel
final JMenuItem reset = new JMenuItem("Reset All"); final JMenuItem reset = new JMenuItem("Reset All");
reset.addActionListener(e -> reset.addActionListener(e ->
{ {
final LootTrackerClient client = plugin.getLootTrackerClient();
final boolean syncLoot = client != null && config.syncPanel();
final int result = JOptionPane.showOptionDialog(overallPanel,
syncLoot ? SYNC_RESET_ALL_WARNING_TEXT : NO_SYNC_RESET_ALL_WARNING_TEXT,
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
null, new String[]{"Yes", "No"}, "No");
if (result != JOptionPane.YES_OPTION)
{
return;
}
// If not in detailed view, remove all, otherwise only remove for the currently detailed title // If not in detailed view, remove all, otherwise only remove for the currently detailed title
records.removeIf(r -> r.matches(currentView)); records.removeIf(r -> r.matches(currentView));
boxes.removeIf(b -> b.matches(currentView)); boxes.removeIf(b -> b.matches(currentView));
@@ -393,8 +410,7 @@ class LootTrackerPanel extends PluginPanel
logsContainer.repaint(); logsContainer.repaint();
// Delete all loot, or loot matching the current view // Delete all loot, or loot matching the current view
LootTrackerClient client = plugin.getLootTrackerClient(); if (syncLoot)
if (client != null && config.syncPanel())
{ {
client.delete(currentView); client.delete(currentView);
} }
@@ -668,7 +684,7 @@ class LootTrackerPanel extends PluginPanel
// Create box // Create box
final LootTrackerBox box = new LootTrackerBox(record.getTimestamp().toEpochMilli(), itemManager, record.getTitle(), record.getSubTitle(), final LootTrackerBox box = new LootTrackerBox(record.getTimestamp().toEpochMilli(), itemManager, record.getTitle(), record.getSubTitle(),
hideIgnoredItems, config.displayDate(), plugin::toggleItem); hideIgnoredItems, config.priceType(), config.showPriceType(), config.displayDate(), plugin::toggleItem);
box.combine(record); box.combine(record);
// Create popup menu // Create popup menu
@@ -764,7 +780,8 @@ class LootTrackerPanel extends PluginPanel
private void updateOverall() private void updateOverall()
{ {
long overallKills = 0; long overallKills = 0;
long overallGp = 0; long overallGe = 0;
long overallHa = 0;
for (LootTrackerRecord record : records) for (LootTrackerRecord record : records)
{ {
@@ -808,7 +825,8 @@ class LootTrackerPanel extends PluginPanel
continue; continue;
} }
overallGp += item.getPrice(); overallGe += item.getGePrice();
overallHa += item.getHaPrice();
} }
if (present > 0) if (present > 0)
@@ -817,8 +835,16 @@ class LootTrackerPanel extends PluginPanel
} }
} }
String priceType = "";
if (config.showPriceType())
{
priceType = config.priceType() == LootTrackerPriceType.HIGH_ALCHEMY ? "HA " : "GE ";
}
overallKillsLabel.setText(htmlLabel("Total count: ", overallKills)); overallKillsLabel.setText(htmlLabel("Total count: ", overallKills));
overallGpLabel.setText(htmlLabel("Total value: ", overallGp)); overallGpLabel.setText(htmlLabel("Total " + priceType + "value: ", config.priceType() == LootTrackerPriceType.HIGH_ALCHEMY ? overallHa : overallGe));
overallGpLabel.setToolTipText("<html>Total GE price: " + QuantityFormatter.formatNumber(overallGe)
+ "<br>Total HA price: " + QuantityFormatter.formatNumber(overallHa) + "</html>");
updateCollapseText(); updateCollapseText();
} }

View File

@@ -66,6 +66,7 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.InventoryID; import net.runelite.api.InventoryID;
import net.runelite.api.Item; import net.runelite.api.Item;
@@ -703,6 +704,10 @@ public class LootTrackerPlugin extends Plugin
eventType = "Kingdom of Miscellania"; eventType = "Kingdom of Miscellania";
container = client.getItemContainer(InventoryID.KINGDOM_OF_MISCELLANIA); container = client.getItemContainer(InventoryID.KINGDOM_OF_MISCELLANIA);
break; break;
case (WidgetID.FISHING_TRAWLER_REWARD_GROUP_ID):
eventType = "Fishing Trawler";
container = client.getItemContainer(InventoryID.FISHING_TRAWLER_REWARD);
break;
default: default:
return; return;
} }
@@ -1209,15 +1214,18 @@ public class LootTrackerPlugin extends Plugin
{ {
final ItemDefinition itemDefinition = itemManager.getItemDefinition(itemId); final ItemDefinition itemDefinition = itemManager.getItemDefinition(itemId);
final int realItemId = itemDefinition.getNote() != -1 ? itemDefinition.getLinkedNoteId() : itemId; final int realItemId = itemDefinition.getNote() != -1 ? itemDefinition.getLinkedNoteId() : itemId;
final long price; final long gePrice ;
final long haPrice ;
// If it's a death we want to get a coin value for untradeables lost // If it's a death we want to get a coin value for untradeables lost
if (!itemDefinition.isTradeable() && quantity < 0) if (!itemDefinition.isTradeable() && quantity < 0)
{ {
price = (long) itemDefinition.getPrice() * (long) quantity; gePrice = (long) itemDefinition.getPrice() * (long) quantity;
haPrice = (long) Math.round(itemDefinition.getPrice() * Constants.HIGH_ALCHEMY_MULTIPLIER) * (long) quantity;
} }
else else
{ {
price = (long) itemManager.getItemPrice(realItemId) * (long) quantity; gePrice = (long) itemManager.getItemPrice(realItemId) * (long) quantity;
haPrice = (long) Math.round(itemManager.getItemPrice(realItemId) * Constants.HIGH_ALCHEMY_MULTIPLIER) * (long) quantity;
} }
final boolean ignored = ignoredItems.contains(itemDefinition.getName()); final boolean ignored = ignoredItems.contains(itemDefinition.getName());
@@ -1225,7 +1233,8 @@ public class LootTrackerPlugin extends Plugin
itemId, itemId,
itemDefinition.getName(), itemDefinition.getName(),
quantity, quantity,
price, gePrice,
haPrice,
ignored); ignored);
} }

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
* 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.loottracker;
public enum LootTrackerPriceType
{
GRAND_EXCHANGE,
HIGH_ALCHEMY
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.music;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("music")
public interface MusicConfig extends Config
{
@ConfigItem(
keyName = "musicVolume",
name = "",
description = "",
hidden = true
)
default int getMusicVolume()
{
return 0;
}
@ConfigItem(
keyName = "musicVolume",
name = "",
description = "",
hidden = true
)
void setMusicVolume(int vol);
@ConfigItem(
keyName = "soundEffectVolume",
name = "",
description = "",
hidden = true
)
default int getSoundEffectVolume()
{
return 0;
}
@ConfigItem(
keyName = "soundEffectVolume",
name = "",
description = "",
hidden = true
)
void setSoundEffectVolume(int val);
@ConfigItem(
keyName = "areaSoundEffectVolume",
name = "",
description = "",
hidden = true
)
default int getAreaSoundEffectVolume()
{
return 0;
}
@ConfigItem(
keyName = "areaSoundEffectVolume",
name = "",
description = "",
hidden = true
)
void setAreaSoundEffectVolume(int vol);
}

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2019, Anthony Chen <https://github.com/achencoms> * Copyright (c) 2019, Anthony Chen <https://github.com/achencoms>
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -22,33 +23,42 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.musiclist; package net.runelite.client.plugins.music;
import com.google.inject.Provides;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.function.BiConsumer;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.ScriptID; import net.runelite.api.ScriptID;
import net.runelite.api.SoundEffectID; import net.runelite.api.SoundEffectID;
import net.runelite.api.SpriteID; import net.runelite.api.SpriteID;
import net.runelite.api.VarClientInt; import net.runelite.api.VarClientInt;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.VarClientIntChanged; import net.runelite.api.events.VarClientIntChanged;
import net.runelite.api.events.VolumeChanged;
import net.runelite.api.events.WidgetLoaded; import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.vars.InterfaceTab;
import net.runelite.api.widgets.JavaScriptCallback; import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetConfig;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetPositionMode; import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetType; import net.runelite.api.widgets.WidgetType;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.game.chatbox.ChatboxTextInput; import net.runelite.client.game.chatbox.ChatboxTextInput;
@@ -56,11 +66,10 @@ import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
@PluginDescriptor( @PluginDescriptor(
name = "Music List", name = "Music",
description = "Adds search and filter for the music list" description = "Adds search and filter for the music list, and additional volume control"
) )
@Singleton public class MusicPlugin extends Plugin
public class MusicListPlugin extends Plugin
{ {
@Inject @Inject
private Client client; private Client client;
@@ -68,6 +77,9 @@ public class MusicListPlugin extends Plugin
@Inject @Inject
private ClientThread clientThread; private ClientThread clientThread;
@Inject
private MusicConfig musicConfig;
@Inject @Inject
private ChatboxPanelManager chatboxPanelManager; private ChatboxPanelManager chatboxPanelManager;
@@ -88,14 +100,17 @@ public class MusicListPlugin extends Plugin
{ {
addSubscriptions(); addSubscriptions();
clientThread.invoke(this::addMusicButtons); clientThread.invoke(() ->
{
addMusicButtons();
applyMusicVolumeConfig();
updateMusicOptions();
});
} }
@Override @Override
protected void shutDown() protected void shutDown()
{ {
eventBus.unregister(this);
Widget header = client.getWidget(WidgetInfo.MUSIC_WINDOW); Widget header = client.getWidget(WidgetInfo.MUSIC_WINDOW);
if (header != null) if (header != null)
{ {
@@ -103,13 +118,24 @@ public class MusicListPlugin extends Plugin
} }
tracks = null; tracks = null;
clientThread.invoke(this::teardownMusicOptions);
}
@Provides
MusicConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(MusicConfig.class);
} }
private void addSubscriptions() private void addSubscriptions()
{ {
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded); eventBus.subscribe(WidgetLoaded.class, this, this::onWidgetLoaded);
eventBus.subscribe(VarClientIntChanged.class, this, this::onVarClientIntChanged); eventBus.subscribe(VarClientIntChanged.class, this, this::onVarClientIntChanged);
eventBus.subscribe(VolumeChanged.class, this, this::onVolumeChanged);
eventBus.subscribe(ScriptCallbackEvent.class, this, this::onScriptCallbackEvent);
} }
private void onGameStateChanged(GameStateChanged gameStateChanged) private void onGameStateChanged(GameStateChanged gameStateChanged)
@@ -132,6 +158,10 @@ public class MusicListPlugin extends Plugin
currentMusicFilter = MusicState.ALL; currentMusicFilter = MusicState.ALL;
addMusicButtons(); addMusicButtons();
} }
if (widgetLoaded.getGroupId() == WidgetID.OPTIONS_GROUP_ID)
{
updateMusicOptions();
}
} }
private void addMusicButtons() private void addMusicButtons()
@@ -181,9 +211,46 @@ public class MusicListPlugin extends Plugin
} }
} }
private void onVolumeChanged(VolumeChanged volumeChanged)
{
applyMusicVolumeConfig();
}
private void onConfigChanged(ConfigChanged configChanged)
{
if (configChanged.getGroup().equals("music"))
{
clientThread.invokeLater(this::applyMusicVolumeConfig);
}
}
private void applyMusicVolumeConfig()
{
int musicVolume = musicConfig.getMusicVolume();
if (musicVolume > 0)
{
client.setMusicVolume(musicVolume - 1);
}
int soundEffectVolume = musicConfig.getSoundEffectVolume();
if (soundEffectVolume > 0)
{
client.setSoundEffectVolume(soundEffectVolume - 1);
}
int areaSoundEffectVolume = musicConfig.getAreaSoundEffectVolume();
if (areaSoundEffectVolume > 0)
{
client.setAreaSoundEffectVolume(areaSoundEffectVolume - 1);
}
updateMusicOptions();
}
private boolean isOnMusicTab() private boolean isOnMusicTab()
{ {
return client.getVar(VarClientInt.INTERFACE_TAB) == InterfaceTab.MUSIC.getId(); return client.getVar(VarClientInt.INTERFACE_TAB) == 13;
} }
private boolean isChatboxOpen() private boolean isChatboxOpen()
@@ -304,4 +371,191 @@ public class MusicListPlugin extends Plugin
private final String name; private final String name;
private final int spriteID; private final int spriteID;
} }
@RequiredArgsConstructor
@Getter
private enum MusicSlider
{
MUSIC(WidgetInfo.OPTIONS_MUSIC_SLIDER, VarPlayer.MUSIC_VOLUME, MusicConfig::getMusicVolume, MusicConfig::setMusicVolume, 255),
AREA(WidgetInfo.OPTIONS_AREA_SOUND_SLIDER, VarPlayer.AREA_EFFECT_VOLUME, MusicConfig::getAreaSoundEffectVolume, MusicConfig::setAreaSoundEffectVolume, 127),
EFFECT(WidgetInfo.OPTIONS_SOUND_EFFECT_SLIDER, VarPlayer.SOUND_EFFECT_VOLUME, MusicConfig::getSoundEffectVolume, MusicConfig::setSoundEffectVolume, 127);
private final WidgetInfo widgetID;
private final VarPlayer var;
private final ToIntFunction<MusicConfig> getter;
private final BiConsumer<MusicConfig, Integer> setter;
private final int max;
@Setter
private Widget handle;
@Setter
private Widget track;
private static int PADDING = 8;
private int getX()
{
return getTrack().getRelativeX() + PADDING;
}
private int getWidth()
{
return getTrack().getWidth() - (PADDING * 2) - handle.getWidth();
}
}
private void teardownMusicOptions()
{
for (MusicSlider slider : MusicSlider.values())
{
Widget icon = client.getWidget(slider.getWidgetID());
if (icon == null)
{
return;
}
if (slider.getHandle() != null)
{
{
Widget handle = slider.getHandle();
Widget parent = handle.getParent();
if (parent == null)
{
continue;
}
else
{
Widget[] siblings = parent.getChildren();
if (siblings == null || handle.getIndex() >= siblings.length || siblings[handle.getIndex()] != handle)
{
continue;
}
siblings[slider.getTrack().getIndex()] = null;
siblings[handle.getIndex()] = null;
}
}
Object[] init = icon.getOnLoadListener();
init[1] = slider.getWidgetID().getId();
// Readd the var transmit triggers and rerun options_allsounds
client.runScript(init);
slider.setHandle(null);
slider.setTrack(null);
}
}
}
private void updateMusicOptions()
{
for (MusicSlider slider : MusicSlider.values())
{
Widget icon = client.getWidget(slider.getWidgetID());
if (icon == null)
{
return;
}
Widget handle = slider.getHandle();
if (handle != null)
{
Widget parent = handle.getParent();
if (parent == null)
{
handle = null;
}
else
{
Widget[] siblings = parent.getChildren();
if (siblings == null || handle.getIndex() >= siblings.length || siblings[handle.getIndex()] != handle)
{
handle = null;
}
}
}
if (handle == null)
{
Object[] init = icon.getOnLoadListener();
icon.setVarTransmitTrigger((int[]) null);
Widget track = icon.getParent().createChild(-1, WidgetType.TEXT);
slider.setTrack(track);
handle = icon.getParent().createChild(-1, WidgetType.GRAPHIC);
slider.setHandle(handle);
{
// First widget of the track
int wid = (Integer) init[2];
Widget w = client.getWidget(WidgetInfo.TO_GROUP(wid), WidgetInfo.TO_CHILD(wid));
track.setOriginalX(w.getRelativeX());
track.setOriginalY(w.getRelativeY());
}
{
// Last widget of the track
int wid = (Integer) init[6];
Widget w = client.getWidget(WidgetInfo.TO_GROUP(wid), WidgetInfo.TO_CHILD(wid));
track.setOriginalWidth((w.getRelativeX() + w.getWidth()) - track.getOriginalX());
}
track.setOriginalHeight(16);
track.setNoClickThrough(true);
track.revalidate();
handle.setSpriteId(SpriteID.OPTIONS_ZOOM_SLIDER_THUMB);
handle.setOriginalWidth(16);
handle.setOriginalHeight(16);
handle.setClickMask(WidgetConfig.DRAG);
JavaScriptCallback move = ev ->
{
int newVal = ((ev.getMouseX() - MusicSlider.PADDING - (slider.getHandle().getWidth() / 2)) * slider.getMax())
/ slider.getWidth();
if (newVal < 0)
{
newVal = 0;
}
if (newVal > slider.getMax())
{
newVal = slider.getMax();
}
// We store +1 so we can tell the difference between 0 and muted
slider.getSetter().accept(musicConfig, newVal + 1);
applyMusicVolumeConfig();
};
track.setOnClickListener(move);
track.setOnHoldListener(move);
track.setOnReleaseListener(move);
track.setHasListener(true);
client.runScript(ScriptID.OPTIONS_ALLSOUNDS, -1, init[2], init[3], init[4], init[5], init[6]);
}
int value = slider.getGetter().applyAsInt(musicConfig) - 1;
if (value <= -1)
{
// Use the vanilla value
value = ((4 - client.getVar(slider.getVar())) * slider.getMax()) / 4;
}
int newX = ((value * slider.getWidth()) / slider.getMax()) + slider.getX();
slider.getHandle().setOriginalX(newX);
slider.getHandle().setOriginalY(slider.getTrack().getOriginalY());
slider.getHandle().revalidate();
}
}
private void onScriptCallbackEvent(ScriptCallbackEvent ev)
{
switch (ev.getEventName())
{
case "optionsAllSounds":
// We have to override this script because it gets invoked periodically from the server
client.getIntStack()[client.getIntStackSize() - 1] = -1;
}
}
} }

View File

@@ -203,7 +203,7 @@ public interface RaidsConfig extends Config
) )
default boolean displayLayoutMessage() default boolean displayLayoutMessage()
{ {
return true; return false;
} }
@ConfigTitleSection( @ConfigTitleSection(

View File

@@ -41,6 +41,7 @@ import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.runelite.api.Client; import net.runelite.api.Client;
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY;
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG; import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG;
import net.runelite.api.SpriteID; import net.runelite.api.SpriteID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
@@ -72,6 +73,7 @@ public class RaidsOverlay extends Overlay
private static final int SMALL_ICON_SIZE = 21; private static final int SMALL_ICON_SIZE = 21;
private static final int TITLE_COMPONENT_HEIGHT = 20; private static final int TITLE_COMPONENT_HEIGHT = 20;
private static final int LINE_COMPONENT_HEIGHT = 16; private static final int LINE_COMPONENT_HEIGHT = 16;
static final String BROADCAST_ACTION = "Broadcast layout";
private final PanelComponent panelComponent = new PanelComponent(); private final PanelComponent panelComponent = new PanelComponent();
private final ItemManager itemManager; private final ItemManager itemManager;
private final SpriteManager spriteManager; private final SpriteManager spriteManager;
@@ -101,6 +103,7 @@ public class RaidsOverlay extends Overlay
this.itemManager = itemManager; this.itemManager = itemManager;
this.spriteManager = spriteManager; this.spriteManager = spriteManager;
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay")); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay"));
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY, BROADCAST_ACTION, "Raids overlay"));
} }
@Override @Override

View File

@@ -550,8 +550,9 @@ public class RaidsPlugin extends Plugin
private void onOverlayMenuClicked(OverlayMenuClicked event) private void onOverlayMenuClicked(OverlayMenuClicked event)
{ {
OverlayMenuEntry entry = event.getEntry(); OverlayMenuEntry entry = event.getEntry();
if (entry.getMenuOpcode() == MenuOpcode.RUNELITE_OVERLAY && if (entry.getMenuOpcode() == MenuOpcode.RUNELITE_OVERLAY)
entry.getTarget().equals("Raids party overlay")) {
if (entry.getTarget().equals("Raids party overlay"))
{ {
switch (entry.getOption()) switch (entry.getOption())
{ {
@@ -567,6 +568,11 @@ public class RaidsPlugin extends Plugin
break; break;
} }
} }
else if (entry.getOption().equals(RaidsOverlay.BROADCAST_ACTION) && event.getOverlay() == overlay)
{
sendRaidLayoutMessage();
}
}
} }
private void updatePartyMembers(boolean force) private void updatePartyMembers(boolean force)
@@ -670,7 +676,10 @@ public class RaidsPlugin extends Plugin
raid.updateLayout(layout); raid.updateLayout(layout);
RotationSolver.solve(raid.getCombatRooms()); RotationSolver.solve(raid.getCombatRooms());
setOverlayStatus(true); setOverlayStatus(true);
if (this.displayLayoutMessage)
{
sendRaidLayoutMessage(); sendRaidLayoutMessage();
}
Matcher puzzleMatch = PUZZLES.matcher(raid.getFullRotationString()); Matcher puzzleMatch = PUZZLES.matcher(raid.getFullRotationString());
final List<String> puzzles = new ArrayList<>(); final List<String> puzzles = new ArrayList<>();
while (puzzleMatch.find()) while (puzzleMatch.find())
@@ -709,11 +718,6 @@ public class RaidsPlugin extends Plugin
private void sendRaidLayoutMessage() private void sendRaidLayoutMessage()
{ {
if (!this.displayLayoutMessage)
{
return;
}
final String layout = getRaid().getLayout().toCodeString(); final String layout = getRaid().getLayout().toCodeString();
final String rooms = getRaid().toRoomString(); final String rooms = getRaid().toRoomString();
final String raidData = "[" + layout + "]: " + rooms; final String raidData = "[" + layout + "]: " + rooms;

View File

@@ -28,10 +28,9 @@ package net.runelite.client.plugins.randomevents;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor; import net.runelite.api.Actor;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MenuOpcode; import net.runelite.api.MenuOpcode;
@@ -39,10 +38,9 @@ import net.runelite.api.NPC;
import net.runelite.api.NpcID; import net.runelite.api.NpcID;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.InteractingChanged; import net.runelite.api.events.InteractingChanged;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.NpcDespawned;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
@@ -54,6 +52,7 @@ import net.runelite.client.plugins.PluginDescriptor;
description = "Notify when random events appear and remove talk/dismiss options on events that aren't yours.", description = "Notify when random events appear and remove talk/dismiss options on events that aren't yours.",
enabledByDefault = false enabledByDefault = false
) )
@Slf4j
public class RandomEventPlugin extends Plugin public class RandomEventPlugin extends Plugin
{ {
private static final Set<Integer> EVENT_NPCS = ImmutableSet.of( private static final Set<Integer> EVENT_NPCS = ImmutableSet.of(
@@ -86,10 +85,8 @@ public class RandomEventPlugin extends Plugin
); );
private static final int RANDOM_EVENT_TIMEOUT = 150; private static final int RANDOM_EVENT_TIMEOUT = 150;
private Map<NPC, Integer> spawnedNpcs = new HashMap<>();
private NPC currentRandomEvent; private NPC currentRandomEvent;
// event npcs teleport to you to stay in range, we need to throttle spawns private int lastNotificationTick = -RANDOM_EVENT_TIMEOUT; // to avoid double notifications
private int lastEventTick = -RANDOM_EVENT_TIMEOUT;
@Inject @Inject
private Client client; private Client client;
@@ -132,73 +129,54 @@ public class RandomEventPlugin extends Plugin
{ {
eventBus.unregister(this); eventBus.unregister(this);
lastEventTick = 0; lastNotificationTick = 0;
currentRandomEvent = null; currentRandomEvent = null;
spawnedNpcs.clear();
} }
private void addSubscriptions() private void addSubscriptions()
{ {
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged); eventBus.subscribe(InteractingChanged.class, this, this::onInteractingChanged);
eventBus.subscribe(GameTick.class, this, this::onGameTick);
eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded);
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
} }
private void onNpcSpawned(NpcSpawned event)
{
NPC npc = event.getNpc();
if (!EVENT_NPCS.contains(npc.getId()))
{
return;
}
// only occasionally do event npcs spawn with non-null interacting
if (npc.getInteracting() == client.getLocalPlayer())
{
if (client.getTickCount() - lastEventTick > RANDOM_EVENT_TIMEOUT)
{
currentRandomEvent = npc;
lastEventTick = client.getTickCount();
}
}
else
{
spawnedNpcs.put(npc, client.getTickCount());
}
}
private void onInteractingChanged(InteractingChanged event) private void onInteractingChanged(InteractingChanged event)
{ {
Actor source = event.getSource(); Actor source = event.getSource();
Actor target = event.getTarget(); Actor target = event.getTarget();
if (spawnedNpcs.containsKey(source))
{
Player player = client.getLocalPlayer(); Player player = client.getLocalPlayer();
if (player == target && client.getTickCount() - lastEventTick > RANDOM_EVENT_TIMEOUT)
// Check that the npc is interacting with the player and the player isn't interacting with the npc, so
// that the notification doesn't fire from talking to other user's randoms
if (player == null
|| target != player
|| player.getInteracting() == source
|| !(source instanceof NPC)
|| !EVENT_NPCS.contains(((NPC) source).getId()))
{ {
return;
}
log.debug("Random event spawn: {}", source.getName());
currentRandomEvent = (NPC) source; currentRandomEvent = (NPC) source;
if (client.getTickCount() - lastNotificationTick > RANDOM_EVENT_TIMEOUT)
{
lastNotificationTick = client.getTickCount();
if (shouldNotify(currentRandomEvent.getId())) if (shouldNotify(currentRandomEvent.getId()))
{ {
notifier.notify("Random event spawned: " + currentRandomEvent.getName()); notifier.notify("Random event spawned: " + currentRandomEvent.getName());
} }
} }
} }
}
private void onGameTick(GameTick event) private void onNpcDespawned(NpcDespawned npcDespawned)
{ {
if (!spawnedNpcs.isEmpty()) NPC npc = npcDespawned.getNpc();
{
// allow 2 ticks for interacting to get set
spawnedNpcs.entrySet().removeIf(entry -> client.getTickCount() - entry.getValue() >= 2);
}
if (client.getTickCount() - lastEventTick > RANDOM_EVENT_TIMEOUT) if (npc == currentRandomEvent)
{ {
currentRandomEvent = null; currentRandomEvent = null;
} }

View File

@@ -1,4 +1,4 @@
/* /**
* Copyright (c) 2018, Kruithne <kruithne@gmail.com> * Copyright (c) 2018, Kruithne <kruithne@gmail.com>
* Copyright (c) 2018, Psikoi <https://github.com/psikoi> * Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved. * All rights reserved.
@@ -132,6 +132,9 @@ class SkillCalculator extends JPanel
// Clear the search bar // Clear the search bar
searchBar.setText(null); searchBar.setText(null);
// Clear the combined action slots
clearCombinedSlots();
// Add in checkboxes for available skill bonuses. // Add in checkboxes for available skill bonuses.
renderBonusOptions(); renderBonusOptions();

View File

@@ -117,7 +117,7 @@ public class TimersPlugin extends Plugin
private static final String KILLED_TELEBLOCK_OPPONENT_TEXT = "<col=4f006f>Your Tele Block has been removed because you killed "; private static final String KILLED_TELEBLOCK_OPPONENT_TEXT = "<col=4f006f>Your Tele Block has been removed because you killed ";
private static final String PRAYER_ENHANCE_EXPIRED = "<col=ff0000>Your prayer enhance effect has worn off.</col>"; private static final String PRAYER_ENHANCE_EXPIRED = "<col=ff0000>Your prayer enhance effect has worn off.</col>";
private static final Pattern DEADMAN_HALF_TELEBLOCK_PATTERN = Pattern.compile("<col=4f006f>A Tele Block spell has been cast on you by (.+)\\. It will expire in 1 minute, 15 seconds\\.</col>"); private static final Pattern DEADMAN_HALF_TELEBLOCK_PATTERN = Pattern.compile("<col=4f006f>A Tele Block spell has been cast on you by (.+)\\. It will expire in 1 minute, 15 seconds\\.</col>");
private static final Pattern FULL_TELEBLOCK_PATTERN = Pattern.compile("<col=4f006f>A Tele Block spell has been cast on you by (.+)\\. It will expire in 5 minutes, 0 seconds\\.</col>"); private static final Pattern FULL_TELEBLOCK_PATTERN = Pattern.compile("<col=4f006f>A Tele Block spell has been cast on you by (.+)\\. It will expire in 5 minutes\\.</col>");
private static final Pattern HALF_TELEBLOCK_PATTERN = Pattern.compile("<col=4f006f>A Tele Block spell has been cast on you by (.+)\\. It will expire in 2 minutes, 30 seconds\\.</col>"); private static final Pattern HALF_TELEBLOCK_PATTERN = Pattern.compile("<col=4f006f>A Tele Block spell has been cast on you by (.+)\\. It will expire in 2 minutes, 30 seconds\\.</col>");
private static final Pattern DIVINE_POTION_PATTERN = Pattern.compile("You drink some of your divine (.+) potion\\."); private static final Pattern DIVINE_POTION_PATTERN = Pattern.compile("You drink some of your divine (.+) potion\\.");

View File

@@ -361,7 +361,7 @@ public class WikiPlugin extends Plugin
} }
if ((WidgetInfo.TO_GROUP(widgetID) == WidgetID.SKILLS_GROUP_ID && event.getOption().startsWith("View")) if ((WidgetInfo.TO_GROUP(widgetID) == WidgetID.SKILLS_GROUP_ID && event.getOption().startsWith("View"))
|| (WidgetInfo.TO_GROUP(widgetID) == WidgetID.DIARY_GROUP_ID && event.getOption().startsWith("Open"))) || (WidgetInfo.TO_GROUP(widgetID) == WidgetID.ACHIEVEMENT_DIARY_GROUP_ID && event.getOption().startsWith("Open")))
{ {
client.insertMenuItem( client.insertMenuItem(
MENUOP_WIKI, MENUOP_WIKI,

View File

@@ -35,13 +35,13 @@ enum FarmingPatchLocation
new WorldPoint(3793, 2836, 0), new WorldPoint(3793, 2836, 0),
new WorldPoint(1269, 3730, 0) new WorldPoint(1269, 3730, 0)
), ),
ALLOTMENT_FLOWER("Allotment/Flower", new WorldPoint(3289, 6100, 0)),
ALLOTMENT_HERB_FLOWER("Allotment/Herb/Flower", ALLOTMENT_HERB_FLOWER("Allotment/Herb/Flower",
new WorldPoint(1809, 3490, 0), new WorldPoint(1809, 3490, 0),
new WorldPoint(3598, 3524, 0), new WorldPoint(3598, 3524, 0),
new WorldPoint(3052, 3309, 0), new WorldPoint(3052, 3309, 0),
new WorldPoint(2810, 3462, 0), new WorldPoint(2810, 3462, 0),
new WorldPoint(2663, 3375, 0), new WorldPoint(2663, 3375, 0)
new WorldPoint(3289, 6100, 0)
), ),
ANIMA_HERB("Anima/Herb", new WorldPoint(1235, 3724, 0)), ANIMA_HERB("Anima/Herb", new WorldPoint(1235, 3724, 0)),
BELLADONNA("Belladonna", new WorldPoint(3084, 3356, 0)), BELLADONNA("Belladonna", new WorldPoint(3084, 3356, 0)),

View File

@@ -58,7 +58,7 @@ enum QuestStartLocation
//Members' Quests //Members' Quests
ANIMAL_MAGNETISM(Quest.ANIMAL_MAGNETISM, new WorldPoint(3094, 3360, 0)), ANIMAL_MAGNETISM(Quest.ANIMAL_MAGNETISM, new WorldPoint(3094, 3360, 0)),
ANOTHER_SLICE_OF_HAM(Quest.ANOTHER_SLICE_OF_HAM, new WorldPoint(2799, 5428, 0)), ANOTHER_SLICE_OF_HAM(Quest.ANOTHER_SLICE_OF_HAM, new WorldPoint(2799, 5428, 0)),
THE_ASCENT_OF_ARCEUUS(Quest.THE_ASCENT_OF_ARCEUUS, new WorldPoint(1700, 3742, 0)), THE_ASCENT_OF_ARCEUUS(Quest.THE_ASCENT_OF_ARCEUUS, new WorldPoint(1699, 3742, 0)),
BETWEEN_A_ROCK(Quest.BETWEEN_A_ROCK, new WorldPoint(2823, 10168, 0)), BETWEEN_A_ROCK(Quest.BETWEEN_A_ROCK, new WorldPoint(2823, 10168, 0)),
BIG_CHOMPY_BIRD_HUNTING(Quest.BIG_CHOMPY_BIRD_HUNTING, new WorldPoint(2629, 2981, 0)), BIG_CHOMPY_BIRD_HUNTING(Quest.BIG_CHOMPY_BIRD_HUNTING, new WorldPoint(2629, 2981, 0)),
BIOHAZARD(Quest.BIOHAZARD, new WorldPoint(2591, 3335, 0)), BIOHAZARD(Quest.BIOHAZARD, new WorldPoint(2591, 3335, 0)),
@@ -72,7 +72,7 @@ enum QuestStartLocation
DARKNESS_OF_HALLOWVALE(Quest.DARKNESS_OF_HALLOWVALE, new WorldPoint(3494, 9628, 0)), DARKNESS_OF_HALLOWVALE(Quest.DARKNESS_OF_HALLOWVALE, new WorldPoint(3494, 9628, 0)),
DEATH_PLATEAU_TROLL_STRONGHOLD(new Quest[]{Quest.DEATH_PLATEAU, Quest.TROLL_STRONGHOLD}, new WorldPoint(2895, 3528, 0)), DEATH_PLATEAU_TROLL_STRONGHOLD(new Quest[]{Quest.DEATH_PLATEAU, Quest.TROLL_STRONGHOLD}, new WorldPoint(2895, 3528, 0)),
DEATH_TO_THE_DORGESHUUN(Quest.DEATH_TO_THE_DORGESHUUN, new WorldPoint(3316, 9613, 0)), DEATH_TO_THE_DORGESHUUN(Quest.DEATH_TO_THE_DORGESHUUN, new WorldPoint(3316, 9613, 0)),
THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1780, 3569, 0)), THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1781, 3570, 0)),
DESERT_TREASURE(Quest.DESERT_TREASURE, new WorldPoint(3177, 3043, 0)), DESERT_TREASURE(Quest.DESERT_TREASURE, new WorldPoint(3177, 3043, 0)),
DEVIOUS_MINDS(Quest.DEVIOUS_MINDS, new WorldPoint(3405, 3492, 0)), DEVIOUS_MINDS(Quest.DEVIOUS_MINDS, new WorldPoint(3405, 3492, 0)),
THE_DIG_SITE(Quest.THE_DIG_SITE, new WorldPoint(3363, 3337, 0)), THE_DIG_SITE(Quest.THE_DIG_SITE, new WorldPoint(3363, 3337, 0)),
@@ -96,6 +96,7 @@ enum QuestStartLocation
THE_FORSAKEN_TOWER(Quest.THE_FORSAKEN_TOWER, new WorldPoint(1484, 3747, 0)), THE_FORSAKEN_TOWER(Quest.THE_FORSAKEN_TOWER, new WorldPoint(1484, 3747, 0)),
THE_FREMENNIK_ISLES(Quest.THE_FREMENNIK_ISLES, new WorldPoint(2645, 3711, 0)), THE_FREMENNIK_ISLES(Quest.THE_FREMENNIK_ISLES, new WorldPoint(2645, 3711, 0)),
THE_FREMENNIK_TRIALS(Quest.THE_FREMENNIK_TRIALS, new WorldPoint(2657, 3669, 0)), THE_FREMENNIK_TRIALS(Quest.THE_FREMENNIK_TRIALS, new WorldPoint(2657, 3669, 0)),
THE_FREMENNIK_EXILES(Quest.THE_FREMENNIK_EXILES, new WorldPoint(2658, 3669, 0)),
GARDEN_OF_TRANQUILLITY(Quest.GARDEN_OF_TRANQUILLITY, new WorldPoint(3227, 3477, 0)), GARDEN_OF_TRANQUILLITY(Quest.GARDEN_OF_TRANQUILLITY, new WorldPoint(3227, 3477, 0)),
GERTRUDES_CAT_RATCATCHERS(Quest.GERTRUDES_CAT, new WorldPoint(3150, 3411, 0)), GERTRUDES_CAT_RATCATCHERS(Quest.GERTRUDES_CAT, new WorldPoint(3150, 3411, 0)),
GHOSTS_AHOY(Quest.GHOSTS_AHOY, new WorldPoint(3677, 3510, 0)), GHOSTS_AHOY(Quest.GHOSTS_AHOY, new WorldPoint(3677, 3510, 0)),
@@ -117,7 +118,7 @@ enum QuestStartLocation
LEGENDS_QUEST(Quest.LEGENDS_QUEST, new WorldPoint(2725, 3367, 0)), LEGENDS_QUEST(Quest.LEGENDS_QUEST, new WorldPoint(2725, 3367, 0)),
LOST_CITY(Quest.LOST_CITY, new WorldPoint(3149, 3205, 0)), LOST_CITY(Quest.LOST_CITY, new WorldPoint(3149, 3205, 0)),
THE_LOST_TRIBE(Quest.THE_LOST_TRIBE, new WorldPoint(3211, 3224, 0)), THE_LOST_TRIBE(Quest.THE_LOST_TRIBE, new WorldPoint(3211, 3224, 0)),
LUNAR_DIPLOMACY(Quest.LUNAR_DIPLOMACY, new WorldPoint(2619, 3689, 0)), LUNAR_DIPLOMACY(Quest.LUNAR_DIPLOMACY, new WorldPoint(2618, 3691, 0)),
MAKING_FRIENDS_WITH_MY_ARM(Quest.MAKING_FRIENDS_WITH_MY_ARM, new WorldPoint(2904, 10092, 0)), MAKING_FRIENDS_WITH_MY_ARM(Quest.MAKING_FRIENDS_WITH_MY_ARM, new WorldPoint(2904, 10092, 0)),
MAKING_HISTORY(Quest.MAKING_HISTORY, new WorldPoint(2435, 3346, 0)), MAKING_HISTORY(Quest.MAKING_HISTORY, new WorldPoint(2435, 3346, 0)),
MONKS_FRIEND(Quest.MONKS_FRIEND, new WorldPoint(2605, 3209, 0)), MONKS_FRIEND(Quest.MONKS_FRIEND, new WorldPoint(2605, 3209, 0)),

View File

@@ -49,6 +49,7 @@ enum TransportationPointLocation
FISHINGPLAT_TO_ARDOUGNE("Ship to Ardougne", new WorldPoint(2779, 3271, 0), new WorldPoint(2722, 3304, 0)), FISHINGPLAT_TO_ARDOUGNE("Ship to Ardougne", new WorldPoint(2779, 3271, 0), new WorldPoint(2722, 3304, 0)),
HARMLESS_TO_PORT_PHASMATYS("Ship to Port Phasmatys", new WorldPoint(3682, 2951, 0), new WorldPoint(3709, 3497, 0)), HARMLESS_TO_PORT_PHASMATYS("Ship to Port Phasmatys", new WorldPoint(3682, 2951, 0), new WorldPoint(3709, 3497, 0)),
ICEBERG_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2657, 3988, 0), new WorldPoint(2707, 3735, 0)), ICEBERG_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2657, 3988, 0), new WorldPoint(2707, 3735, 0)),
ISLAND_OF_STONE_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2470, 3994, 0), new WorldPoint(2621, 3692, 0)),
ISLAND_TO_APE_ATOLL("Ship to Ape Atoll", new WorldPoint(2891, 2726, 0), new WorldPoint(2802, 2706, 0)), ISLAND_TO_APE_ATOLL("Ship to Ape Atoll", new WorldPoint(2891, 2726, 0), new WorldPoint(2802, 2706, 0)),
JATIZSO_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2420, 3780, 0), new WorldPoint(2639, 3710, 0)), JATIZSO_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2420, 3780, 0), new WorldPoint(2639, 3710, 0)),
KARAMJA_TO_PORT_SARIM("Ship to Port Sarim", new WorldPoint(2955, 3145, 0), new WorldPoint(3029, 3218, 0)), KARAMJA_TO_PORT_SARIM("Ship to Port Sarim", new WorldPoint(2955, 3145, 0), new WorldPoint(3029, 3218, 0)),
@@ -59,7 +60,7 @@ enum TransportationPointLocation
NEITIZNOT_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2310, 3779, 0), new WorldPoint(2639, 3710, 0)), NEITIZNOT_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2310, 3779, 0), new WorldPoint(2639, 3710, 0)),
PESTCONTROL_TO_PORTSARIM("Ship to Port Sarim", new WorldPoint(2659, 2675, 0), new WorldPoint(3039, 3201, 0)), PESTCONTROL_TO_PORTSARIM("Ship to Port Sarim", new WorldPoint(2659, 2675, 0), new WorldPoint(3039, 3201, 0)),
PIRATES_COVE_TO_LUNAR_ISLE("Ship to Lunar Isle", new WorldPoint(2223, 3796, 0), new WorldPoint(2137, 3899, 0)), PIRATES_COVE_TO_LUNAR_ISLE("Ship to Lunar Isle", new WorldPoint(2223, 3796, 0), new WorldPoint(2137, 3899, 0)),
PIRATES_COVE_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2212, 3794, 0), new WorldPoint(2656, 3680, 0)), PIRATES_COVE_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2212, 3794, 0), new WorldPoint(2620, 3695, 0)),
PORT_PHASMATYS_TO_DRAGONTOOTH("Ship to Dragontooth Island", new WorldPoint(3703, 3487, 0), new WorldPoint(3791, 3561, 0)), PORT_PHASMATYS_TO_DRAGONTOOTH("Ship to Dragontooth Island", new WorldPoint(3703, 3487, 0), new WorldPoint(3791, 3561, 0)),
PORT_PHASMATYS_TO_HARMLESS("Ship to Mos Le'Harmless", new WorldPoint(3709, 3497, 0), new WorldPoint(3682, 2951, 0)), PORT_PHASMATYS_TO_HARMLESS("Ship to Mos Le'Harmless", new WorldPoint(3709, 3497, 0), new WorldPoint(3682, 2951, 0)),
PORT_PISCARILIUS_TO_PORTSARIM_LANDSEND("Ship to Port Sarim/Land's End", new WorldPoint(1823, 3692, 0)), PORT_PISCARILIUS_TO_PORTSARIM_LANDSEND("Ship to Port Sarim/Land's End", new WorldPoint(1823, 3692, 0)),
@@ -70,11 +71,12 @@ enum TransportationPointLocation
PORTSARIM_TO_PEST_CONTROL("Ship to Pest Control", new WorldPoint(3039, 3201, 0), new WorldPoint(2659, 2675, 0)), PORTSARIM_TO_PEST_CONTROL("Ship to Pest Control", new WorldPoint(3039, 3201, 0), new WorldPoint(2659, 2675, 0)),
RELLEKKA_TO_JATIZSO_NEITIZNOT("Ship to Jatizso/Neitiznot", new WorldPoint(2639, 3710, 0)), RELLEKKA_TO_JATIZSO_NEITIZNOT("Ship to Jatizso/Neitiznot", new WorldPoint(2639, 3710, 0)),
RELLEKKA_TO_MISCELLANIA("Ship to Miscellania", new WorldPoint(2627, 3692, 0), new WorldPoint(2579, 3846, 0)), RELLEKKA_TO_MISCELLANIA("Ship to Miscellania", new WorldPoint(2627, 3692, 0), new WorldPoint(2579, 3846, 0)),
RELLEKKA_TO_WATERBIRTH("Ship to Waterbirth", new WorldPoint(2621, 3683, 0), new WorldPoint(2549, 3758, 0)), RELLEKKA_TO_PIRATES_COVE("Ship to Pirates' Cove", new WorldPoint(2620, 3695, 0), new WorldPoint(2212, 3794, 0)),
RELLEKKA_TO_WATERBIRTH("Ship to Waterbirth", new WorldPoint(2618, 3685, 0), new WorldPoint(2549, 3758, 0)),
RELLEKKA_TO_WEISS_ICEBERG("Ship to Weiss/Iceberg", new WorldPoint(2707, 3735, 0)), RELLEKKA_TO_WEISS_ICEBERG("Ship to Weiss/Iceberg", new WorldPoint(2707, 3735, 0)),
RELLEKKA_TO_UNGAEL("Ship to Ungael", new WorldPoint(2638, 3698, 0), new WorldPoint(2276, 4034, 0)), RELLEKKA_TO_UNGAEL("Ship to Ungael", new WorldPoint(2638, 3698, 0), new WorldPoint(2276, 4034, 0)),
RIMMINGTON_TO_CORSAIR_COVE("Ship to Corsair Cove", new WorldPoint(2909, 3227, 0 ), new WorldPoint(2577, 2839, 0)), RIMMINGTON_TO_CORSAIR_COVE("Ship to Corsair Cove", new WorldPoint(2909, 3227, 0 ), new WorldPoint(2577, 2839, 0)),
WATERBIRTH_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2549, 3758, 0), new WorldPoint(2621, 3683, 0)), WATERBIRTH_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2549, 3758, 0), new WorldPoint(2618, 3685, 0)),
WEISS_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2847, 3967, 0), new WorldPoint(2707, 3735, 0)), WEISS_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2847, 3967, 0), new WorldPoint(2707, 3735, 0)),
UNGAEL_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2276, 4034, 0), new WorldPoint(2638, 3698, 0)), UNGAEL_TO_RELLEKKA("Ship to Rellekka", new WorldPoint(2276, 4034, 0), new WorldPoint(2638, 3698, 0)),

View File

@@ -51,6 +51,7 @@ public class WidgetOverlay extends Overlay
.put(WidgetInfo.PEST_CONTROL_INFO, OverlayPosition.TOP_LEFT) .put(WidgetInfo.PEST_CONTROL_INFO, OverlayPosition.TOP_LEFT)
.put(WidgetInfo.ZEAH_MESS_HALL_COOKING_DISPLAY, OverlayPosition.TOP_LEFT) .put(WidgetInfo.ZEAH_MESS_HALL_COOKING_DISPLAY, OverlayPosition.TOP_LEFT)
.put(WidgetInfo.PVP_BOUNTY_HUNTER_INFO, OverlayPosition.TOP_RIGHT) .put(WidgetInfo.PVP_BOUNTY_HUNTER_INFO, OverlayPosition.TOP_RIGHT)
.put(WidgetInfo.PVP_KILLDEATH_COUNTER, OverlayPosition.TOP_LEFT)
.put(WidgetInfo.SKOTIZO_CONTAINER, OverlayPosition.TOP_LEFT) .put(WidgetInfo.SKOTIZO_CONTAINER, OverlayPosition.TOP_LEFT)
.put(WidgetInfo.KOUREND_FAVOUR_OVERLAY, OverlayPosition.TOP_CENTER) .put(WidgetInfo.KOUREND_FAVOUR_OVERLAY, OverlayPosition.TOP_CENTER)
.put(WidgetInfo.MULTICOMBAT_FIXED, OverlayPosition.BOTTOM_RIGHT) .put(WidgetInfo.MULTICOMBAT_FIXED, OverlayPosition.BOTTOM_RIGHT)

View File

@@ -74,9 +74,9 @@ bool face_visible(ivec4 vA, ivec4 vB, ivec4 vC, ivec4 position, int cameraYaw, i
vB += position - cameraPos; vB += position - cameraPos;
vC += position - cameraPos; vC += position - cameraPos;
ivec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
ivec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
ivec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0; return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0;
} }

View File

@@ -74,9 +74,9 @@ bool face_visible(ivec4 vA, ivec4 vB, ivec4 vC, ivec4 position, int cameraYaw, i
vB += position - cameraPos; vB += position - cameraPos;
vC += position - cameraPos; vC += position - cameraPos;
ivec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
ivec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
ivec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0; return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0;
} }

View File

@@ -60,9 +60,9 @@ out float fogAmount;
void main() { void main() {
ivec3 cameraPos = ivec3(cameraX, cameraY, cameraZ); ivec3 cameraPos = ivec3(cameraX, cameraY, cameraZ);
ivec3 screenA = toScreen(vPosition[0] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 screenA = toScreen(vPosition[0] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
ivec3 screenB = toScreen(vPosition[1] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 screenB = toScreen(vPosition[1] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
ivec3 screenC = toScreen(vPosition[2] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom); vec3 screenC = toScreen(vPosition[2] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
if (-screenA.z < 50 || -screenB.z < 50 || -screenC.z < 50) { if (-screenA.z < 50 || -screenB.z < 50 || -screenC.z < 50) {
// the client does not draw a triangle if any vertex distance is <50 // the client does not draw a triangle if any vertex distance is <50

View File

@@ -26,22 +26,22 @@
/* /*
* Convert a vertex to screen space * Convert a vertex to screen space
*/ */
ivec3 toScreen(ivec3 vertex, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) { vec3 toScreen(ivec3 vertex, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) {
int yawSin = int(65536.0f * sin(cameraYaw * UNIT)); float yawSin = sin(cameraYaw * UNIT);
int yawCos = int(65536.0f * cos(cameraYaw * UNIT)); float yawCos = cos(cameraYaw * UNIT);
int pitchSin = int(65536.0f * sin(cameraPitch * UNIT)); float pitchSin = sin(cameraPitch * UNIT);
int pitchCos = int(65536.0f * cos(cameraPitch * UNIT)); float pitchCos = cos(cameraPitch * UNIT);
int rotatedX = ((vertex.z * yawSin) + (vertex.x * yawCos)) >> 16; float rotatedX = (vertex.z * yawSin) + (vertex.x * yawCos);
int rotatedZ = ((vertex.z * yawCos) - (vertex.x * yawSin)) >> 16; float rotatedZ = (vertex.z * yawCos) - (vertex.x * yawSin);
int var13 = ((vertex.y * pitchCos) - (rotatedZ * pitchSin)) >> 16; float var13 = (vertex.y * pitchCos) - (rotatedZ * pitchSin);
int var12 = ((vertex.y * pitchSin) + (rotatedZ * pitchCos)) >> 16; float var12 = (vertex.y * pitchSin) + (rotatedZ * pitchCos);
int x = rotatedX * zoom / var12 + centerX; float x = rotatedX * zoom / var12 + centerX;
int y = var13 * zoom / var12 + centerY; float y = var13 * zoom / var12 + centerY;
int z = -var12; // in OpenGL depth is negative float z = -var12; // in OpenGL depth is negative
return ivec3(x, y, z); return vec3(x, y, z);
} }

View File

@@ -187,7 +187,7 @@
"xp": 6218.4 "xp": 6218.4
}, },
{ {
"level": 57, "level": 58,
"icon": 22932, "icon": 22932,
"name": "White lily", "name": "White lily",
"xp": 292 "xp": 292

View File

@@ -486,6 +486,24 @@
"name": "Amethyst Broad Bolts", "name": "Amethyst Broad Bolts",
"xp": 10.6 "xp": 10.6
}, },
{
"level": 78,
"icon": 21952,
"name": "Magic Stock",
"xp": 70
},
{
"level": 78,
"icon": 21921,
"name": "Dragon Crossbow (U)",
"xp": 135
},
{
"level": 78,
"icon": 21902,
"name": "Dragon Crossbow",
"xp": 70
},
{ {
"level": 80, "level": 80,
"icon": 861, "icon": 861,

View File

@@ -318,6 +318,12 @@
"name": "Ninja Impling (Gielinor)", "name": "Ninja Impling (Gielinor)",
"xp": 240 "xp": 240
}, },
{
"level": 80,
"icon": 23768,
"name": "Crystal Impling",
"xp": 280
},
{ {
"level": 83, "level": 83,
"icon": 11256, "icon": 11256,

View File

@@ -126,6 +126,12 @@
"name": "Mithril Ore", "name": "Mithril Ore",
"xp": 80 "xp": 80
}, },
{
"level": 70,
"icon": 1761,
"name": "Soft Clay",
"xp": 5
},
{ {
"level": 70, "level": 70,
"icon": 449, "icon": 449,

View File

@@ -377,12 +377,17 @@ LABEL327:
jump LABEL372 jump LABEL372
LABEL330: LABEL330:
iload 7 iload 7
iload 12 ; Load the id of the messageNode
sconst "" ; Push a container for the timestamp
sconst "addTimestamp" ; Push event name
runelite_callback ; Invoke callback
pop_int ; Pop the id of the messageNode
sconst "From " sconst "From "
sload 1 sload 1
sconst ":" sconst ":"
sconst "privateChatSplitFrom" sconst "privateChatSplitFrom"
runelite_callback runelite_callback
join_string 3 join_string 4 ; Add the timestamp to the message
sload 0 sload 0
iload 9 iload 9
iload 10 iload 10
@@ -401,12 +406,17 @@ LABEL330:
jump LABEL407 jump LABEL407
LABEL351: LABEL351:
iload 7 iload 7
iload 12 ; Load the id of the messageNode
sconst "" ; Push container for the timestamp
sconst "addTimestamp" ; Push event name
runelite_callback ; Invoke callback
pop_int ; Pop the id of the messageNode
sconst "To " sconst "To "
sload 1 sload 1
sconst ":" sconst ":"
sconst "privateChatSplitTo" sconst "privateChatSplitTo"
runelite_callback runelite_callback
join_string 3 join_string 4 ; Add the timestamp to the message
sload 0 sload 0
iload 9 iload 9
iload 10 iload 10
@@ -425,7 +435,13 @@ LABEL351:
jump LABEL407 jump LABEL407
LABEL372: LABEL372:
iload 7 iload 7
sload 0 iload 12 ; Load the id of the messageNode
sconst "" ; Push a container for the timestamp
sconst "addTimestamp" ; Push event name
runelite_callback ; Invoke callback
pop_int ; Pop the id of the messageNode
sload 0 ; Load the log in/out message
join_string 2 ; Add the timestamp to the message
iload 9 iload 9
iload 10 iload 10
iconst 10682368 iconst 10682368

View File

@@ -0,0 +1 @@
950ADB6A28E029005D24F99A65EF4D2AC4486EDC680D8770F4435F0300AA1299

View File

@@ -0,0 +1,140 @@
.id 358
.int_stack_count 6
.string_stack_count 0
.int_var_count 6
.string_var_count 0
; callback "optionsAllSounds"
; Used by the MusicPlugin to hide the vanilla (blue) volume handles
; Enable the MusicPlugin and go to the volume options panel. There should
; only be a green handle on the slider
iload 0
sconst "optionsAllSounds"
runelite_callback
istore 0
iload 0
iconst 4
if_icmpeq LABEL4
jump LABEL20
LABEL4:
iconst 687
iload 1
if_setgraphic
iconst 693
iload 2
if_setgraphic
iconst 694
iload 3
if_setgraphic
iconst 695
iload 4
if_setgraphic
iconst 696
iload 5
if_setgraphic
jump LABEL115
LABEL20:
iload 0
iconst 3
if_icmpeq LABEL24
jump LABEL40
LABEL24:
iconst 692
iload 1
if_setgraphic
iconst 688
iload 2
if_setgraphic
iconst 694
iload 3
if_setgraphic
iconst 695
iload 4
if_setgraphic
iconst 696
iload 5
if_setgraphic
jump LABEL115
LABEL40:
iload 0
iconst 2
if_icmpeq LABEL44
jump LABEL60
LABEL44:
iconst 692
iload 1
if_setgraphic
iconst 693
iload 2
if_setgraphic
iconst 689
iload 3
if_setgraphic
iconst 695
iload 4
if_setgraphic
iconst 696
iload 5
if_setgraphic
jump LABEL115
LABEL60:
iload 0
iconst 1
if_icmpeq LABEL64
jump LABEL80
LABEL64:
iconst 692
iload 1
if_setgraphic
iconst 693
iload 2
if_setgraphic
iconst 694
iload 3
if_setgraphic
iconst 690
iload 4
if_setgraphic
iconst 696
iload 5
if_setgraphic
jump LABEL115
LABEL80:
iload 0
iconst 0
if_icmpeq LABEL84
jump LABEL100
LABEL84:
iconst 692
iload 1
if_setgraphic
iconst 693
iload 2
if_setgraphic
iconst 694
iload 3
if_setgraphic
iconst 695
iload 4
if_setgraphic
iconst 691
iload 5
if_setgraphic
jump LABEL115
LABEL100:
iconst 692
iload 1
if_setgraphic
iconst 693
iload 2
if_setgraphic
iconst 694
iload 3
if_setgraphic
iconst 695
iload 4
if_setgraphic
iconst 696
iload 5
if_setgraphic
LABEL115:
return

View File

@@ -37,12 +37,12 @@ import net.runelite.client.config.ChatColorConfig;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import static org.mockito.Matchers.eq; import static org.mockito.ArgumentMatchers.eq;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class ChatMessageManagerTest public class ChatMessageManagerTest

View File

@@ -57,7 +57,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class PluginManagerTest public class PluginManagerTest

View File

@@ -44,7 +44,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class BankPluginTest public class BankPluginTest

View File

@@ -38,11 +38,11 @@ import net.runelite.client.config.ConfigManager;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import static org.mockito.Matchers.eq; import static org.mockito.ArgumentMatchers.eq;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class ChatCommandsPluginTest public class ChatCommandsPluginTest

View File

@@ -135,6 +135,7 @@ public class ChatFilterPluginTest
public void testMessageFromFriendIsFiltered() public void testMessageFromFriendIsFiltered()
{ {
chatFilterPlugin.setFilterFriends(true); chatFilterPlugin.setFilterFriends(true);
when(client.isClanMember("Iron Mammal")).thenReturn(false);
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal")); assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal"));
} }
@@ -149,8 +150,7 @@ public class ChatFilterPluginTest
@Test @Test
public void testMessageFromClanIsFiltered() public void testMessageFromClanIsFiltered()
{ {
lenient().when(client.isClanMember("B0aty")).thenReturn(true); when(client.isFriended("B0aty", false)).thenReturn(false);
chatFilterPlugin.setFilterClan(true);
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("B0aty")); assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("B0aty"));
} }

View File

@@ -34,10 +34,9 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.MessageNode; import net.runelite.api.MessageNode;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.util.Text;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.api.util.Text;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -67,10 +66,6 @@ public class ChatNotificationsPluginTest
@Bind @Bind
private Notifier notifier; private Notifier notifier;
@Mock
@Bind
private OpenOSRSConfig OpenOSRSConfig;
@Inject @Inject
private ChatNotificationsPlugin chatNotificationsPlugin; private ChatNotificationsPlugin chatNotificationsPlugin;
@@ -98,6 +93,44 @@ public class ChatNotificationsPluginTest
verify(messageNode).setValue("<colHIGHLIGHT>Deathbeam<colNORMAL>, <colHIGHLIGHT>Deathbeam<colNORMAL> OSRS"); verify(messageNode).setValue("<colHIGHLIGHT>Deathbeam<colNORMAL>, <colHIGHLIGHT>Deathbeam<colNORMAL> OSRS");
} }
@Test
public void testLtGt()
{
when(config.highlightWordsString()).thenReturn("<test>");
String message = "test <lt>test<gt> test";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("test <colHIGHLIGHT><lt>test<gt><colNORMAL> test");
}
@Test
public void testFullStop()
{
when(config.highlightWordsString()).thenReturn("test");
String message = "foo test. bar";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("foo <colHIGHLIGHT>test<colNORMAL>. bar");
}
@Test @Test
public void testColor() public void testColor()
{ {

View File

@@ -29,6 +29,7 @@ import com.google.inject.Inject;
import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule; import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.util.EnumSet; import java.util.EnumSet;
import net.runelite.api.Actor;
import net.runelite.api.AnimationID; import net.runelite.api.AnimationID;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
@@ -202,7 +203,7 @@ public class IdleNotifierPluginTest
@Test @Test
public void checkCombatReset() public void checkCombatReset()
{ {
when(player.getInteracting()).thenReturn(monster); when(player.getInteracting()).thenReturn(mock(Actor.class));
plugin.onInteractingChanged(new InteractingChanged(player, monster)); plugin.onInteractingChanged(new InteractingChanged(player, monster));
plugin.onGameTick(GameTick.INSTANCE); plugin.onGameTick(GameTick.INSTANCE);
plugin.onInteractingChanged(new InteractingChanged(player, randomEvent)); plugin.onInteractingChanged(new InteractingChanged(player, randomEvent));
@@ -216,7 +217,7 @@ public class IdleNotifierPluginTest
public void checkCombatLogout() public void checkCombatLogout()
{ {
plugin.onInteractingChanged(new InteractingChanged(player, monster)); plugin.onInteractingChanged(new InteractingChanged(player, monster));
when(player.getInteracting()).thenReturn(monster); when(player.getInteracting()).thenReturn(mock(Actor.class));
plugin.onGameTick(GameTick.INSTANCE); plugin.onGameTick(GameTick.INSTANCE);
// Logout // Logout

View File

@@ -40,7 +40,6 @@ import static net.runelite.api.widgets.WidgetID.DIALOG_SPRITE_GROUP_ID;
import static net.runelite.api.widgets.WidgetID.LEVEL_UP_GROUP_ID; import static net.runelite.api.widgets.WidgetID.LEVEL_UP_GROUP_ID;
import static net.runelite.api.widgets.WidgetInfo.DIALOG_SPRITE_TEXT; import static net.runelite.api.widgets.WidgetInfo.DIALOG_SPRITE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.LEVEL_UP_LEVEL; import static net.runelite.api.widgets.WidgetInfo.LEVEL_UP_LEVEL;
import static net.runelite.api.widgets.WidgetInfo.PACK;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ClientUI;
@@ -169,8 +168,6 @@ public class ScreenshotPluginTest
@Test @Test
public void testHitpointsLevel99() public void testHitpointsLevel99()
{ {
Widget widget = mock(Widget.class);
Widget levelChild = mock(Widget.class); Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild); when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
@@ -192,8 +189,6 @@ public class ScreenshotPluginTest
@Test @Test
public void testFiremakingLevel9() public void testFiremakingLevel9()
{ {
Widget widget = mock(Widget.class);
Widget levelChild = mock(Widget.class); Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild); when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
@@ -215,8 +210,6 @@ public class ScreenshotPluginTest
@Test @Test
public void testAttackLevel70() public void testAttackLevel70()
{ {
Widget widget = mock(Widget.class);
Widget levelChild = mock(Widget.class); Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild); when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
@@ -238,8 +231,6 @@ public class ScreenshotPluginTest
@Test @Test
public void testHunterLevel2() public void testHunterLevel2()
{ {
Widget widget = mock(Widget.class);
Widget levelChild = mock(Widget.class); Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(DIALOG_SPRITE_TEXT))).thenReturn(levelChild); when(client.getWidget(eq(DIALOG_SPRITE_TEXT))).thenReturn(levelChild);

View File

@@ -51,7 +51,7 @@ import org.mockito.junit.MockitoJUnitRunner;
public class TimersPluginTest public class TimersPluginTest
{ {
private static final String DMM_HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 1 minute, 15 seconds.</col>"; private static final String DMM_HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 1 minute, 15 seconds.</col>";
private static final String FULL_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 5 minutes, 0 seconds.</col>"; private static final String FULL_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 5 minutes.</col>";
private static final String HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds.</col>"; private static final String HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds.</col>";
@Inject @Inject

View File

@@ -27,13 +27,11 @@ package net.runelite.client.plugins.xptracker;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule; import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.util.EnumSet;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import net.runelite.api.WorldType;
import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;

View File

@@ -50,6 +50,7 @@ import net.runelite.api.Ignore;
import net.runelite.api.IndexDataBase; import net.runelite.api.IndexDataBase;
import net.runelite.api.IndexedSprite; import net.runelite.api.IndexedSprite;
import net.runelite.api.InventoryID; import net.runelite.api.InventoryID;
import net.runelite.api.MenuEntry;
import net.runelite.api.MenuOpcode; import net.runelite.api.MenuOpcode;
import static net.runelite.api.MenuOpcode.PLAYER_EIGTH_OPTION; import static net.runelite.api.MenuOpcode.PLAYER_EIGTH_OPTION;
import static net.runelite.api.MenuOpcode.PLAYER_FIFTH_OPTION; import static net.runelite.api.MenuOpcode.PLAYER_FIFTH_OPTION;
@@ -59,7 +60,6 @@ import static net.runelite.api.MenuOpcode.PLAYER_SECOND_OPTION;
import static net.runelite.api.MenuOpcode.PLAYER_SEVENTH_OPTION; import static net.runelite.api.MenuOpcode.PLAYER_SEVENTH_OPTION;
import static net.runelite.api.MenuOpcode.PLAYER_SIXTH_OPTION; import static net.runelite.api.MenuOpcode.PLAYER_SIXTH_OPTION;
import static net.runelite.api.MenuOpcode.PLAYER_THIRD_OPTION; import static net.runelite.api.MenuOpcode.PLAYER_THIRD_OPTION;
import net.runelite.api.MenuEntry;
import net.runelite.api.MessageNode; import net.runelite.api.MessageNode;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.Node; import net.runelite.api.Node;
@@ -98,6 +98,7 @@ import net.runelite.api.events.PlayerSpawned;
import net.runelite.api.events.ResizeableChanged; import net.runelite.api.events.ResizeableChanged;
import net.runelite.api.events.UsernameChanged; import net.runelite.api.events.UsernameChanged;
import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.VolumeChanged;
import net.runelite.api.events.WidgetLoaded; import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.events.WidgetPressed; import net.runelite.api.events.WidgetPressed;
import net.runelite.api.hooks.Callbacks; import net.runelite.api.hooks.Callbacks;
@@ -1760,7 +1761,6 @@ public abstract class RSClientMixin implements RSClient
return modulus; return modulus;
} }
@Inject @Inject
@Override @Override
public void setModulus(BigInteger modulus) public void setModulus(BigInteger modulus)
@@ -1783,4 +1783,41 @@ public abstract class RSClientMixin implements RSClient
client.promptCredentials(true); client.promptCredentials(true);
} }
} }
@Inject
@Override
public void setMusicVolume(int volume)
{
if (volume > 0 && client.getMusicVolume() <= 0 && client.getCurrentTrackGroupId() != -1)
{
client.playMusicTrack(client.getMusicTracks(), client.getCurrentTrackGroupId(), 0, volume, false);
}
client.setClientMusicVolume(volume);
client.setMusicTrackVolume(volume);
if (client.getMidiPcmStream() != null)
{
client.getMidiPcmStream().setPcmStreamVolume(volume);
}
}
@Copy("changeGameOptions")
public static void rs$changeGameOptions(int var0)
{
throw new RuntimeException();
}
@Replace("changeGameOptions")
public static void changeGameOptions(int var0)
{
rs$changeGameOptions(var0);
int type = client.getVarpDefinition(var0).getType();
if (type == 3 || type == 4 || type == 10)
{
VolumeChanged volumeChanged = new VolumeChanged(type == 3 ? VolumeChanged.Type.MUSIC : type == 4 ? VolumeChanged.Type.EFFECTS : VolumeChanged.Type.AREA);
client.getCallbacks().post(VolumeChanged.class, volumeChanged);
}
}
} }

View File

@@ -31,11 +31,11 @@ import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow; import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSRawPcmStream;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSPcmStream;
import net.runelite.rs.api.RSRawPcmStream;
import net.runelite.rs.api.RSRawSound; import net.runelite.rs.api.RSRawSound;
import net.runelite.rs.api.RSSoundEffect; import net.runelite.rs.api.RSSoundEffect;
import net.runelite.rs.api.RSPcmStream;
@Mixin(RSClient.class) @Mixin(RSClient.class)
public abstract class SoundEffectMixin implements RSClient public abstract class SoundEffectMixin implements RSClient

View File

@@ -449,6 +449,9 @@ public interface RSClient extends RSGameShell, Client
@Import("SpriteBuffer_spritePalette") @Import("SpriteBuffer_spritePalette")
void setIndexedSpritePalette(int[] indexedSpritePalette); void setIndexedSpritePalette(int[] indexedSpritePalette);
@Import("archive6")
RSAbstractArchive getMusicTracks();
@Import("archive8") @Import("archive8")
@Override @Override
RSAbstractArchive getIndexSprites(); RSAbstractArchive getIndexSprites();
@@ -1042,12 +1045,44 @@ public interface RSClient extends RSGameShell, Client
@Import("decimator") @Import("decimator")
RSDecimator getSoundEffectResampler(); RSDecimator getSoundEffectResampler();
@Import("musicVolume")
@Override
int getMusicVolume();
@Import("musicVolume")
void setClientMusicVolume(int volume);
@Import("areaSoundEffectVolume")
@Override
int getAreaSoundEffectVolume();
@Import("areaSoundEffectVolume")
@Override
void setAreaSoundEffectVolume(int volume);
@Import("soundEffectVolume") @Import("soundEffectVolume")
@Override
int getSoundEffectVolume(); int getSoundEffectVolume();
@Import("soundEffectVolume")
@Override
void setSoundEffectVolume(int volume);
@Import("musicTrackVolume")
void setMusicTrackVolume(int volume);
@Import("viewportWalking") @Import("viewportWalking")
void setViewportWalking(boolean viewportWalking); void setViewportWalking(boolean viewportWalking);
@Import("playMusicTrack")
void playMusicTrack(RSAbstractArchive var0, int var1, int var2, int var3, boolean var4);
@Import("midiPcmStream")
RSMidiPcmStream getMidiPcmStream();
@Import("currentTrackGroupId")
int getCurrentTrackGroupId();
@Import("crossSprites") @Import("crossSprites")
@Override @Override
RSSprite[] getCrossSprites(); RSSprite[] getCrossSprites();
@@ -1101,6 +1136,9 @@ public interface RSClient extends RSGameShell, Client
@Import("Login_promptCredentials") @Import("Login_promptCredentials")
void promptCredentials(boolean clearPass); void promptCredentials(boolean clearPass);
@Import("VarpDefinition_get")
RSVarpDefinition getVarpDefinition(int id);
@Construct @Construct
RSTileItem newTileItem(); RSTileItem newTileItem();

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018, trimbe <github.com/trimbe>
* 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.rs.api;
import net.runelite.mapping.Import;
public interface RSMidiPcmStream
{
@Import("setPcmStreamVolume")
void setPcmStreamVolume(int volume);
}

View File

@@ -20,4 +20,7 @@ public interface RSScriptEvent extends ScriptEvent
@Import("targetName") @Import("targetName")
String getOpbase(); String getOpbase();
@Import("mouseX")
int getMouseX();
} }

View File

@@ -0,0 +1,9 @@
package net.runelite.rs.api;
import net.runelite.mapping.Import;
public interface RSVarpDefinition extends RSDualNode
{
@Import("type")
int getType();
}

View File

@@ -496,4 +496,20 @@ public interface RSWidget extends Widget
@Import("getSprite") @Import("getSprite")
RSSprite getSprite(boolean b); RSSprite getSprite(boolean b);
@Import("onRelease")
@Override
void setOnReleaseListener(Object[] o);
@Import("varTransmitTriggers")
@Override
void setVarTransmitTrigger(int[] i);
@Import("onHold")
@Override
void setOnHoldListener(Object[] o);
@Import("onClick")
@Override
void setOnClickListener(Object[] o);
} }

View File

@@ -213,10 +213,10 @@ public abstract class AbstractWorldMapIcon {
class197.midiPcmStream.clear(); class197.midiPcmStream.clear();
class197.field2377 = 1; class197.field2377 = 1;
class247.musicTrackArchive = null; class247.musicTrackArchive = null;
} else if (var0 != -1 && var0 != Client.field865 && Client.field864 != 0 && !Client.field855) { } else if (var0 != -1 && var0 != Client.currentTrackGroupId && Client.musicVolume != 0 && !Client.field855) {
WorldMapIcon_0.method253(2, class216.archive6, var0, 0, Client.field864, false); WorldMapIcon_0.method253(2, class216.archive6, var0, 0, Client.musicVolume, false);
} }
Client.field865 = var0; Client.currentTrackGroupId = var0;
} }
} }

View File

@@ -237,7 +237,8 @@ public final class Client extends GameShell implements Usernamed {
@ObfuscatedGetter( @ObfuscatedGetter(
intValue = -1636781949 intValue = -1636781949
) )
static int field868; @Export("areaSoundEffectVolume")
static int areaSoundEffectVolume;
@ObfuscatedName("sl") @ObfuscatedName("sl")
@ObfuscatedGetter( @ObfuscatedGetter(
intValue = 1393467707 intValue = 1393467707
@@ -354,7 +355,8 @@ public final class Client extends GameShell implements Usernamed {
@ObfuscatedGetter( @ObfuscatedGetter(
intValue = 398456721 intValue = 398456721
) )
static int field865; @Export("currentTrackGroupId")
static int currentTrackGroupId;
@ObfuscatedName("pq") @ObfuscatedName("pq")
@ObfuscatedGetter( @ObfuscatedGetter(
intValue = -87647027 intValue = -87647027
@@ -372,7 +374,8 @@ public final class Client extends GameShell implements Usernamed {
@ObfuscatedGetter( @ObfuscatedGetter(
intValue = -1999845863 intValue = -1999845863
) )
static int field864; @Export("musicVolume")
static int musicVolume;
@ObfuscatedName("qq") @ObfuscatedName("qq")
@Export("soundLocations") @Export("soundLocations")
static int[] soundLocations; static int[] soundLocations;
@@ -1493,11 +1496,11 @@ public final class Client extends GameShell implements Usernamed {
destinationX = 0; destinationX = 0;
destinationY = 0; destinationY = 0;
minimapState = 0; minimapState = 0;
field864 = 255; musicVolume = 255;
field865 = -1; currentTrackGroupId = -1;
field855 = false; field855 = false;
soundEffectVolume = 127; soundEffectVolume = 127;
field868 = 127; areaSoundEffectVolume = 127;
soundEffectCount = 0; soundEffectCount = 0;
soundEffectIds = new int[50]; soundEffectIds = new int[50];
queuedSoundEffectLoops = new int[50]; queuedSoundEffectLoops = new int[50];
@@ -1611,7 +1614,7 @@ public final class Client extends GameShell implements Usernamed {
var45 = 0; var45 = 0;
} }
class197.midiPcmStream.method3942(var45); class197.midiPcmStream.setPcmStreamVolume(var45);
} else { } else {
class197.midiPcmStream.clear(); class197.midiPcmStream.clear();
class197.midiPcmStream.removeAll(); class197.midiPcmStream.removeAll();
@@ -2653,7 +2656,7 @@ public final class Client extends GameShell implements Usernamed {
if (class197.midiPcmStream.loadMusicTrack(class197.musicTrack, class197.musicPatchesArchive, ByteArrayPool.soundCache, 22050)) { if (class197.midiPcmStream.loadMusicTrack(class197.musicTrack, class197.musicPatchesArchive, ByteArrayPool.soundCache, 22050)) {
class197.midiPcmStream.clearAll(); class197.midiPcmStream.clearAll();
class197.midiPcmStream.method3942(class197.field2379); class197.midiPcmStream.setPcmStreamVolume(class197.musicTrackVolume);
class197.midiPcmStream.setMusicTrack(class197.musicTrack, ScriptFrame.musicTrackBoolean); class197.midiPcmStream.setMusicTrack(class197.musicTrack, ScriptFrame.musicTrackBoolean);
class197.field2377 = 0; class197.field2377 = 0;
class197.musicTrack = null; class197.musicTrack = null;
@@ -4084,7 +4087,7 @@ public final class Client extends GameShell implements Usernamed {
var9 = 0; var9 = 0;
} }
var3 = (var4 - var9) * field868 / var4; var3 = (var4 - var9) * areaSoundEffectVolume / var4;
} else { } else {
var3 = soundEffectVolume; var3 = soundEffectVolume;
} }
@@ -4114,8 +4117,8 @@ public final class Client extends GameShell implements Usernamed {
} }
if (field855 && !Login.method2256()) { if (field855 && !Login.method2256()) {
if (field864 != 0 && field865 != -1) { if (musicVolume != 0 && currentTrackGroupId != -1) {
MusicPatchNode2.method3830(class216.archive6, field865, 0, field864, false); MusicPatchNode2.playMusicTrack(class216.archive6, currentTrackGroupId, 0, musicVolume, false);
} }
field855 = false; field855 = false;
@@ -4717,13 +4720,13 @@ public final class Client extends GameShell implements Usernamed {
var6 += var5.y * 128 - var3; var6 += var5.y * 128 - var3;
} }
if (var6 - 64 <= var5.field1052 && field868 != 0 && var1 == var5.plane) { if (var6 - 64 <= var5.field1052 && areaSoundEffectVolume != 0 && var1 == var5.plane) {
var6 -= 64; var6 -= 64;
if (var6 < 0) { if (var6 < 0) {
var6 = 0; var6 = 0;
} }
int var7 = (var5.field1052 - var6) * field868 / var5.field1052; int var7 = (var5.field1052 - var6) * areaSoundEffectVolume / var5.field1052;
Object var10000; Object var10000;
if (var5.stream1 == null) { if (var5.stream1 == null) {
if (var5.soundEffectId >= 0) { if (var5.soundEffectId >= 0) {
@@ -5630,7 +5633,7 @@ public final class Client extends GameShell implements Usernamed {
if (ServerPacket.field2103 == var1.serverPacket) { if (ServerPacket.field2103 == var1.serverPacket) {
for (var16 = 0; var16 < VarpDefinition.VarpDefinition_fileCount; ++var16) { for (var16 = 0; var16 < VarpDefinition.VarpDefinition_fileCount; ++var16) {
VarpDefinition var51 = Varcs.method2352(var16); VarpDefinition var51 = Varcs.VarpDefinition_get(var16);
if (var51 != null) { if (var51 != null) {
Varps.Varps_temp[var16] = 0; Varps.Varps_temp[var16] = 0;
Varps.Varps_main[var16] = 0; Varps.Varps_main[var16] = 0;
@@ -5657,7 +5660,7 @@ public final class Client extends GameShell implements Usernamed {
Varps.Varps_main[var16] = var41; Varps.Varps_main[var16] = var41;
} }
WorldMapDecoration.method389(var16); WorldMapDecoration.changeGameOptions(var16);
field817[++field679 - 1 & 31] = var16; field817[++field679 - 1 & 31] = var16;
var1.serverPacket = null; var1.serverPacket = null;
return true; return true;
@@ -5681,7 +5684,7 @@ public final class Client extends GameShell implements Usernamed {
for (var16 = 0; var16 < Varps.Varps_main.length; ++var16) { for (var16 = 0; var16 < Varps.Varps_main.length; ++var16) {
if (Varps.Varps_main[var16] != Varps.Varps_temp[var16]) { if (Varps.Varps_main[var16] != Varps.Varps_temp[var16]) {
Varps.Varps_main[var16] = Varps.Varps_temp[var16]; Varps.Varps_main[var16] = Varps.Varps_temp[var16];
WorldMapDecoration.method389(var16); WorldMapDecoration.changeGameOptions(var16);
field817[++field679 - 1 & 31] = var16; field817[++field679 - 1 & 31] = var16;
} }
} }
@@ -6003,7 +6006,7 @@ public final class Client extends GameShell implements Usernamed {
Varps.Varps_main[var5] = var16; Varps.Varps_main[var5] = var16;
} }
WorldMapDecoration.method389(var5); WorldMapDecoration.changeGameOptions(var5);
field817[++field679 - 1 & 31] = var5; field817[++field679 - 1 & 31] = var5;
var1.serverPacket = null; var1.serverPacket = null;
return true; return true;

View File

@@ -475,7 +475,7 @@ public class GrandExchangeOfferOwnWorldComparator implements Comparator {
if (var14.cs1Instructions != null && var14.cs1Instructions[0][0] == 5) { if (var14.cs1Instructions != null && var14.cs1Instructions[0][0] == 5) {
var10 = var14.cs1Instructions[0][1]; var10 = var14.cs1Instructions[0][1];
Varps.Varps_main[var10] = 1 - Varps.Varps_main[var10]; Varps.Varps_main[var10] = 1 - Varps.Varps_main[var10];
WorldMapDecoration.method389(var10); WorldMapDecoration.changeGameOptions(var10);
} }
} else if (var2 == 29) { } else if (var2 == 29) {
var8 = SoundSystem.getPacketBufferNode(ClientPacket.field2252, Client.packetWriter.isaacCipher); var8 = SoundSystem.getPacketBufferNode(ClientPacket.field2252, Client.packetWriter.isaacCipher);
@@ -486,7 +486,7 @@ public class GrandExchangeOfferOwnWorldComparator implements Comparator {
var10 = var14.cs1Instructions[0][1]; var10 = var14.cs1Instructions[0][1];
if (Varps.Varps_main[var10] != var14.cs1ComparisonValues[0]) { if (Varps.Varps_main[var10] != var14.cs1ComparisonValues[0]) {
Varps.Varps_main[var10] = var14.cs1ComparisonValues[0]; Varps.Varps_main[var10] = var14.cs1ComparisonValues[0];
WorldMapDecoration.method389(var10); WorldMapDecoration.changeGameOptions(var10);
} }
} }
} else if (var2 == 30) { } else if (var2 == 30) {

View File

@@ -169,7 +169,7 @@ final class GrandExchangeOfferTotalQuantityComparator implements Comparator {
PacketWriter.friendSystem.clear(); PacketWriter.friendSystem.clear();
for (var0 = 0; var0 < VarpDefinition.VarpDefinition_fileCount; ++var0) { for (var0 = 0; var0 < VarpDefinition.VarpDefinition_fileCount; ++var0) {
VarpDefinition var3 = Varcs.method2352(var0); VarpDefinition var3 = Varcs.VarpDefinition_get(var0);
if (var3 != null) { if (var3 != null) {
Varps.Varps_temp[var0] = 0; Varps.Varps_temp[var0] = 0;
Varps.Varps_main[var0] = 0; Varps.Varps_main[var0] = 0;

View File

@@ -137,7 +137,8 @@ public class MidiPcmStream extends PcmStream {
signature = "(II)V", signature = "(II)V",
garbageValue = "636798046" garbageValue = "636798046"
) )
public synchronized void method3942(int var1) { @Export("setPcmStreamVolume")
public synchronized void setPcmStreamVolume(int var1) {
this.field2399 = var1; this.field2399 = var1;
} }

View File

@@ -1,3 +1,4 @@
import net.runelite.mapping.Export;
import net.runelite.mapping.Implements; import net.runelite.mapping.Implements;
import net.runelite.mapping.ObfuscatedGetter; import net.runelite.mapping.ObfuscatedGetter;
import net.runelite.mapping.ObfuscatedName; import net.runelite.mapping.ObfuscatedName;
@@ -92,12 +93,13 @@ public class MusicPatchNode2 {
signature = "(Lhq;IIIZI)V", signature = "(Lhq;IIIZI)V",
garbageValue = "1856110966" garbageValue = "1856110966"
) )
public static void method3830(AbstractArchive var0, int var1, int var2, int var3, boolean var4) { @Export("playMusicTrack")
public static void playMusicTrack(AbstractArchive var0, int var1, int var2, int var3, boolean var4) {
class197.field2377 = 1; class197.field2377 = 1;
class247.musicTrackArchive = var0; class247.musicTrackArchive = var0;
class189.musicTrackGroupId = var1; class189.musicTrackGroupId = var1;
class197.musicTrackFileId = var2; class197.musicTrackFileId = var2;
class197.field2379 = var3; class197.musicTrackVolume = var3;
ScriptFrame.musicTrackBoolean = var4; ScriptFrame.musicTrackBoolean = var4;
class197.field2384 = 10000; class197.field2384 = 10000;
} }

View File

@@ -231,7 +231,7 @@ public final class Tile extends Node {
) )
@Export("addSequenceSoundEffect") @Export("addSequenceSoundEffect")
static void addSequenceSoundEffect(SequenceDefinition var0, int var1, int var2, int var3) { static void addSequenceSoundEffect(SequenceDefinition var0, int var1, int var2, int var3) {
if (Client.soundEffectCount < 50 && Client.field868 != 0) { if (Client.soundEffectCount < 50 && Client.areaSoundEffectVolume != 0) {
if (var0.soundEffects != null && var1 < var0.soundEffects.length) { if (var0.soundEffects != null && var1 < var0.soundEffects.length) {
int var4 = var0.soundEffects[var1]; int var4 = var0.soundEffects[var1];
if (var4 != 0) { if (var4 != 0) {

View File

@@ -329,7 +329,8 @@ public class Varcs {
signature = "(II)Liu;", signature = "(II)Liu;",
garbageValue = "-1999284157" garbageValue = "-1999284157"
) )
public static VarpDefinition method2352(int var0) { @Export("VarpDefinition_get")
public static VarpDefinition VarpDefinition_get(int var0) {
VarpDefinition var1 = (VarpDefinition)VarpDefinition.VarpDefinition_cached.get((long)var0); VarpDefinition var1 = (VarpDefinition)VarpDefinition.VarpDefinition_cached.get((long)var0);
if (var1 != null) { if (var1 != null) {
return var1; return var1;

View File

@@ -140,7 +140,8 @@ public class WorldMapDecoration {
signature = "(IB)V", signature = "(IB)V",
garbageValue = "-115" garbageValue = "-115"
) )
static final void method389(int var0) { @Export("changeGameOptions")
static final void changeGameOptions(int var0) {
BoundaryObject.method3393(); BoundaryObject.method3393();
for (ObjectSound var1 = (ObjectSound)ObjectSound.objectSounds.last(); var1 != null; var1 = (ObjectSound)ObjectSound.objectSounds.previous()) { for (ObjectSound var1 = (ObjectSound)ObjectSound.objectSounds.last(); var1 != null; var1 = (ObjectSound)ObjectSound.objectSounds.previous()) {
@@ -149,7 +150,7 @@ public class WorldMapDecoration {
} }
} }
int var4 = Varcs.method2352(var0).type; int var4 = Varcs.VarpDefinition_get(var0).type;
if (var4 != 0) { if (var4 != 0) {
int var2 = Varps.Varps_main[var0]; int var2 = Varps.Varps_main[var0];
if (var4 == 1) { if (var4 == 1) {
@@ -198,20 +199,20 @@ public class WorldMapDecoration {
var3 = 0; var3 = 0;
} }
if (var3 != Client.field864) { if (var3 != Client.musicVolume) {
if (Client.field864 == 0 && Client.field865 != -1) { if (Client.musicVolume == 0 && Client.currentTrackGroupId != -1) {
MusicPatchNode2.method3830(class216.archive6, Client.field865, 0, var3, false); MusicPatchNode2.playMusicTrack(class216.archive6, Client.currentTrackGroupId, 0, var3, false);
Client.field855 = false; Client.field855 = false;
} else if (var3 == 0) { } else if (var3 == 0) {
ReflectionCheck.method2438(); ReflectionCheck.method2438();
Client.field855 = false; Client.field855 = false;
} else if (class197.field2377 != 0) { } else if (class197.field2377 != 0) {
class197.field2379 = var3; class197.musicTrackVolume = var3;
} else { } else {
class197.midiPcmStream.method3942(var3); class197.midiPcmStream.setPcmStreamVolume(var3);
} }
Client.field864 = var3; Client.musicVolume = var3;
} }
} }
@@ -251,23 +252,23 @@ public class WorldMapDecoration {
if (var4 == 10) { if (var4 == 10) {
if (var2 == 0) { if (var2 == 0) {
Client.field868 = 127; Client.areaSoundEffectVolume = 127;
} }
if (var2 == 1) { if (var2 == 1) {
Client.field868 = 96; Client.areaSoundEffectVolume = 96;
} }
if (var2 == 2) { if (var2 == 2) {
Client.field868 = 64; Client.areaSoundEffectVolume = 64;
} }
if (var2 == 3) { if (var2 == 3) {
Client.field868 = 32; Client.areaSoundEffectVolume = 32;
} }
if (var2 == 4) { if (var2 == 4) {
Client.field868 = 0; Client.areaSoundEffectVolume = 0;
} }
} }

View File

@@ -42,8 +42,8 @@ public class WorldMapEvent {
) )
@Export("playSoundJingle") @Export("playSoundJingle")
static void playSoundJingle(int var0, int var1) { static void playSoundJingle(int var0, int var1) {
if (Client.field864 != 0 && var0 != -1) { if (Client.musicVolume != 0 && var0 != -1) {
MusicPatchNode2.method3830(Decimator.archive11, var0, 0, Client.field864, false); MusicPatchNode2.playMusicTrack(Decimator.archive11, var0, 0, Client.musicVolume, false);
Client.field855 = true; Client.field855 = true;
} }

View File

@@ -173,7 +173,7 @@ public class WorldMapIcon_0 extends AbstractWorldMapIcon {
class247.musicTrackArchive = var1; class247.musicTrackArchive = var1;
class189.musicTrackGroupId = var2; class189.musicTrackGroupId = var2;
class197.musicTrackFileId = var3; class197.musicTrackFileId = var3;
class197.field2379 = var4; class197.musicTrackVolume = var4;
ScriptFrame.musicTrackBoolean = var5; ScriptFrame.musicTrackBoolean = var5;
class197.field2384 = var0; class197.field2384 = var0;
} }

View File

@@ -62,7 +62,7 @@ public final class WorldMapRectangle {
public static void method330(AbstractArchive var0, String var1, String var2, int var3, boolean var4) { public static void method330(AbstractArchive var0, String var1, String var2, int var3, boolean var4) {
int var5 = var0.getGroupId(var1); int var5 = var0.getGroupId(var1);
int var6 = var0.getFileId(var5, var2); int var6 = var0.getFileId(var5, var2);
MusicPatchNode2.method3830(var0, var5, var6, var3, var4); MusicPatchNode2.playMusicTrack(var0, var5, var6, var3, var4);
} }
@ObfuscatedName("v") @ObfuscatedName("v")

View File

@@ -392,7 +392,7 @@ public final class WorldMapSprite {
var37 = var1.method5646(); var37 = var1.method5646();
if (var7 >= 0 && var8 >= 0 && var7 < 104 && var8 < 104) { if (var7 >= 0 && var8 >= 0 && var7 < 104 && var8 < 104) {
var32 = var4 + 1; var32 = var4 + 1;
if (class215.localPlayer.pathX[0] >= var7 - var32 && class215.localPlayer.pathX[0] <= var7 + var32 && class215.localPlayer.pathY[0] >= var8 - var32 && class215.localPlayer.pathY[0] <= var8 + var32 && Client.field868 != 0 && var5 > 0 && Client.soundEffectCount < 50) { if (class215.localPlayer.pathX[0] >= var7 - var32 && class215.localPlayer.pathX[0] <= var7 + var32 && class215.localPlayer.pathY[0] >= var8 - var32 && class215.localPlayer.pathY[0] <= var8 + var32 && Client.areaSoundEffectVolume != 0 && var5 > 0 && Client.soundEffectCount < 50) {
Client.soundEffectIds[Client.soundEffectCount] = var37; Client.soundEffectIds[Client.soundEffectCount] = var37;
Client.queuedSoundEffectLoops[Client.soundEffectCount] = var5; Client.queuedSoundEffectLoops[Client.soundEffectCount] = var5;
Client.queuedSoundEffectDelays[Client.soundEffectCount] = var2; Client.queuedSoundEffectDelays[Client.soundEffectCount] = var2;

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