Merge remote-tracking branch 'Upstream/master'

# Conflicts:
#	http-api/src/main/java/net/runelite/http/api/ws/messages/party/PartyChatMessage.java
#	runelite-api/src/main/java/net/runelite/api/Quest.java
#	runelite-client/src/main/java/net/runelite/client/RuneLite.java
#	runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java
#	runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItem.java
#	runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java
#	runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java
#	runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/itemprices/ItemPricesOverlay.java
#	runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/questlist/QuestListPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/zoom/ZoomPlugin.java
#	runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java
#	runelite-client/src/main/java/net/runelite/client/ws/PartyService.java
#	runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java
This commit is contained in:
Zeruth
2019-07-29 01:44:57 -04:00
49 changed files with 611 additions and 663 deletions

View File

@@ -34,6 +34,7 @@ import net.runelite.http.api.ws.messages.Handshake;
import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.api.ws.messages.LoginResponse;
import net.runelite.http.api.ws.messages.party.Join; import net.runelite.http.api.ws.messages.party.Join;
import net.runelite.http.api.ws.messages.party.Part; import net.runelite.http.api.ws.messages.party.Part;
import net.runelite.http.api.ws.messages.party.PartyChatMessage;
import net.runelite.http.api.ws.messages.party.UserJoin; import net.runelite.http.api.ws.messages.party.UserJoin;
import net.runelite.http.api.ws.messages.party.UserPart; import net.runelite.http.api.ws.messages.party.UserPart;
import net.runelite.http.api.ws.messages.party.UserSync; import net.runelite.http.api.ws.messages.party.UserSync;
@@ -52,6 +53,7 @@ public class WebsocketGsonFactory
messages.add(UserJoin.class); messages.add(UserJoin.class);
messages.add(UserPart.class); messages.add(UserPart.class);
messages.add(UserSync.class); messages.add(UserSync.class);
messages.add(PartyChatMessage.class);
MESSAGES = messages; MESSAGES = messages;
} }

View File

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

View File

@@ -173,6 +173,7 @@ public enum Quest
ZOGRE_FLESH_EATERS(449, "Zogre Flesh Eaters", Varbits.QUEST_ZOGRE_FLESH_EATERS), ZOGRE_FLESH_EATERS(449, "Zogre Flesh Eaters", Varbits.QUEST_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", Varbits.QUEST_THE_ASCENT_OF_ARCEUUS),
THE_FORSAKEN_TOWER(543, "The Forsaken Tower", Varbits.QUEST_THE_FORSAKEN_TOWER), THE_FORSAKEN_TOWER(543, "The Forsaken Tower", Varbits.QUEST_THE_FORSAKEN_TOWER),
SONG_OF_THE_ELVES(603, "Song of the Elves", Varbits.QUEST_SONG_OF_THE_ELVES),
//Miniquests //Miniquests
ENTER_THE_ABYSS(319, "Enter the Abyss", VarPlayer.QUEST_ENTER_THE_ABYSS), ENTER_THE_ABYSS(319, "Enter the Abyss", VarPlayer.QUEST_ENTER_THE_ABYSS),
@@ -186,7 +187,8 @@ public enum Quest
THE_MAGE_ARENA(327, "The Mage Arena", VarPlayer.QUEST_THE_MAGE_ARENA), THE_MAGE_ARENA(327, "The Mage Arena", VarPlayer.QUEST_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", Varbits.QUEST_LAIR_OF_TARN_RAZORLOR),
FAMILY_PEST(329, "Family Pest", Varbits.QUEST_FAMILY_PEST), FAMILY_PEST(329, "Family Pest", Varbits.QUEST_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", Varbits.QUEST_THE_MAGE_ARENA_II),
IN_SEARCH_OF_KNOWLEDGE(602, "In Search of Knowledge", Varbits.QUEST_IN_SEARCH_OF_KNOWLEDGE);
@Getter @Getter
private final int id; private final int id;

View File

@@ -629,6 +629,8 @@ public enum Varbits
QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528), QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528),
QUEST_THE_ASCENT_OF_ARCEUUS(7856), QUEST_THE_ASCENT_OF_ARCEUUS(7856),
QUEST_THE_FORSAKEN_TOWER(7796), QUEST_THE_FORSAKEN_TOWER(7796),
//TODO
QUEST_SONG_OF_THE_ELVES(7796),
/** /**
* mini-quest varbits, these don't hold the completion value. * mini-quest varbits, these don't hold the completion value.
@@ -642,6 +644,8 @@ public enum Varbits
QUEST_LAIR_OF_TARN_RAZORLOR(3290), QUEST_LAIR_OF_TARN_RAZORLOR(3290),
QUEST_FAMILY_PEST(5347), QUEST_FAMILY_PEST(5347),
QUEST_THE_MAGE_ARENA_II(6067), QUEST_THE_MAGE_ARENA_II(6067),
//TODO
QUEST_IN_SEARCH_OF_KNOWLEDGE(6067),
/** /**
* Active spellbook (see enumID) * Active spellbook (see enumID)

View File

@@ -1127,5 +1127,7 @@ public class WidgetID
static class SeedVault static class SeedVault
{ {
static final int TITLE_CONTAINER = 2; static final int TITLE_CONTAINER = 2;
static final int ITEM_CONTAINER = 15;
static final int ITEM_TEXT = 16;
} }
} }

View File

@@ -752,7 +752,9 @@ public enum WidgetInfo
ITEMS_LOST_VALUE(WidgetID.ITEMS_KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.LOST_ITEMS_VALUE), ITEMS_LOST_VALUE(WidgetID.ITEMS_KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.LOST_ITEMS_VALUE),
ITEMS_KEPT_MAX(WidgetID.ITEMS_KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.MAX_ITEMS_KEPT_ON_DEATH), ITEMS_KEPT_MAX(WidgetID.ITEMS_KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.MAX_ITEMS_KEPT_ON_DEATH),
SEED_VAULT_TITLE_CONTAINER(WidgetID.SEED_VAULT_GROUP_ID, WidgetID.SeedVault.TITLE_CONTAINER); SEED_VAULT_TITLE_CONTAINER(WidgetID.SEED_VAULT_GROUP_ID, WidgetID.SeedVault.TITLE_CONTAINER),
SEED_VAULT_ITEM_CONTAINER(WidgetID.SEED_VAULT_GROUP_ID, WidgetID.SeedVault.ITEM_CONTAINER),
SEED_VAULT_ITEM_TEXT(WidgetID.SEED_VAULT_GROUP_ID, WidgetID.SeedVault.ITEM_TEXT);
private final int groupId; private final int groupId;
private final int childId; private final int childId;

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2019 Abex
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import net.runelite.client.ui.FontManager;
/**
* Loads some slow to initialize classes (hopefully) before they are needed to streamline client startup
*/
@SuppressWarnings({"ResultOfMethodCallIgnored", "unused"})
class ClassPreloader
{
static void preload()
{
// This needs to enumerate the system fonts for some reason, and that takes a while
FontManager.getRunescapeSmallFont();
// This needs to load a timezone database that is mildly large
ZoneId.of("Europe/London");
// This just needs to call 20 different DateTimeFormatter constructors, which are slow
Object unused = DateTimeFormatter.BASIC_ISO_DATE;
}
}

View File

@@ -38,200 +38,7 @@ import static net.runelite.api.NullObjectID.NULL_31823;
import static net.runelite.api.NullObjectID.NULL_31849; import static net.runelite.api.NullObjectID.NULL_31849;
import static net.runelite.api.NullObjectID.NULL_33327; import static net.runelite.api.NullObjectID.NULL_33327;
import static net.runelite.api.NullObjectID.NULL_33328; import static net.runelite.api.NullObjectID.NULL_33328;
import static net.runelite.api.ObjectID.A_WOODEN_LOG; import static net.runelite.api.ObjectID.*;
import static net.runelite.api.ObjectID.BALANCING_LEDGE_23548;
import static net.runelite.api.ObjectID.BIG_WINDOW;
import static net.runelite.api.ObjectID.BOULDER_27990;
import static net.runelite.api.ObjectID.BROKEN_FENCE;
import static net.runelite.api.ObjectID.BROKEN_FENCE_2618;
import static net.runelite.api.ObjectID.BROKEN_RAFT;
import static net.runelite.api.ObjectID.BROKEN_WALL_33344;
import static net.runelite.api.ObjectID.CASTLE_WALL;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_11948;
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_11949;
import static net.runelite.api.ObjectID.CREVICE_16465;
import static net.runelite.api.ObjectID.CREVICE_16539;
import static net.runelite.api.ObjectID.CREVICE_16543;
import static net.runelite.api.ObjectID.CREVICE_19043;
import static net.runelite.api.ObjectID.CREVICE_30198;
import static net.runelite.api.ObjectID.CREVICE_9739;
import static net.runelite.api.ObjectID.CREVICE_9740;
import static net.runelite.api.ObjectID.CROSSBOW_TREE_17062;
import static net.runelite.api.ObjectID.CRUMBLING_WALL_24222;
import static net.runelite.api.ObjectID.DARK_TUNNEL_10047;
import static net.runelite.api.ObjectID.DENSE_FOREST;
import static net.runelite.api.ObjectID.DENSE_FOREST_3938;
import static net.runelite.api.ObjectID.DENSE_FOREST_3939;
import static net.runelite.api.ObjectID.DENSE_FOREST_3998;
import static net.runelite.api.ObjectID.DENSE_FOREST_3999;
import static net.runelite.api.ObjectID.FALLEN_TREE_33192;
import static net.runelite.api.ObjectID.FENCE_16518;
import static net.runelite.api.ObjectID.GAP;
import static net.runelite.api.ObjectID.GAP_2831;
import static net.runelite.api.ObjectID.GAP_29326;
import static net.runelite.api.ObjectID.HOLE_16520;
import static net.runelite.api.ObjectID.HOLE_30966;
import static net.runelite.api.ObjectID.HOLE_31481;
import static net.runelite.api.ObjectID.HOLE_31482;
import static net.runelite.api.ObjectID.ICE_CHUNKS_31822;
import static net.runelite.api.ObjectID.ICE_CHUNKS_31990;
import static net.runelite.api.ObjectID.JUTTING_WALL_17002;
import static net.runelite.api.ObjectID.LADDER_30938;
import static net.runelite.api.ObjectID.LADDER_30939;
import static net.runelite.api.ObjectID.LADDER_30940;
import static net.runelite.api.ObjectID.LADDER_30941;
import static net.runelite.api.ObjectID.LEAVES;
import static net.runelite.api.ObjectID.LEAVES_3924;
import static net.runelite.api.ObjectID.LEAVES_3925;
import static net.runelite.api.ObjectID.LEDGE_33190;
import static net.runelite.api.ObjectID.LITTLE_BOULDER;
import static net.runelite.api.ObjectID.LOG_BALANCE_16540;
import static net.runelite.api.ObjectID.LOG_BALANCE_16541;
import static net.runelite.api.ObjectID.LOG_BALANCE_16542;
import static net.runelite.api.ObjectID.LOG_BALANCE_16546;
import static net.runelite.api.ObjectID.LOG_BALANCE_16547;
import static net.runelite.api.ObjectID.LOG_BALANCE_16548;
import static net.runelite.api.ObjectID.LOG_BALANCE_20882;
import static net.runelite.api.ObjectID.LOG_BALANCE_20884;
import static net.runelite.api.ObjectID.LOG_BALANCE_23274;
import static net.runelite.api.ObjectID.LOG_BALANCE_3929;
import static net.runelite.api.ObjectID.LOG_BALANCE_3930;
import static net.runelite.api.ObjectID.LOG_BALANCE_3931;
import static net.runelite.api.ObjectID.LOG_BALANCE_3932;
import static net.runelite.api.ObjectID.LOG_BALANCE_3933;
import static net.runelite.api.ObjectID.LOOSE_RAILING;
import static net.runelite.api.ObjectID.LOOSE_RAILING_2186;
import static net.runelite.api.ObjectID.LOOSE_RAILING_28849;
import static net.runelite.api.ObjectID.LOW_FENCE;
import static net.runelite.api.ObjectID.MONKEYBARS_23566;
import static net.runelite.api.ObjectID.MONKEYBARS_23567;
import static net.runelite.api.ObjectID.MYSTERIOUS_PIPE;
import static net.runelite.api.ObjectID.OBSTACLE;
import static net.runelite.api.ObjectID.OBSTACLE_30767;
import static net.runelite.api.ObjectID.OBSTACLE_30962;
import static net.runelite.api.ObjectID.OBSTACLE_30964;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_16509;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_16511;
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23140;
import static net.runelite.api.ObjectID.ORNATE_RAILING;
import static net.runelite.api.ObjectID.ORNATE_RAILING_17000;
import static net.runelite.api.ObjectID.PILE_OF_RUBBLE_23563;
import static net.runelite.api.ObjectID.PILE_OF_RUBBLE_23564;
import static net.runelite.api.ObjectID.PILLAR_31561;
import static net.runelite.api.ObjectID.PILLAR_31809;
import static net.runelite.api.ObjectID.PIPE_21727;
import static net.runelite.api.ObjectID.PIPE_21728;
import static net.runelite.api.ObjectID.ROCKS;
import static net.runelite.api.ObjectID.ROCKSLIDE_33184;
import static net.runelite.api.ObjectID.ROCKSLIDE_33185;
import static net.runelite.api.ObjectID.ROCKSLIDE_33191;
import static net.runelite.api.ObjectID.ROCKS_14106;
import static net.runelite.api.ObjectID.ROCKS_16464;
import static net.runelite.api.ObjectID.ROCKS_16514;
import static net.runelite.api.ObjectID.ROCKS_16515;
import static net.runelite.api.ObjectID.ROCKS_16521;
import static net.runelite.api.ObjectID.ROCKS_16522;
import static net.runelite.api.ObjectID.ROCKS_16523;
import static net.runelite.api.ObjectID.ROCKS_16524;
import static net.runelite.api.ObjectID.ROCKS_16534;
import static net.runelite.api.ObjectID.ROCKS_16535;
import static net.runelite.api.ObjectID.ROCKS_16545;
import static net.runelite.api.ObjectID.ROCKS_16549;
import static net.runelite.api.ObjectID.ROCKS_16550;
import static net.runelite.api.ObjectID.ROCKS_16998;
import static net.runelite.api.ObjectID.ROCKS_16999;
import static net.runelite.api.ObjectID.ROCKS_17042;
import static net.runelite.api.ObjectID.ROCKS_19849;
import static net.runelite.api.ObjectID.ROCKS_2231;
import static net.runelite.api.ObjectID.ROCKS_27984;
import static net.runelite.api.ObjectID.ROCKS_27985;
import static net.runelite.api.ObjectID.ROCKS_27987;
import static net.runelite.api.ObjectID.ROCKS_27988;
import static net.runelite.api.ObjectID.ROCKS_31757;
import static net.runelite.api.ObjectID.ROCKS_31758;
import static net.runelite.api.ObjectID.ROCKS_31759;
import static net.runelite.api.ObjectID.ROCKS_34396;
import static net.runelite.api.ObjectID.ROCKS_34397;
import static net.runelite.api.ObjectID.ROCKS_34741;
import static net.runelite.api.ObjectID.ROCKS_3748;
import static net.runelite.api.ObjectID.ROCKS_3790;
import static net.runelite.api.ObjectID.ROCKS_3791;
import static net.runelite.api.ObjectID.ROCKS_3803;
import static net.runelite.api.ObjectID.ROCKS_3804;
import static net.runelite.api.ObjectID.ROCKS_6673;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26400;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26401;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26402;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26404;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26405;
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26406;
import static net.runelite.api.ObjectID.ROCK_16115;
import static net.runelite.api.ObjectID.ROPESWING_23568;
import static net.runelite.api.ObjectID.ROPESWING_23569;
import static net.runelite.api.ObjectID.ROPE_ANCHOR;
import static net.runelite.api.ObjectID.ROPE_ANCHOR_30917;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21306;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21307;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21308;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21309;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21310;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21311;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21312;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21313;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21314;
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21315;
import static net.runelite.api.ObjectID.RUBBER_CAP_MUSHROOM;
import static net.runelite.api.ObjectID.SPIKEY_CHAIN;
import static net.runelite.api.ObjectID.SPIKEY_CHAIN_16538;
import static net.runelite.api.ObjectID.STAIRS_31485;
import static net.runelite.api.ObjectID.STEPPING_STONES;
import static net.runelite.api.ObjectID.STEPPING_STONES_23646;
import static net.runelite.api.ObjectID.STEPPING_STONES_23647;
import static net.runelite.api.ObjectID.STEPPING_STONE_10663;
import static net.runelite.api.ObjectID.STEPPING_STONE_11768;
import static net.runelite.api.ObjectID.STEPPING_STONE_13504;
import static net.runelite.api.ObjectID.STEPPING_STONE_14917;
import static net.runelite.api.ObjectID.STEPPING_STONE_14918;
import static net.runelite.api.ObjectID.STEPPING_STONE_16466;
import static net.runelite.api.ObjectID.STEPPING_STONE_16513;
import static net.runelite.api.ObjectID.STEPPING_STONE_16533;
import static net.runelite.api.ObjectID.STEPPING_STONE_19040;
import static net.runelite.api.ObjectID.STEPPING_STONE_19042;
import static net.runelite.api.ObjectID.STEPPING_STONE_21738;
import static net.runelite.api.ObjectID.STEPPING_STONE_21739;
import static net.runelite.api.ObjectID.STEPPING_STONE_29728;
import static net.runelite.api.ObjectID.STEPPING_STONE_29729;
import static net.runelite.api.ObjectID.STEPPING_STONE_29730;
import static net.runelite.api.ObjectID.STEPPING_STONE_5948;
import static net.runelite.api.ObjectID.STEPPING_STONE_5949;
import static net.runelite.api.ObjectID.STEPS;
import static net.runelite.api.ObjectID.STEPS_29993;
import static net.runelite.api.ObjectID.STICKS;
import static net.runelite.api.ObjectID.STILE;
import static net.runelite.api.ObjectID.STILE_12982;
import static net.runelite.api.ObjectID.STRANGE_FLOOR;
import static net.runelite.api.ObjectID.STRANGE_FLOOR_16544;
import static net.runelite.api.ObjectID.STRONG_TREE_17074;
import static net.runelite.api.ObjectID.TIGHTGAP;
import static net.runelite.api.ObjectID.TRELLIS_20056;
import static net.runelite.api.ObjectID.TRIPWIRE;
import static net.runelite.api.ObjectID.TUNNEL_30174;
import static net.runelite.api.ObjectID.TUNNEL_30175;
import static net.runelite.api.ObjectID.TUNNEL_30959;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16528;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16529;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16530;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_19032;
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_19036;
import static net.runelite.api.ObjectID.VINE_26880;
import static net.runelite.api.ObjectID.VINE_26882;
import static net.runelite.api.ObjectID.WALL_17047;
import static net.runelite.api.ObjectID.WALL_17049;
import static net.runelite.api.ObjectID.WALL_17050;
import static net.runelite.api.ObjectID.WEATHERED_WALL;
import static net.runelite.api.ObjectID.WEATHERED_WALL_16526;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
@Getter @Getter
@@ -347,6 +154,7 @@ public enum AgilityShortcut
YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567), YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567),
PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null, WEATHERED_WALL, WEATHERED_WALL_16526), PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null, WEATHERED_WALL, WEATHERED_WALL_16526),
ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515), ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515),
ELVEN_OVERPASS_CLIFF_SCRAMBLE_PRIFDDINAS(59, "Rocks", new WorldPoint(3369, 6052, 0), ROCKS_16514, ROCKS_16515),
WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406), WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
WILDERNESS_GWD_CLIMB_WEST(60, "Rocks", new WorldPoint(2928, 3760, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406), WILDERNESS_GWD_CLIMB_WEST(60, "Rocks", new WorldPoint(2928, 3760, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
MOS_LEHARMLESS_STEPPING_STONE(60, "Stepping Stone", new WorldPoint(3710, 2970, 0), STEPPING_STONE_19042), MOS_LEHARMLESS_STEPPING_STONE(60, "Stepping Stone", new WorldPoint(3710, 2970, 0), STEPPING_STONE_19042),
@@ -368,6 +176,7 @@ public enum AgilityShortcut
HEROES_GUILD_TUNNEL_WEST(67, "Crevice", new WorldPoint(2913, 9895, 0), CREVICE_9739, CREVICE_9740), HEROES_GUILD_TUNNEL_WEST(67, "Crevice", new WorldPoint(2913, 9895, 0), CREVICE_9739, CREVICE_9740),
YANILLE_DUNGEON_RUBBLE_CLIMB(67, "Pile of Rubble", null, PILE_OF_RUBBLE_23563, PILE_OF_RUBBLE_23564), YANILLE_DUNGEON_RUBBLE_CLIMB(67, "Pile of Rubble", null, PILE_OF_RUBBLE_23563, PILE_OF_RUBBLE_23564),
ELVEN_OVERPASS_MEDIUM_CLIFF(68, "Rocks", new WorldPoint(2337, 3288, 0), ROCKS_16514, ROCKS_16515), ELVEN_OVERPASS_MEDIUM_CLIFF(68, "Rocks", new WorldPoint(2337, 3288, 0), ROCKS_16514, ROCKS_16515),
ELVEN_OVERPASS_MEDIUM_CLIFF_PRIFDDINAS(68, "Rocks", new WorldPoint(3361, 6040, 0), ROCKS_16514, ROCKS_16515),
WEISS_OBSTACLES(68, "Shortcut", null, LITTLE_BOULDER, ROCKSLIDE_33184, ROCKSLIDE_33185, NULL_33327, NULL_33328, LEDGE_33190, ROCKSLIDE_33191, FALLEN_TREE_33192), WEISS_OBSTACLES(68, "Shortcut", null, LITTLE_BOULDER, ROCKSLIDE_33184, ROCKSLIDE_33185, NULL_33327, NULL_33328, LEDGE_33190, ROCKSLIDE_33191, FALLEN_TREE_33192),
ARCEUUS_ESSENSE_NORTH(69, "Rock Climb", new WorldPoint(1761, 3873, 0), ROCKS_34741), ARCEUUS_ESSENSE_NORTH(69, "Rock Climb", new WorldPoint(1761, 3873, 0), ROCKS_34741),
TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509), TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509),
@@ -388,14 +197,19 @@ public enum AgilityShortcut
REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561), REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561),
REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561), REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561),
ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663), ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663),
SHILO_VILLAGE_STEPPING_STONES(77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466), SHILO_VILLAGE_STEPPING_STONES( 77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466),
IORWERTHS_DUNGEON_NORTHERN_SHORTCUT_EAST(78, "Tight Gap", new WorldPoint(3221, 12441, 0), TIGHT_GAP),
IORWERTHS_DUNGEON_NORTHERN_SHORTCUT_WEST(78, "Tight Gap", new WorldPoint(3215, 12441, 0), TIGHT_GAP_36693),
KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886), KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886),
TAVERLEY_DUNGEON_SPIKED_BLADES(80, "Strange Floor", new WorldPoint(2877, 9813, 0), STRANGE_FLOOR), TAVERLEY_DUNGEON_SPIKED_BLADES(80, "Strange Floor", new WorldPoint(2877, 9813, 0), STRANGE_FLOOR),
SLAYER_DUNGEON_CHASM_JUMP(81, "Spiked Blades", new WorldPoint(2770, 10003, 0), STRANGE_FLOOR_16544), SLAYER_DUNGEON_CHASM_JUMP(81, "Spiked Blades", new WorldPoint(2770, 10003, 0), STRANGE_FLOOR_16544),
LAVA_MAZE_NORTH_JUMP(82, "Stepping Stone", new WorldPoint(3092, 3880, 0), STEPPING_STONE_14917), LAVA_MAZE_NORTH_JUMP(82, "Stepping Stone", new WorldPoint(3092, 3880, 0), STEPPING_STONE_14917),
BRIMHAVEN_DUNGEON_EAST_STEPPING_STONES_NORTH(83, "Stepping Stones", new WorldPoint(2685, 9547, 0), STEPPING_STONE_19040), BRIMHAVEN_DUNGEON_EAST_STEPPING_STONES_NORTH(83, "Stepping Stones", new WorldPoint(2685, 9547, 0), STEPPING_STONE_19040),
BRIMHAVEN_DUNGEON_EAST_STEPPING_STONES_SOUTH(83, "Stepping Stones", new WorldPoint(2693, 9529, 0), STEPPING_STONE_19040), BRIMHAVEN_DUNGEON_EAST_STEPPING_STONES_SOUTH(83, "Stepping Stones", new WorldPoint(2693, 9529, 0), STEPPING_STONE_19040),
IORWERTHS_DUNGEON_SOUTHERN_SHORTCUT_EAST(84, "Tight Gap", new WorldPoint(3241, 12420, 0), TIGHT_GAP_36694),
IORWERTHS_DUNGEON_SOUTHERN_SHORTCUT_WEST(84, "Tight Gap", new WorldPoint(3231, 12420, 0), TIGHT_GAP_36695),
ELVEN_ADVANCED_CLIFF_SCRAMBLE(85, "Rocks", new WorldPoint(2337, 3253, 0), ROCKS_16514, ROCKS_16514), ELVEN_ADVANCED_CLIFF_SCRAMBLE(85, "Rocks", new WorldPoint(2337, 3253, 0), ROCKS_16514, ROCKS_16514),
ELVEN_ADVANCED_CLIFF_SCRAMBLE_PRIFDDINAS(85, "Rocks", new WorldPoint(3361, 6005, 0), ROCKS_16514, ROCKS_16514),
KALPHITE_WALL(86, "Crevice", new WorldPoint(3214, 9508, 0), CREVICE_16465), KALPHITE_WALL(86, "Crevice", new WorldPoint(3214, 9508, 0), CREVICE_16465),
BRIMHAVEN_DUNGEON_VINE_EAST(87, "Vine", new WorldPoint(2672, 9582, 0), VINE_26880, VINE_26882), BRIMHAVEN_DUNGEON_VINE_EAST(87, "Vine", new WorldPoint(2672, 9582, 0), VINE_26880, VINE_26882),
BRIMHAVEN_DUNGEON_VINE_WEST(87, "Vine", new WorldPoint(2606, 9584, 0), VINE_26880, VINE_26882), BRIMHAVEN_DUNGEON_VINE_WEST(87, "Vine", new WorldPoint(2606, 9584, 0), VINE_26880, VINE_26882),

View File

@@ -47,6 +47,7 @@ enum Courses
SEERS(570.0, 435, 10806), SEERS(570.0, 435, 10806),
POLLNIVNEACH(890.0, 540, 13358), POLLNIVNEACH(890.0, 540, 13358),
RELLEKA(780.0, 475, 10553), RELLEKA(780.0, 475, 10553),
PRIFDDINAS(1199.0, 968, 12895),
ARDOUGNE(793.0, 529, 10547); ARDOUGNE(793.0, 529, 10547);
private final static Map<Integer, Courses> coursesByRegion; private final static Map<Integer, Courses> coursesByRegion;

View File

@@ -91,7 +91,12 @@ class Obstacles
NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980, NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980,
// Werewolf // Werewolf
STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE, STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE,
ZIP_LINE_11645, ZIP_LINE_11646 ZIP_LINE_11645, ZIP_LINE_11646,
// Prifddinas
LADDER_36221, TIGHTROPE_36225, CHIMNEY_36227, ROOF_EDGE, DARK_HOLE_36229, LADDER_36231, ROPE_BRIDGE_36233,
TIGHTROPE_36234, ROPE_BRIDGE_36235, TIGHTROPE_36236, TIGHTROPE_36237, DARK_HOLE_36238,
// Prifddinas portals
NULL_36241, NULL_36242, NULL_36243, NULL_36244, NULL_36245, NULL_36246
); );
static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS; static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS;

View File

@@ -58,7 +58,8 @@ enum Boss
KALPHITE_QUEEN(NpcID.KALPHITE_QUEEN_965, 30, ChronoUnit.SECONDS, ItemID.KALPHITE_PRINCESS), KALPHITE_QUEEN(NpcID.KALPHITE_QUEEN_965, 30, ChronoUnit.SECONDS, ItemID.KALPHITE_PRINCESS),
DUSK(NpcID.DUSK_7889, 2, ChronoUnit.MINUTES, ItemID.NOON), DUSK(NpcID.DUSK_7889, 2, ChronoUnit.MINUTES, ItemID.NOON),
ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA), ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA),
SARACHNIS(NpcID.SARACHNIS, 30, ChronoUnit.SECONDS, ItemID.SRARACHA); SARACHNIS(NpcID.SARACHNIS, 30, ChronoUnit.SECONDS, ItemID.SRARACHA),
ZALCANO(NpcID.ZALCANO_9050, 21600, ChronoUnit.MILLIS, ItemID.SMOLCANO);
private static final Map<Integer, Boss> bosses; private static final Map<Integer, Boss> bosses;

View File

@@ -87,12 +87,12 @@ import org.apache.commons.text.WordUtils;
@Slf4j @Slf4j
public class ChatCommandsPlugin extends Plugin public class ChatCommandsPlugin extends Plugin
{ {
private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (.+) (?:kill|harvest) count is: <col=ff0000>(\\d+)</col>"); private static final Pattern KILLCOUNT_PATTERN = Pattern.compile("Your (.+) (?:kill|harvest|lap) count is: <col=ff0000>(\\d+)</col>");
private static final Pattern RAIDS_PATTERN = Pattern.compile("Your completed (.+) count is: <col=ff0000>(\\d+)</col>"); private static final Pattern RAIDS_PATTERN = Pattern.compile("Your completed (.+) count is: <col=ff0000>(\\d+)</col>");
private static final Pattern WINTERTODT_PATTERN = Pattern.compile("Your subdued Wintertodt count is: <col=ff0000>(\\d+)</col>"); private static final Pattern WINTERTODT_PATTERN = Pattern.compile("Your subdued Wintertodt count is: <col=ff0000>(\\d+)</col>");
private static final Pattern BARROWS_PATTERN = Pattern.compile("Your Barrows chest count is: <col=ff0000>(\\d+)</col>"); private static final Pattern BARROWS_PATTERN = Pattern.compile("Your Barrows chest count is: <col=ff0000>(\\d+)</col>");
private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("Fight duration: <col=ff0000>[0-9:]+</col>. Personal best: ([0-9:]+)"); private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?:Fight|Lap) duration: <col=ff0000>[0-9:]+</col>. Personal best: ([0-9:]+)");
private static final Pattern NEW_PB_PATTERN = Pattern.compile("Fight duration: <col=ff0000>([0-9:]+)</col> \\(new personal best\\)"); private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?:Fight|Lap) duration: <col=ff0000>([0-9:]+)</col> \\(new personal best\\)");
private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?"); private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?");
private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?"); private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?");
private static final String TOTAL_LEVEL_COMMAND_STRING = "!total"; private static final String TOTAL_LEVEL_COMMAND_STRING = "!total";
@@ -1377,6 +1377,11 @@ public class ChatCommandsPlugin extends Plugin
case "raids 2": case "raids 2":
return "Theatre of Blood"; return "Theatre of Blood";
// agility course
case "prif":
case "prifddinas":
return "Prifddinas Agility Course";
default: default:
return WordUtils.capitalize(boss); return WordUtils.capitalize(boss);
} }

View File

@@ -25,6 +25,7 @@
*/ */
package net.runelite.client.plugins.chatfilter; package net.runelite.client.plugins.chatfilter;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.util.ArrayList; import java.util.ArrayList;
@@ -66,7 +67,7 @@ public class ChatFilterPlugin extends Plugin
private static final String CENSOR_MESSAGE = "Hey, everyone, I just tried to say something very silly!"; private static final String CENSOR_MESSAGE = "Hey, everyone, I just tried to say something very silly!";
private final JagexPrintableCharMatcher jagexPrintableCharMatcher = new JagexPrintableCharMatcher(); private final CharMatcher jagexPrintableCharMatcher = Text.JAGEX_PRINTABLE_CHAR_MATCHER;
private final List<Pattern> filteredPatterns = new ArrayList<>(); private final List<Pattern> filteredPatterns = new ArrayList<>();
@Inject @Inject

View File

@@ -162,7 +162,8 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
new AnagramClue("RAIN COVE", "Veronica", new WorldPoint(3110, 3330, 0), "Outside Draynor Manor"), new AnagramClue("RAIN COVE", "Veronica", new WorldPoint(3110, 3330, 0), "Outside Draynor Manor"),
new AnagramClue("RUG DETER", "Gertrude", new WorldPoint(3151, 3412, 0), "West of Varrock, south of the Cooks' Guild"), new AnagramClue("RUG DETER", "Gertrude", new WorldPoint(3151, 3412, 0), "West of Varrock, south of the Cooks' Guild"),
new AnagramClue("SIR SHARE RED", "Hairdresser", new WorldPoint(2944, 3381, 0), "Western Falador"), new AnagramClue("SIR SHARE RED", "Hairdresser", new WorldPoint(2944, 3381, 0), "Western Falador"),
new AnagramClue("TAUNT ROOF", "Fortunato", new WorldPoint(3080, 3250, 0), "Draynor Village Market") new AnagramClue("TAUNT ROOF", "Fortunato", new WorldPoint(3080, 3250, 0), "Draynor Village Market"),
new AnagramClue("HICK JET", "Jethick", new WorldPoint(2541, 3305, 0), "West Ardougne", "38")
); );
private final String text; private final String text;

View File

@@ -266,7 +266,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
new CrypticClue("Thanks, Grandma!", "Tynan", new WorldPoint(1836, 3786, 0), "Tynan can be found in the north-east corner of Port Piscarilius."), new CrypticClue("Thanks, Grandma!", "Tynan", new WorldPoint(1836, 3786, 0), "Tynan can be found in the north-east corner of Port Piscarilius."),
new CrypticClue("In a town where everyone has perfect vision, seek some locked drawers in a house that sits opposite a workshop.", "Chicken", DRAWERS_25766, new WorldPoint(2709, 3478, 0), "The Seers' Village house south of the Elemental Workshop entrance. Kill any Chicken to obtain a key."), new CrypticClue("In a town where everyone has perfect vision, seek some locked drawers in a house that sits opposite a workshop.", "Chicken", DRAWERS_25766, new WorldPoint(2709, 3478, 0), "The Seers' Village house south of the Elemental Workshop entrance. Kill any Chicken to obtain a key."),
new CrypticClue("The treasure is buried in a small building full of bones. Here is a hint: it's not near a graveyard.", new WorldPoint(3356, 3507, 0), "In the western building near the Limestone quarry east of Varrock. Dig south of the box of bones in the smaller building."), new CrypticClue("The treasure is buried in a small building full of bones. Here is a hint: it's not near a graveyard.", new WorldPoint(3356, 3507, 0), "In the western building near the Limestone quarry east of Varrock. Dig south of the box of bones in the smaller building."),
new CrypticClue("Search the crates in East Ardougne's general store.", CRATE_357, new WorldPoint(2615, 3291, 0), "Located south of the Ardounge church."), new CrypticClue("Search the crates in East Ardougne's general store.", CRATE_357, new WorldPoint(2615, 3291, 0), "Located south of the Ardougne church."),
new CrypticClue("Come brave adventurer, your sense is on fire. If you talk to me, it's an old god you desire.", "Viggora", null, "Speak to Viggora"), new CrypticClue("Come brave adventurer, your sense is on fire. If you talk to me, it's an old god you desire.", "Viggora", null, "Speak to Viggora"),
new CrypticClue("2 musical birds. Dig in front of the spinning light.", new WorldPoint(2671, 10396, 0), "Dig in front of the spinning light in Ping and Pong's room inside the Iceberg"), new CrypticClue("2 musical birds. Dig in front of the spinning light.", new WorldPoint(2671, 10396, 0), "Dig in front of the spinning light in Ping and Pong's room inside the Iceberg"),
new CrypticClue("Search the wheelbarrow in Rimmington mine.", WHEELBARROW_9625, new WorldPoint(2978, 3239, 0), "The Rimmington mining site is located north of Rimmington."), new CrypticClue("Search the wheelbarrow in Rimmington mine.", WHEELBARROW_9625, new WorldPoint(2978, 3239, 0), "The Rimmington mining site is located north of Rimmington."),

View File

@@ -42,7 +42,9 @@ import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import static net.runelite.api.widgets.WidgetInfo.SEED_VAULT_ITEM_CONTAINER;
import static net.runelite.api.widgets.WidgetInfo.TO_CHILD; import static net.runelite.api.widgets.WidgetInfo.TO_CHILD;
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP; import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
import net.runelite.api.widgets.WidgetItem; import net.runelite.api.widgets.WidgetItem;
@@ -335,6 +337,24 @@ public class ExaminePlugin extends Plugin
return new int[]{widgetItem.getItemQuantity(), widgetItem.getItemId()}; return new int[]{widgetItem.getItemQuantity(), widgetItem.getItemId()};
} }
} }
else if (WidgetID.SEED_VAULT_GROUP_ID == widgetGroup)
{
Widget[] children = client.getWidget(SEED_VAULT_ITEM_CONTAINER).getDynamicChildren();
if (actionParam < children.length)
{
Widget widgetItem = children[actionParam];
return new int[]{widgetItem.getItemQuantity(), widgetItem.getItemId()};
}
}
else if (WidgetID.SEED_VAULT_INVENTORY_GROUP_ID == widgetGroup)
{
Widget[] children = widget.getDynamicChildren();
if (actionParam < children.length)
{
Widget widgetItem = children[actionParam];
return new int[]{widgetItem.getItemQuantity(), widgetItem.getItemId()};
}
}
return null; return null;
} }

View File

@@ -25,6 +25,8 @@
package net.runelite.client.plugins.grounditems; package net.runelite.client.plugins.grounditems;
import java.time.Instant; import java.time.Instant;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.Value; import lombok.Value;
@@ -51,6 +53,16 @@ class GroundItem
private boolean isAlwaysPrivate; private boolean isAlwaysPrivate;
private boolean isOwnedByPlayer; private boolean isOwnedByPlayer;
private Instant droppedInstant; private Instant droppedInstant;
@Nonnull
private LootType lootType;
/**
* Is dropped by me
*/
private boolean isDropped;
@Nullable
private Instant spawnTime;
int getHaPrice() int getHaPrice()
{ {
@@ -62,6 +74,11 @@ class GroundItem
return gePrice * quantity; return gePrice * quantity;
} }
boolean isMine()
{
return lootType != LootType.UNKNOWN;
}
@Value @Value
static class GroundItemKey static class GroundItemKey
{ {

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.grounditems;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.EvictingQueue;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Color; import java.awt.Color;
import java.awt.Rectangle; import java.awt.Rectangle;
@@ -40,6 +41,7 @@ import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -72,6 +74,7 @@ import net.runelite.api.events.ItemDespawned;
import net.runelite.api.events.ItemQuantityChanged; import net.runelite.api.events.ItemQuantityChanged;
import net.runelite.api.events.ItemSpawned; import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
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;
@@ -170,6 +173,7 @@ public class GroundItemsPlugin extends Plugin
private EventBus eventBus; private EventBus eventBus;
private LoadingCache<String, Boolean> highlightedItems; private LoadingCache<String, Boolean> highlightedItems;
private LoadingCache<String, Boolean> hiddenItems; private LoadingCache<String, Boolean> hiddenItems;
private final Queue<Integer> droppedItemQueue = EvictingQueue.create(16); // recently dropped items
private Color defaultColor; private Color defaultColor;
private Color highlightedColor; private Color highlightedColor;
@@ -270,6 +274,7 @@ public class GroundItemsPlugin extends Plugin
eventBus.subscribe(ClientTick.class, this, this::onClientTick); eventBus.subscribe(ClientTick.class, this, this::onClientTick);
eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded); eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded);
eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged); eventBus.subscribe(FocusChanged.class, this, this::onFocusChanged);
eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
} }
private void onGameTick(GameTick event) private void onGameTick(GameTick event)
@@ -313,6 +318,7 @@ public class GroundItemsPlugin extends Plugin
if (existing != null) if (existing != null)
{ {
existing.setQuantity(existing.getQuantity() + groundItem.getQuantity()); existing.setQuantity(existing.getQuantity() + groundItem.getQuantity());
// The spawn time remains set at the oldest spawn
} }
boolean shouldNotify = !this.onlyShowLoot && this.highlightedColor.equals(getHighlighted( boolean shouldNotify = !this.onlyShowLoot && this.highlightedColor.equals(getHighlighted(
@@ -345,6 +351,10 @@ public class GroundItemsPlugin extends Plugin
else else
{ {
groundItem.setQuantity(groundItem.getQuantity() - item.getQuantity()); groundItem.setQuantity(groundItem.getQuantity() - item.getQuantity());
// When picking up an item when multiple stacks appear on the ground,
// it is not known which item is picked up, so we invalidate the spawn
// time
groundItem.setSpawnTime(null);
} }
} }
@@ -377,14 +387,14 @@ public class GroundItemsPlugin extends Plugin
); );
Collection<ItemStack> items = npcLootReceived.getItems(); Collection<ItemStack> items = npcLootReceived.getItems();
lootReceived(items); lootReceived(items, LootType.PVM);
lootNotifier(items); lootNotifier(items);
} }
private void onPlayerLootReceived(PlayerLootReceived playerLootReceived) private void onPlayerLootReceived(PlayerLootReceived playerLootReceived)
{ {
Collection<ItemStack> items = playerLootReceived.getItems(); Collection<ItemStack> items = playerLootReceived.getItems();
lootReceived(items); lootReceived(items, LootType.PVP);
lootNotifier(items); lootNotifier(items);
} }
@@ -534,7 +544,7 @@ public class GroundItemsPlugin extends Plugin
}).toArray(MenuEntry[]::new)); }).toArray(MenuEntry[]::new));
} }
private void lootReceived(Collection<ItemStack> items) private void lootReceived(Collection<ItemStack> items, LootType lootType)
{ {
for (ItemStack itemStack : items) for (ItemStack itemStack : items)
{ {
@@ -545,6 +555,7 @@ public class GroundItemsPlugin extends Plugin
{ {
groundItem.setMine(true); groundItem.setMine(true);
groundItem.setTicks(200); groundItem.setTicks(200);
groundItem.setLootType(lootType);
boolean shouldNotify = this.onlyShowLoot && this.highlightedColor.equals(getHighlighted( boolean shouldNotify = this.onlyShowLoot && this.highlightedColor.equals(getHighlighted(
groundItem.getName(), groundItem.getName(),
@@ -586,6 +597,7 @@ public class GroundItemsPlugin extends Plugin
durationMillis = NORMAL_DURATION_MILLIS; durationMillis = NORMAL_DURATION_MILLIS;
durationTicks = tile.getWorldLocation().equals(playerLocation) ? NORMAL_DURATION_TICKS * 2 : NORMAL_DURATION_TICKS; durationTicks = tile.getWorldLocation().equals(playerLocation) ? NORMAL_DURATION_TICKS * 2 : NORMAL_DURATION_TICKS;
} }
final boolean dropped = tile.getWorldLocation().equals(client.getLocalPlayer().getWorldLocation()) && droppedItemQueue.remove(itemId);
final GroundItem groundItem = GroundItem.builder() final GroundItem groundItem = GroundItem.builder()
.id(itemId) .id(itemId)
@@ -601,6 +613,9 @@ public class GroundItemsPlugin extends Plugin
.isAlwaysPrivate(client.isInInstancedRegion() || (!itemComposition.isTradeable() && realItemId != COINS)) .isAlwaysPrivate(client.isInInstancedRegion() || (!itemComposition.isTradeable() && realItemId != COINS))
.isOwnedByPlayer(tile.getWorldLocation().equals(playerLocation)) .isOwnedByPlayer(tile.getWorldLocation().equals(playerLocation))
.ticks(durationTicks) .ticks(durationTicks)
.lootType(LootType.UNKNOWN)
.isDropped(dropped)
.spawnTime(Instant.now())
.build(); .build();
@@ -925,6 +940,17 @@ public class GroundItemsPlugin extends Plugin
} }
} }
private void onMenuOptionClicked(MenuOptionClicked menuOptionClicked)
{
if (menuOptionClicked.getMenuAction() == MenuAction.ITEM_DROP)
{
int itemId = menuOptionClicked.getIdentifier();
// Keep a queue of recently dropped items to better detect
// item spawns that are drops
droppedItemQueue.add(itemId);
}
}
private void notifyHighlightedItem(GroundItem item) private void notifyHighlightedItem(GroundItem item)
{ {
final Player local = client.getLocalPlayer(); final Player local = client.getLocalPlayer();

View File

@@ -0,0 +1,32 @@
/*
* 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.grounditems;
enum LootType
{
UNKNOWN,
PVP,
PVM;
}

View File

@@ -97,9 +97,9 @@ class ItemPricesOverlay extends Overlay
switch (action) switch (action)
{ {
case ITEM_USE_ON_WIDGET: case ITEM_USE_ON_WIDGET:
if (!client.getSelectedSpellName().equalsIgnoreCase("high level alchemy") || !plugin.isShowAlchProfit()) if (!menuEntry.getTarget().contains("High Level Alchemy") || !plugin.isShowAlchProfit())
{ {
return null; break;
} }
case WIDGET_DEFAULT: case WIDGET_DEFAULT:
case ITEM_USE: case ITEM_USE:

View File

@@ -30,395 +30,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import static net.runelite.api.ItemID.ADMIRAL_PIE; import static net.runelite.api.ItemID.*;
import static net.runelite.api.ItemID.AGILITY_POTION1;
import static net.runelite.api.ItemID.AGILITY_POTION2;
import static net.runelite.api.ItemID.AGILITY_POTION3;
import static net.runelite.api.ItemID.AGILITY_POTION4;
import static net.runelite.api.ItemID.ANCHOVIES;
import static net.runelite.api.ItemID.ANCHOVY_PIZZA;
import static net.runelite.api.ItemID.ANGLERFISH;
import static net.runelite.api.ItemID.APPLE_PIE;
import static net.runelite.api.ItemID.ATTACK_POTION1;
import static net.runelite.api.ItemID.ATTACK_POTION2;
import static net.runelite.api.ItemID.ATTACK_POTION3;
import static net.runelite.api.ItemID.ATTACK_POTION4;
import static net.runelite.api.ItemID.AUTUMN_SQIRKJUICE;
import static net.runelite.api.ItemID.BAGUETTE;
import static net.runelite.api.ItemID.BAKED_POTATO;
import static net.runelite.api.ItemID.BANANA;
import static net.runelite.api.ItemID.BANDAGES;
import static net.runelite.api.ItemID.BASS;
import static net.runelite.api.ItemID.BASTION_POTION1;
import static net.runelite.api.ItemID.BASTION_POTION2;
import static net.runelite.api.ItemID.BASTION_POTION3;
import static net.runelite.api.ItemID.BASTION_POTION4;
import static net.runelite.api.ItemID.BATTLEMAGE_POTION1;
import static net.runelite.api.ItemID.BATTLEMAGE_POTION2;
import static net.runelite.api.ItemID.BATTLEMAGE_POTION3;
import static net.runelite.api.ItemID.BATTLEMAGE_POTION4;
import static net.runelite.api.ItemID.BAT_SHISH;
import static net.runelite.api.ItemID.BOTANICAL_PIE;
import static net.runelite.api.ItemID.BOTTLE_OF_WINE;
import static net.runelite.api.ItemID.BRAWK_FISH_3;
import static net.runelite.api.ItemID.BREAD;
import static net.runelite.api.ItemID.CABBAGE;
import static net.runelite.api.ItemID.CABBAGE_1967;
import static net.runelite.api.ItemID.CAKE;
import static net.runelite.api.ItemID.CAVE_EEL;
import static net.runelite.api.ItemID.CAVIAR;
import static net.runelite.api.ItemID.CHEESE;
import static net.runelite.api.ItemID.CHEESETOM_BATTA;
import static net.runelite.api.ItemID.CHILLI_CON_CARNE;
import static net.runelite.api.ItemID.CHILLI_POTATO;
import static net.runelite.api.ItemID.CHOCCHIP_CRUNCHIES;
import static net.runelite.api.ItemID.CHOCICE;
import static net.runelite.api.ItemID.CHOCOLATEY_MILK;
import static net.runelite.api.ItemID.CHOCOLATE_BAR;
import static net.runelite.api.ItemID.CHOCOLATE_BOMB;
import static net.runelite.api.ItemID.CHOCOLATE_CAKE;
import static net.runelite.api.ItemID.CHOCOLATE_SLICE;
import static net.runelite.api.ItemID.CHOC_SATURDAY;
import static net.runelite.api.ItemID.CHOPPED_ONION;
import static net.runelite.api.ItemID.CHOPPED_TOMATO;
import static net.runelite.api.ItemID.CHOPPED_TUNA;
import static net.runelite.api.ItemID.COATED_FROGS_LEGS;
import static net.runelite.api.ItemID.COD;
import static net.runelite.api.ItemID.COMBAT_POTION1;
import static net.runelite.api.ItemID.COMBAT_POTION2;
import static net.runelite.api.ItemID.COMBAT_POTION3;
import static net.runelite.api.ItemID.COMBAT_POTION4;
import static net.runelite.api.ItemID.COOKED_CHICKEN;
import static net.runelite.api.ItemID.COOKED_CHOMPY;
import static net.runelite.api.ItemID.COOKED_CRAB_MEAT;
import static net.runelite.api.ItemID.COOKED_FISHCAKE;
import static net.runelite.api.ItemID.COOKED_JUBBLY;
import static net.runelite.api.ItemID.COOKED_KARAMBWAN;
import static net.runelite.api.ItemID.COOKED_MEAT;
import static net.runelite.api.ItemID.COOKED_RABBIT;
import static net.runelite.api.ItemID.COOKED_SLIMY_EEL;
import static net.runelite.api.ItemID.COOKED_SWEETCORN;
import static net.runelite.api.ItemID.CURRY;
import static net.runelite.api.ItemID.DARK_CRAB;
import static net.runelite.api.ItemID.DEFENCE_POTION1;
import static net.runelite.api.ItemID.DEFENCE_POTION2;
import static net.runelite.api.ItemID.DEFENCE_POTION3;
import static net.runelite.api.ItemID.DEFENCE_POTION4;
import static net.runelite.api.ItemID.DRUNK_DRAGON;
import static net.runelite.api.ItemID.DWELLBERRIES;
import static net.runelite.api.ItemID.EASTER_EGG;
import static net.runelite.api.ItemID.EDIBLE_SEAWEED;
import static net.runelite.api.ItemID.EEL_SUSHI;
import static net.runelite.api.ItemID.EGG_AND_TOMATO;
import static net.runelite.api.ItemID.EGG_POTATO;
import static net.runelite.api.ItemID.ELDER_1;
import static net.runelite.api.ItemID.ELDER_1_20921;
import static net.runelite.api.ItemID.ELDER_2;
import static net.runelite.api.ItemID.ELDER_2_20922;
import static net.runelite.api.ItemID.ELDER_3;
import static net.runelite.api.ItemID.ELDER_3_20923;
import static net.runelite.api.ItemID.ELDER_4;
import static net.runelite.api.ItemID.ELDER_4_20924;
import static net.runelite.api.ItemID.ELDER_POTION_1;
import static net.runelite.api.ItemID.ELDER_POTION_2;
import static net.runelite.api.ItemID.ELDER_POTION_3;
import static net.runelite.api.ItemID.ELDER_POTION_4;
import static net.runelite.api.ItemID.ENERGY_POTION1;
import static net.runelite.api.ItemID.ENERGY_POTION2;
import static net.runelite.api.ItemID.ENERGY_POTION3;
import static net.runelite.api.ItemID.ENERGY_POTION4;
import static net.runelite.api.ItemID.FAT_SNAIL_MEAT;
import static net.runelite.api.ItemID.FIELD_RATION;
import static net.runelite.api.ItemID.FILLETS;
import static net.runelite.api.ItemID.FINGERS;
import static net.runelite.api.ItemID.FISHING_POTION1;
import static net.runelite.api.ItemID.FISHING_POTION2;
import static net.runelite.api.ItemID.FISHING_POTION3;
import static net.runelite.api.ItemID.FISHING_POTION4;
import static net.runelite.api.ItemID.FISH_PIE;
import static net.runelite.api.ItemID.FRIED_MUSHROOMS;
import static net.runelite.api.ItemID.FRIED_ONIONS;
import static net.runelite.api.ItemID.FROGBURGER;
import static net.runelite.api.ItemID.FROGSPAWN_GUMBO;
import static net.runelite.api.ItemID.FROG_SPAWN;
import static net.runelite.api.ItemID.FRUIT_BATTA;
import static net.runelite.api.ItemID.FRUIT_BLAST;
import static net.runelite.api.ItemID.GARDEN_PIE;
import static net.runelite.api.ItemID.GIANT_CARP;
import static net.runelite.api.ItemID.GIRAL_BAT_2;
import static net.runelite.api.ItemID.GOUT_TUBER;
import static net.runelite.api.ItemID.GREEN_GLOOP_SOUP;
import static net.runelite.api.ItemID.GRUBS__LA_MODE;
import static net.runelite.api.ItemID.GUANIC_BAT_0;
import static net.runelite.api.ItemID.GUTHIX_REST1;
import static net.runelite.api.ItemID.GUTHIX_REST2;
import static net.runelite.api.ItemID.GUTHIX_REST3;
import static net.runelite.api.ItemID.GUTHIX_REST4;
import static net.runelite.api.ItemID.HALF_AN_ADMIRAL_PIE;
import static net.runelite.api.ItemID.HALF_AN_APPLE_PIE;
import static net.runelite.api.ItemID.HALF_A_BOTANICAL_PIE;
import static net.runelite.api.ItemID.HALF_A_FISH_PIE;
import static net.runelite.api.ItemID.HALF_A_GARDEN_PIE;
import static net.runelite.api.ItemID.HALF_A_MEAT_PIE;
import static net.runelite.api.ItemID.HALF_A_MUSHROOM_PIE;
import static net.runelite.api.ItemID.HALF_A_REDBERRY_PIE;
import static net.runelite.api.ItemID.HALF_A_SUMMER_PIE;
import static net.runelite.api.ItemID.HALF_A_WILD_PIE;
import static net.runelite.api.ItemID.HERRING;
import static net.runelite.api.ItemID.HUNTER_POTION1;
import static net.runelite.api.ItemID.HUNTER_POTION2;
import static net.runelite.api.ItemID.HUNTER_POTION3;
import static net.runelite.api.ItemID.HUNTER_POTION4;
import static net.runelite.api.ItemID.IMBUED_HEART;
import static net.runelite.api.ItemID.JANGERBERRIES;
import static net.runelite.api.ItemID.JUG_OF_WINE;
import static net.runelite.api.ItemID.KODAI_1;
import static net.runelite.api.ItemID.KODAI_1_20945;
import static net.runelite.api.ItemID.KODAI_2;
import static net.runelite.api.ItemID.KODAI_2_20946;
import static net.runelite.api.ItemID.KODAI_3;
import static net.runelite.api.ItemID.KODAI_3_20947;
import static net.runelite.api.ItemID.KODAI_4;
import static net.runelite.api.ItemID.KODAI_4_20948;
import static net.runelite.api.ItemID.KODAI_POTION_1;
import static net.runelite.api.ItemID.KODAI_POTION_2;
import static net.runelite.api.ItemID.KODAI_POTION_3;
import static net.runelite.api.ItemID.KODAI_POTION_4;
import static net.runelite.api.ItemID.KRYKET_BAT_4;
import static net.runelite.api.ItemID.KYREN_FISH_6;
import static net.runelite.api.ItemID.LAVA_EEL;
import static net.runelite.api.ItemID.LECKISH_FISH_2;
import static net.runelite.api.ItemID.LEMON;
import static net.runelite.api.ItemID.LEMON_CHUNKS;
import static net.runelite.api.ItemID.LEMON_SLICES;
import static net.runelite.api.ItemID.LIME;
import static net.runelite.api.ItemID.LIME_CHUNKS;
import static net.runelite.api.ItemID.LIME_SLICES;
import static net.runelite.api.ItemID.LOACH;
import static net.runelite.api.ItemID.LOBSTER;
import static net.runelite.api.ItemID.MACKEREL;
import static net.runelite.api.ItemID.MAGIC_ESSENCE1;
import static net.runelite.api.ItemID.MAGIC_ESSENCE2;
import static net.runelite.api.ItemID.MAGIC_ESSENCE3;
import static net.runelite.api.ItemID.MAGIC_ESSENCE4;
import static net.runelite.api.ItemID.MAGIC_POTION1;
import static net.runelite.api.ItemID.MAGIC_POTION2;
import static net.runelite.api.ItemID.MAGIC_POTION3;
import static net.runelite.api.ItemID.MAGIC_POTION4;
import static net.runelite.api.ItemID.MANTA_RAY;
import static net.runelite.api.ItemID.MEAT_PIE;
import static net.runelite.api.ItemID.MEAT_PIZZA;
import static net.runelite.api.ItemID.MINT_CAKE;
import static net.runelite.api.ItemID.MONKFISH;
import static net.runelite.api.ItemID.MOONLIGHT_MEAD;
import static net.runelite.api.ItemID.MURNG_BAT_5;
import static net.runelite.api.ItemID.MUSHROOMS;
import static net.runelite.api.ItemID.MUSHROOM_PIE;
import static net.runelite.api.ItemID.MUSHROOM_POTATO;
import static net.runelite.api.ItemID.MUSHROOM__ONION;
import static net.runelite.api.ItemID.MYCIL_FISH_4;
import static net.runelite.api.ItemID.ONION;
import static net.runelite.api.ItemID.ORANGE;
import static net.runelite.api.ItemID.ORANGE_CHUNKS;
import static net.runelite.api.ItemID.ORANGE_SLICES;
import static net.runelite.api.ItemID.OVERLOAD_1;
import static net.runelite.api.ItemID.OVERLOAD_1_20985;
import static net.runelite.api.ItemID.OVERLOAD_1_20989;
import static net.runelite.api.ItemID.OVERLOAD_1_20993;
import static net.runelite.api.ItemID.OVERLOAD_2;
import static net.runelite.api.ItemID.OVERLOAD_2_20986;
import static net.runelite.api.ItemID.OVERLOAD_2_20990;
import static net.runelite.api.ItemID.OVERLOAD_2_20994;
import static net.runelite.api.ItemID.OVERLOAD_3;
import static net.runelite.api.ItemID.OVERLOAD_3_20987;
import static net.runelite.api.ItemID.OVERLOAD_3_20991;
import static net.runelite.api.ItemID.OVERLOAD_3_20995;
import static net.runelite.api.ItemID.OVERLOAD_4;
import static net.runelite.api.ItemID.OVERLOAD_4_20988;
import static net.runelite.api.ItemID.OVERLOAD_4_20992;
import static net.runelite.api.ItemID.OVERLOAD_4_20996;
import static net.runelite.api.ItemID.PAPAYA_FRUIT;
import static net.runelite.api.ItemID.PEACH;
import static net.runelite.api.ItemID.PHLUXIA_BAT_3;
import static net.runelite.api.ItemID.PIKE;
import static net.runelite.api.ItemID.PINEAPPLE_CHUNKS;
import static net.runelite.api.ItemID.PINEAPPLE_PIZZA;
import static net.runelite.api.ItemID.PINEAPPLE_PUNCH;
import static net.runelite.api.ItemID.PINEAPPLE_RING;
import static net.runelite.api.ItemID.PLAIN_PIZZA;
import static net.runelite.api.ItemID.POISON_KARAMBWAN;
import static net.runelite.api.ItemID.POTATO;
import static net.runelite.api.ItemID.POTATO_WITH_BUTTER;
import static net.runelite.api.ItemID.POTATO_WITH_CHEESE;
import static net.runelite.api.ItemID.POT_OF_CREAM;
import static net.runelite.api.ItemID.PRAEL_BAT_1;
import static net.runelite.api.ItemID.PRAYER_POTION1;
import static net.runelite.api.ItemID.PRAYER_POTION2;
import static net.runelite.api.ItemID.PRAYER_POTION3;
import static net.runelite.api.ItemID.PRAYER_POTION4;
import static net.runelite.api.ItemID.PREMADE_CHOC_BOMB;
import static net.runelite.api.ItemID.PREMADE_CHOC_SDY;
import static net.runelite.api.ItemID.PREMADE_CH_CRUNCH;
import static net.runelite.api.ItemID.PREMADE_CT_BATTA;
import static net.runelite.api.ItemID.PREMADE_DR_DRAGON;
import static net.runelite.api.ItemID.PREMADE_FRT_BATTA;
import static net.runelite.api.ItemID.PREMADE_FR_BLAST;
import static net.runelite.api.ItemID.PREMADE_P_PUNCH;
import static net.runelite.api.ItemID.PREMADE_SGG;
import static net.runelite.api.ItemID.PREMADE_SY_CRUNCH;
import static net.runelite.api.ItemID.PREMADE_TD_BATTA;
import static net.runelite.api.ItemID.PREMADE_TD_CRUNCH;
import static net.runelite.api.ItemID.PREMADE_TTL;
import static net.runelite.api.ItemID.PREMADE_VEG_BALL;
import static net.runelite.api.ItemID.PREMADE_VEG_BATTA;
import static net.runelite.api.ItemID.PREMADE_WIZ_BLZD;
import static net.runelite.api.ItemID.PREMADE_WM_BATTA;
import static net.runelite.api.ItemID.PREMADE_WM_CRUN;
import static net.runelite.api.ItemID.PREMADE_WORM_HOLE;
import static net.runelite.api.ItemID.PSYKK_BAT_6;
import static net.runelite.api.ItemID.PUMPKIN;
import static net.runelite.api.ItemID.PURPLE_SWEETS_10476;
import static net.runelite.api.ItemID.PYSK_FISH_0;
import static net.runelite.api.ItemID.RAINBOW_FISH;
import static net.runelite.api.ItemID.RANGING_POTION1;
import static net.runelite.api.ItemID.RANGING_POTION2;
import static net.runelite.api.ItemID.RANGING_POTION3;
import static net.runelite.api.ItemID.RANGING_POTION4;
import static net.runelite.api.ItemID.REDBERRY_PIE;
import static net.runelite.api.ItemID.RESTORE_POTION1;
import static net.runelite.api.ItemID.RESTORE_POTION2;
import static net.runelite.api.ItemID.RESTORE_POTION3;
import static net.runelite.api.ItemID.RESTORE_POTION4;
import static net.runelite.api.ItemID.REVITALISATION_1_20957;
import static net.runelite.api.ItemID.REVITALISATION_2_20958;
import static net.runelite.api.ItemID.REVITALISATION_3_20959;
import static net.runelite.api.ItemID.REVITALISATION_4_20960;
import static net.runelite.api.ItemID.ROAST_BEAST_MEAT;
import static net.runelite.api.ItemID.ROAST_BIRD_MEAT;
import static net.runelite.api.ItemID.ROAST_FROG;
import static net.runelite.api.ItemID.ROAST_RABBIT;
import static net.runelite.api.ItemID.ROE;
import static net.runelite.api.ItemID.ROLL;
import static net.runelite.api.ItemID.ROQED_FISH_5;
import static net.runelite.api.ItemID.SALMON;
import static net.runelite.api.ItemID.SANFEW_SERUM1;
import static net.runelite.api.ItemID.SANFEW_SERUM2;
import static net.runelite.api.ItemID.SANFEW_SERUM3;
import static net.runelite.api.ItemID.SANFEW_SERUM4;
import static net.runelite.api.ItemID.SARADOMIN_BREW1;
import static net.runelite.api.ItemID.SARADOMIN_BREW2;
import static net.runelite.api.ItemID.SARADOMIN_BREW3;
import static net.runelite.api.ItemID.SARADOMIN_BREW4;
import static net.runelite.api.ItemID.SARDINE;
import static net.runelite.api.ItemID.SEA_TURTLE;
import static net.runelite.api.ItemID.SHARK;
import static net.runelite.api.ItemID.SHORT_GREEN_GUY;
import static net.runelite.api.ItemID.SHRIMPS;
import static net.runelite.api.ItemID.SLICED_BANANA;
import static net.runelite.api.ItemID.SLICE_OF_CAKE;
import static net.runelite.api.ItemID.SPICY_CRUNCHIES;
import static net.runelite.api.ItemID.SPICY_SAUCE;
import static net.runelite.api.ItemID.SPICY_STEW;
import static net.runelite.api.ItemID.SPINACH_ROLL;
import static net.runelite.api.ItemID.SPRING_SQIRKJUICE;
import static net.runelite.api.ItemID.SQUARE_SANDWICH;
import static net.runelite.api.ItemID.STAMINA_POTION1;
import static net.runelite.api.ItemID.STAMINA_POTION2;
import static net.runelite.api.ItemID.STAMINA_POTION3;
import static net.runelite.api.ItemID.STAMINA_POTION4;
import static net.runelite.api.ItemID.STEW;
import static net.runelite.api.ItemID.STRANGE_FRUIT;
import static net.runelite.api.ItemID.STRAWBERRY;
import static net.runelite.api.ItemID.STRENGTH_POTION1;
import static net.runelite.api.ItemID.STRENGTH_POTION2;
import static net.runelite.api.ItemID.STRENGTH_POTION3;
import static net.runelite.api.ItemID.STRENGTH_POTION4;
import static net.runelite.api.ItemID.STUFFED_SNAKE;
import static net.runelite.api.ItemID.SUMMER_PIE;
import static net.runelite.api.ItemID.SUMMER_SQIRKJUICE;
import static net.runelite.api.ItemID.SUPER_ATTACK1;
import static net.runelite.api.ItemID.SUPER_ATTACK2;
import static net.runelite.api.ItemID.SUPER_ATTACK3;
import static net.runelite.api.ItemID.SUPER_ATTACK4;
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION1;
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION2;
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION3;
import static net.runelite.api.ItemID.SUPER_COMBAT_POTION4;
import static net.runelite.api.ItemID.SUPER_DEFENCE1;
import static net.runelite.api.ItemID.SUPER_DEFENCE2;
import static net.runelite.api.ItemID.SUPER_DEFENCE3;
import static net.runelite.api.ItemID.SUPER_DEFENCE4;
import static net.runelite.api.ItemID.SUPER_ENERGY1;
import static net.runelite.api.ItemID.SUPER_ENERGY2;
import static net.runelite.api.ItemID.SUPER_ENERGY3;
import static net.runelite.api.ItemID.SUPER_ENERGY4;
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_1;
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_2;
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_3;
import static net.runelite.api.ItemID.SUPER_MAGIC_POTION_4;
import static net.runelite.api.ItemID.SUPER_RANGING_1;
import static net.runelite.api.ItemID.SUPER_RANGING_2;
import static net.runelite.api.ItemID.SUPER_RANGING_3;
import static net.runelite.api.ItemID.SUPER_RANGING_4;
import static net.runelite.api.ItemID.SUPER_RESTORE1;
import static net.runelite.api.ItemID.SUPER_RESTORE2;
import static net.runelite.api.ItemID.SUPER_RESTORE3;
import static net.runelite.api.ItemID.SUPER_RESTORE4;
import static net.runelite.api.ItemID.SUPER_STRENGTH1;
import static net.runelite.api.ItemID.SUPER_STRENGTH2;
import static net.runelite.api.ItemID.SUPER_STRENGTH3;
import static net.runelite.api.ItemID.SUPER_STRENGTH4;
import static net.runelite.api.ItemID.SUPHI_FISH_1;
import static net.runelite.api.ItemID.SWEETCORN_7088;
import static net.runelite.api.ItemID.SWORDFISH;
import static net.runelite.api.ItemID.TANGLED_TOADS_LEGS;
import static net.runelite.api.ItemID.THIN_SNAIL_MEAT;
import static net.runelite.api.ItemID.TOAD_BATTA;
import static net.runelite.api.ItemID.TOAD_CRUNCHIES;
import static net.runelite.api.ItemID.TOMATO;
import static net.runelite.api.ItemID.TRIANGLE_SANDWICH;
import static net.runelite.api.ItemID.TROUT;
import static net.runelite.api.ItemID.TUNA;
import static net.runelite.api.ItemID.TUNA_AND_CORN;
import static net.runelite.api.ItemID.TUNA_POTATO;
import static net.runelite.api.ItemID.TWISTED_1;
import static net.runelite.api.ItemID.TWISTED_1_20933;
import static net.runelite.api.ItemID.TWISTED_2;
import static net.runelite.api.ItemID.TWISTED_2_20934;
import static net.runelite.api.ItemID.TWISTED_3;
import static net.runelite.api.ItemID.TWISTED_3_20935;
import static net.runelite.api.ItemID.TWISTED_4;
import static net.runelite.api.ItemID.TWISTED_4_20936;
import static net.runelite.api.ItemID.TWISTED_POTION_1;
import static net.runelite.api.ItemID.TWISTED_POTION_2;
import static net.runelite.api.ItemID.TWISTED_POTION_3;
import static net.runelite.api.ItemID.TWISTED_POTION_4;
import static net.runelite.api.ItemID.UGTHANKI_KEBAB;
import static net.runelite.api.ItemID.UGTHANKI_KEBAB_1885;
import static net.runelite.api.ItemID.VEGETABLE_BATTA;
import static net.runelite.api.ItemID.VEG_BALL;
import static net.runelite.api.ItemID.WATERMELON_SLICE;
import static net.runelite.api.ItemID.WHITE_TREE_FRUIT;
import static net.runelite.api.ItemID.WILD_PIE;
import static net.runelite.api.ItemID.WINTER_SQIRKJUICE;
import static net.runelite.api.ItemID.WIZARD_BLIZZARD;
import static net.runelite.api.ItemID.WORM_BATTA;
import static net.runelite.api.ItemID.WORM_CRUNCHIES;
import static net.runelite.api.ItemID.WORM_HOLE;
import static net.runelite.api.ItemID.XERICS_AID_1_20981;
import static net.runelite.api.ItemID.XERICS_AID_2_20982;
import static net.runelite.api.ItemID.XERICS_AID_3_20983;
import static net.runelite.api.ItemID.XERICS_AID_4_20984;
import static net.runelite.api.ItemID.ZAMORAK_BREW1;
import static net.runelite.api.ItemID.ZAMORAK_BREW2;
import static net.runelite.api.ItemID.ZAMORAK_BREW3;
import static net.runelite.api.ItemID.ZAMORAK_BREW4;
import static net.runelite.api.ItemID._12_ANCHOVY_PIZZA;
import static net.runelite.api.ItemID._12_MEAT_PIZZA;
import static net.runelite.api.ItemID._12_PINEAPPLE_PIZZA;
import static net.runelite.api.ItemID._12_PLAIN_PIZZA;
import static net.runelite.api.ItemID._23_CAKE;
import static net.runelite.api.ItemID._23_CHOCOLATE_CAKE;
import static net.runelite.client.plugins.itemstats.Builders.boost; import static net.runelite.client.plugins.itemstats.Builders.boost;
import static net.runelite.client.plugins.itemstats.Builders.combo; import static net.runelite.client.plugins.itemstats.Builders.combo;
import static net.runelite.client.plugins.itemstats.Builders.dec; import static net.runelite.client.plugins.itemstats.Builders.dec;
@@ -501,6 +113,7 @@ public class ItemStatChanges
add(combo(2, food(8), heal(RUN_ENERGY, 5)), PAPAYA_FRUIT); add(combo(2, food(8), heal(RUN_ENERGY, 5)), PAPAYA_FRUIT);
add(range(food(5), food(7)), THIN_SNAIL_MEAT); add(range(food(5), food(7)), THIN_SNAIL_MEAT);
add(range(food(7), food(9)), FAT_SNAIL_MEAT); add(range(food(7), food(9)), FAT_SNAIL_MEAT);
add(range(food(7), food(10)), SPIDER_ON_STICK_6297, SPIDER_ON_SHAFT_6299);
// Dorgeshuun Cuisine // Dorgeshuun Cuisine
add(food(2), BAT_SHISH, COATED_FROGS_LEGS, FILLETS, FINGERS, FROGBURGER, FROGSPAWN_GUMBO, GREEN_GLOOP_SOUP, add(food(2), BAT_SHISH, COATED_FROGS_LEGS, FILLETS, FINGERS, FROGBURGER, FROGSPAWN_GUMBO, GREEN_GLOOP_SOUP,

View File

@@ -115,6 +115,7 @@ import net.runelite.http.api.loottracker.GameItem;
import net.runelite.http.api.loottracker.LootRecord; import net.runelite.http.api.loottracker.LootRecord;
import net.runelite.http.api.loottracker.LootRecordType; import net.runelite.http.api.loottracker.LootRecordType;
import net.runelite.http.api.loottracker.LootTrackerClient; import net.runelite.http.api.loottracker.LootTrackerClient;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Loot Tracker", name = "Loot Tracker",
@@ -135,7 +136,17 @@ public class LootTrackerPlugin extends Plugin
// Herbiboar loot handling // Herbiboar loot handling
private static final String HERBIBOAR_LOOTED_MESSAGE = "You harvest herbs from the herbiboar, whereupon it escapes."; private static final String HERBIBOAR_LOOTED_MESSAGE = "You harvest herbs from the herbiboar, whereupon it escapes.";
private static final String HERBIBOR_EVENT = "Herbiboar"; private static final String HERBIBOAR_EVENT = "Herbiboar";
// Hespori loot handling
private static final String HESPORI_LOOTED_MESSAGE = "You have successfully cleared this patch for new crops.";
private static final String HESPORI_EVENT = "Hespori";
private static final int HESPORI_REGION = 5021;
// Gauntlet loot handling
private static final String GAUNTLET_LOOTED_MESSAGE = "You open the chest.";
private static final String GAUNTLET_EVENT = "The Gauntlet";
private static final int GAUNTLET_LOBBY_REGION = 12127;
// Chest loot handling // Chest loot handling
private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!"; private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!";
@@ -144,7 +155,8 @@ public class LootTrackerPlugin extends Plugin
5179, "Brimstone Chest", 5179, "Brimstone Chest",
11573, "Crystal Chest", 11573, "Crystal Chest",
12093, "Larran's big chest", 12093, "Larran's big chest",
13113, "Larran's small chest" 13113, "Larran's small chest",
13151, "Elven Crystal Chest"
); );
private static final File LOOT_RECORDS_FILE = new File(RuneLite.RUNELITE_DIR, "lootRecords.json"); private static final File LOOT_RECORDS_FILE = new File(RuneLite.RUNELITE_DIR, "lootRecords.json");
private static final Set<Integer> RESPAWN_REGIONS = ImmutableSet.of( private static final Set<Integer> RESPAWN_REGIONS = ImmutableSet.of(
@@ -163,6 +175,10 @@ public class LootTrackerPlugin extends Plugin
@VisibleForTesting @VisibleForTesting
private Collection<LootRecord> lootRecords = new ArrayList<>(); private Collection<LootRecord> lootRecords = new ArrayList<>();
private boolean pvpDeath = false; private boolean pvpDeath = false;
// Last man standing map regions
private static final Set<Integer> LAST_MAN_STANDING_REGIONS = ImmutableSet.of(13658, 13659, 13914, 13915, 13916);
@Inject @Inject
private ClientToolbar clientToolbar; private ClientToolbar clientToolbar;
@Inject @Inject
@@ -511,6 +527,11 @@ public class LootTrackerPlugin extends Plugin
private void onPlayerLootReceived(final PlayerLootReceived playerLootReceived) private void onPlayerLootReceived(final PlayerLootReceived playerLootReceived)
{ {
// Ignore Last Man Standing player loots
if (isAtLMS())
{
return;
}
if (this.sendLootValueMessages) if (this.sendLootValueMessages)
{ {
if (WorldType.isDeadmanWorld(client.getWorldType()) || WorldType.isHighRiskWorld(client.getWorldType()) || if (WorldType.isDeadmanWorld(client.getWorldType()) || WorldType.isHighRiskWorld(client.getWorldType()) ||
@@ -680,7 +701,7 @@ public class LootTrackerPlugin extends Plugin
if (message.equals(HERBIBOAR_LOOTED_MESSAGE)) if (message.equals(HERBIBOAR_LOOTED_MESSAGE))
{ {
eventType = HERBIBOR_EVENT; eventType = HERBIBOAR_EVENT;
takeInventorySnapshot(); takeInventorySnapshot();
return; return;
@@ -688,6 +709,21 @@ public class LootTrackerPlugin extends Plugin
// Remove all tags // Remove all tags
final String chatMessage = Text.removeTags(message); final String chatMessage = Text.removeTags(message);
final int regionID = client.getLocalPlayer().getWorldLocation().getRegionID();
if (HESPORI_REGION == regionID && message.equals(HESPORI_LOOTED_MESSAGE))
{
eventType = HESPORI_EVENT;
takeInventorySnapshot();
return;
}
if (GAUNTLET_LOBBY_REGION == regionID && message.equals(GAUNTLET_LOOTED_MESSAGE))
{
eventType = GAUNTLET_EVENT;
takeInventorySnapshot();
return;
}
// Check if message is for a clue scroll reward // Check if message is for a clue scroll reward
final Matcher m = CLUE_SCROLL_PATTERN.matcher(chatMessage); final Matcher m = CLUE_SCROLL_PATTERN.matcher(chatMessage);
@@ -810,7 +846,10 @@ public class LootTrackerPlugin extends Plugin
} }
} }
if (eventType != null && (CHEST_EVENT_TYPES.containsValue(eventType) || HERBIBOR_EVENT.equals(eventType))) if (CHEST_EVENT_TYPES.containsValue(eventType)
|| HERBIBOAR_EVENT.equals(eventType)
|| HESPORI_EVENT.equals(eventType)
|| GAUNTLET_EVENT.equals(eventType))
{ {
if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY)) if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY))
{ {
@@ -1048,6 +1087,24 @@ public class LootTrackerPlugin extends Plugin
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
/**
* Is player at the Last Man Standing minigame
*/
private boolean isAtLMS()
{
final int[] mapRegions = client.getMapRegions();
for (int region : LAST_MAN_STANDING_REGIONS)
{
if (ArrayUtils.contains(mapRegions, region))
{
return true;
}
}
return false;
}
private void updateConfig() private void updateConfig()
{ {
this.getIgnoredItems = config.getIgnoredItems(); this.getIgnoredItems = config.getIgnoredItems();

View File

@@ -364,7 +364,14 @@ public class QuestListPlugin extends Plugin
else else
{ {
// Otherwise hide if it doesn't match the filter state // Otherwise hide if it doesn't match the filter state
hidden = currentFilterState != QuestState.ALL && questState != null && !questState.equals(currentFilterState); if (currentFilterState == QuestState.NOT_COMPLETED)
{
hidden = questState == QuestState.COMPLETE;
}
else
{
hidden = currentFilterState != QuestState.ALL && questState != currentFilterState;
}
} }
quest.setHidden(hidden); quest.setHidden(hidden);
@@ -398,7 +405,8 @@ public class QuestListPlugin extends Plugin
NOT_STARTED(0xff0000, "Not started", SpriteID.MINIMAP_ORB_HITPOINTS), NOT_STARTED(0xff0000, "Not started", SpriteID.MINIMAP_ORB_HITPOINTS),
IN_PROGRESS(0xffff00, "In progress", SpriteID.MINIMAP_ORB_HITPOINTS_DISEASE), IN_PROGRESS(0xffff00, "In progress", SpriteID.MINIMAP_ORB_HITPOINTS_DISEASE),
COMPLETE(0xdc10d, "Completed", SpriteID.MINIMAP_ORB_HITPOINTS_POISON), COMPLETE(0xdc10d, "Completed", SpriteID.MINIMAP_ORB_HITPOINTS_POISON),
ALL(0, "All", SpriteID.MINIMAP_ORB_PRAYER); ALL(0, "All", SpriteID.MINIMAP_ORB_PRAYER),
NOT_COMPLETED(0, "Not Completed", SpriteID.MINIMAP_ORB_RUN);
private final int color; private final int color;
private final String name; private final String name;

View File

@@ -196,11 +196,11 @@ public interface RaidsConfig extends Config
@ConfigItem( @ConfigItem(
position = 12, position = 12,
parent = "scouterConfig", parent = "scouterConfig",
keyName = "layoutMessage", keyName = "displayLayoutMessage",
name = "Send raid layout message when entering raid", name = "Send raid layout message when entering raid",
description = "Sends game message with raid layout on entering new raid" description = "Sends game message with raid layout on entering new raid"
) )
default boolean layoutMessage() default boolean displayLayoutMessage()
{ {
return true; return true;
} }

View File

@@ -34,7 +34,6 @@ import java.awt.image.BufferedImage;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -97,6 +96,10 @@ import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;
import net.runelite.client.ws.PartyMember;
import net.runelite.client.ws.PartyService;
import net.runelite.client.ws.WSClient;
import net.runelite.http.api.ws.messages.party.PartyChatMessage;
@PluginDescriptor( @PluginDescriptor(
name = "CoX Scouter", name = "CoX Scouter",
@@ -199,6 +202,28 @@ public class RaidsPlugin extends Plugin
@Inject @Inject
private EventBus eventBus; private EventBus eventBus;
private boolean raidStarted; private boolean raidStarted;
@Inject
private PartyService party;
@Inject
private WSClient ws;
@Getter
private final ArrayList<String> roomWhitelist = new ArrayList<>();
@Getter
private final ArrayList<String> roomBlacklist = new ArrayList<>();
@Getter
private final ArrayList<String> rotationWhitelist = new ArrayList<>();
@Getter
private final ArrayList<String> layoutWhitelist = new ArrayList<>();
@Getter
private Raid raid;
private boolean inRaidChambers; private boolean inRaidChambers;
private boolean enhanceScouterTitle; private boolean enhanceScouterTitle;
private boolean hideBackground; private boolean hideBackground;
@@ -211,7 +236,6 @@ public class RaidsPlugin extends Plugin
private boolean displayFloorBreak; private boolean displayFloorBreak;
private boolean showRecommendedItems; private boolean showRecommendedItems;
private boolean alwaysShowWorldAndCC; private boolean alwaysShowWorldAndCC;
private boolean layoutMessage;
private boolean colorTightrope; private boolean colorTightrope;
private boolean crabHandler; private boolean crabHandler;
private boolean enableRotationWhitelist; private boolean enableRotationWhitelist;
@@ -232,7 +256,8 @@ public class RaidsPlugin extends Plugin
private Color rareCrabColor; private Color rareCrabColor;
private Color scavPrepColor; private Color scavPrepColor;
private Color tightropeColor; private Color tightropeColor;
private Raid raid; private boolean displayLayoutMessage;
private String layoutMessage;
private RaidsTimer timer; private RaidsTimer timer;
private WidgetOverlay widgetOverlay; private WidgetOverlay widgetOverlay;
private NavigationButton navButton; private NavigationButton navButton;
@@ -244,10 +269,6 @@ public class RaidsPlugin extends Plugin
private String tooltip; private String tooltip;
private String goodCrabs; private String goodCrabs;
private String layoutFullCode; private String layoutFullCode;
private List<String> roomWhitelist = new ArrayList<>();
private List<String> roomBlacklist = new ArrayList<>();
private List<String> rotationWhitelist = new ArrayList<>();
private List<String> layoutWhitelist = new ArrayList<>();
private List<String> partyMembers = new ArrayList<>(); private List<String> partyMembers = new ArrayList<>();
private List<String> startingPartyMembers = new ArrayList<>(); private List<String> startingPartyMembers = new ArrayList<>();
private Map<String, List<Integer>> recommendedItemsList = new HashMap<>(); private Map<String, List<Integer>> recommendedItemsList = new HashMap<>();
@@ -688,7 +709,7 @@ public class RaidsPlugin extends Plugin
private void sendRaidLayoutMessage() private void sendRaidLayoutMessage()
{ {
if (!this.layoutMessage) if (!this.displayLayoutMessage)
{ {
return; return;
} }
@@ -725,6 +746,22 @@ public class RaidsPlugin extends Plugin
.build()) .build())
.build()); .build());
} }
final PartyMember localMember = party.getLocalMember();
if (party.getMembers().isEmpty() || localMember == null)
{
chatMessageManager.queue(QueuedMessage.builder()
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
.runeLiteFormattedMessage(layoutMessage)
.build());
}
else
{
final PartyChatMessage message = new PartyChatMessage(layoutMessage);
message.setMemberId(localMember.getMemberId());
ws.send(message);
}
} }
private void updateInfoBoxState() private void updateInfoBoxState()
@@ -828,28 +865,28 @@ public class RaidsPlugin extends Plugin
} }
else else
{ {
list.addAll(Arrays.asList(input.toLowerCase().split(SPLIT_REGEX))); list.addAll(Text.fromCSV(input.toLowerCase()));
} }
} }
int getRotationMatches() int getRotationMatches()
{ {
String rotation = raid.getRotationString().toLowerCase(); String rotation = raid.getRotationString().toLowerCase();
String[] bosses = rotation.split(SPLIT_REGEX); List<String> bosses = Text.fromCSV(rotation);
if (rotationWhitelist.contains(rotation)) if (rotationWhitelist.contains(rotation))
{ {
return bosses.length; return bosses.size();
} }
for (String whitelisted : rotationWhitelist) for (String whitelisted : rotationWhitelist)
{ {
int matches = 0; int matches = 0;
String[] whitelistedBosses = whitelisted.split(SPLIT_REGEX); List<String> whitelistedBosses = Text.fromCSV(whitelisted);
for (int i = 0; i < whitelistedBosses.length; i++) for (int i = 0; i < whitelistedBosses.size(); i++)
{ {
if (i < bosses.length && whitelistedBosses[i].equals(bosses[i])) if (i < bosses.size() && whitelistedBosses.get(i).equals(bosses.get(i)))
{ {
matches++; matches++;
} }
@@ -1240,7 +1277,7 @@ public class RaidsPlugin extends Plugin
this.showRecommendedItems = config.showRecommendedItems(); this.showRecommendedItems = config.showRecommendedItems();
this.recommendedItems = config.recommendedItems(); this.recommendedItems = config.recommendedItems();
this.alwaysShowWorldAndCC = config.alwaysShowWorldAndCC(); this.alwaysShowWorldAndCC = config.alwaysShowWorldAndCC();
this.layoutMessage = config.layoutMessage(); this.displayLayoutMessage = config.displayLayoutMessage();
this.colorTightrope = config.colorTightrope(); this.colorTightrope = config.colorTightrope();
this.tightropeColor = config.tightropeColor(); this.tightropeColor = config.tightropeColor();
this.crabHandler = config.crabHandler(); this.crabHandler = config.crabHandler();

View File

@@ -49,7 +49,7 @@ import net.runelite.client.ui.overlay.components.table.TableComponent;
@Singleton @Singleton
class SmeltingOverlay extends Overlay class SmeltingOverlay extends Overlay
{ {
private static final int SMELT_TIMEOUT = 5; private static final int SMELT_TIMEOUT = 7;
private final Client client; private final Client client;
private final SmeltingPlugin plugin; private final SmeltingPlugin plugin;

View File

@@ -244,6 +244,13 @@ class FarmingWorld
new FarmingPatch("", Varbits.FARMING_7907, PatchImplementation.REDWOOD) new FarmingPatch("", Varbits.FARMING_7907, PatchImplementation.REDWOOD)
)); ));
add(new FarmingRegion("Prifddinas", 13151,
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.CRYSTAL_TREE)
));
// Finalize // Finalize
this.regions = Collections.unmodifiableMap(regions); this.regions = Collections.unmodifiableMap(regions);
Map<Tab, Set<FarmingPatch>> umtabs = new TreeMap<>(); Map<Tab, Set<FarmingPatch>> umtabs = new TreeMap<>();

View File

@@ -224,7 +224,7 @@ public enum PatchImplementation
} }
if (value >= 63 && value <= 69) if (value >= 63 && value <= 69)
{ {
// snape grass seedling,Snape grass plant[Inspect,Guide] 33674,33675,33676,33677,33678,33679,33680 // Snape grass seedling,Snape grass plant[Inspect,Guide] 33674,33675,33676,33677,33678,33679,33680
return new PatchState(Produce.SNAPE_GRASS, CropState.GROWING, value - 63); return new PatchState(Produce.SNAPE_GRASS, CropState.GROWING, value - 63);
} }
if (value >= 70 && value <= 73) if (value >= 70 && value <= 73)
@@ -2391,7 +2391,7 @@ public enum PatchImplementation
} }
if (value >= 46 && value <= 51) if (value >= 46 && value <= 51)
{ {
// Diseased Poato cactus[Cure,Inspect,Guide] 33749,33750,33751,33752,33753,33754 // Diseased Potato cactus[Cure,Inspect,Guide] 33749,33750,33751,33752,33753,33754
return new PatchState(Produce.POTATO_CACTUS, CropState.DISEASED, value - 45); return new PatchState(Produce.POTATO_CACTUS, CropState.DISEASED, value - 45);
} }
if (value >= 52 && value <= 57) if (value >= 52 && value <= 57)
@@ -2575,6 +2575,34 @@ public enum PatchImplementation
} }
return null; return null;
} }
},
CRYSTAL_TREE(Tab.FRUIT_TREE, "Crystal Tree")
{
@Override
PatchState forVarbitValue(int value)
{
if (value >= 0 && value <= 3)
{
// Crystal tree patch[Rake,Inspect,Guide] 34910,34909,34908,34907
return new PatchState(Produce.WEEDS, CropState.GROWING, 3 - value);
}
if (value >= 8 && value <= 13)
{
// Crystal tree[Inspect,Guide] 34911,34912,34913,34914,34915,34916
return new PatchState(Produce.CRYSTAL_TREE, CropState.GROWING, value - 8);
}
if (value == 14)
{
// Crystal tree[Check-health,Inspect,Guide] 34917
return new PatchState(Produce.CRYSTAL_TREE, CropState.GROWING, Produce.CRYSTAL_TREE.getStages() - 1);
}
if (value == 15)
{
// Crystal tree[Chop-down,Inspect,Guide] 34918
return new PatchState(Produce.CRYSTAL_TREE, CropState.HARVESTABLE, 0);
}
return null;
}
}; };
@Nullable @Nullable

View File

@@ -129,7 +129,8 @@ public enum Produce
SPIRIT_TREE("Spirit tree", ItemID.SPIRIT_TREE, 320, 13), SPIRIT_TREE("Spirit tree", ItemID.SPIRIT_TREE, 320, 13),
CELASTRUS("Celastrus", ItemID.BATTLESTAFF, 160, 6, 0, 4), CELASTRUS("Celastrus", ItemID.BATTLESTAFF, 160, 6, 0, 4),
REDWOOD("Redwood", ItemID.REDWOOD_LOGS, 640, 11), REDWOOD("Redwood", ItemID.REDWOOD_LOGS, 640, 11),
HESPORI("Hespori", NullItemID.NULL_23044, 640, 4, 0, 2); HESPORI("Hespori", NullItemID.NULL_23044, 640, 4, 0, 2),
CRYSTAL_TREE("Crystal tree", ItemID.CRYSTAL_SHARDS, 80, 7);
/** /**
* User-visible name * User-visible name

View File

@@ -40,7 +40,8 @@ enum FarmingPatchLocation
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)),
@@ -59,6 +60,9 @@ enum FarmingPatchLocation
CELASTRUS_FRUIT_TREE("Celastrus/Fruit Tree", CELASTRUS_FRUIT_TREE("Celastrus/Fruit Tree",
new WorldPoint(1242, 3755, 0) new WorldPoint(1242, 3755, 0)
), ),
CRYSTAL_TREE("Crystal Tree",
new WorldPoint(3292, 6120, 0)
),
FRUIT_TREE("Fruit Tree", FRUIT_TREE("Fruit Tree",
new WorldPoint(2487, 3181, 0), new WorldPoint(2487, 3181, 0),
new WorldPoint(2343, 3160, 0), new WorldPoint(2343, 3160, 0),

View File

@@ -70,7 +70,8 @@ enum MinigameLocation
ANIMATION_ROOM("Animation Room", new WorldPoint(2853, 3537, 0)), ANIMATION_ROOM("Animation Room", new WorldPoint(2853, 3537, 0)),
DUMMY_ROOM("Dummy Room", new WorldPoint(2857, 3551, 0)), DUMMY_ROOM("Dummy Room", new WorldPoint(2857, 3551, 0)),
CATAPULT_ROOM("Catapult Room", new WorldPoint(2842, 3545, 0)), CATAPULT_ROOM("Catapult Room", new WorldPoint(2842, 3545, 0)),
SHOT_PUT_ROOM("Shot Put Room", new WorldPoint(2863, 3550, 0)); SHOT_PUT_ROOM("Shot Put Room", new WorldPoint(2863, 3550, 0)),
THE_GAUNTLET("The Gauntlet", new WorldPoint(3223, 12505, 1));
private final String tooltip; private final String tooltip;
private final WorldPoint location; private final WorldPoint location;

View File

@@ -130,7 +130,7 @@ enum QuestStartLocation
OBSERVATORY_QUEST(Quest.OBSERVATORY_QUEST, new WorldPoint(2438, 3185, 0)), OBSERVATORY_QUEST(Quest.OBSERVATORY_QUEST, new WorldPoint(2438, 3185, 0)),
OLAFS_QUEST(Quest.OLAFS_QUEST, new WorldPoint(2723, 3729, 0)), OLAFS_QUEST(Quest.OLAFS_QUEST, new WorldPoint(2723, 3729, 0)),
ONE_SMALL_FAVOUR(Quest.ONE_SMALL_FAVOUR, new WorldPoint(2834, 2985, 0)), ONE_SMALL_FAVOUR(Quest.ONE_SMALL_FAVOUR, new WorldPoint(2834, 2985, 0)),
PLAGUE_CITY(Quest.PLAGUE_CITY, new WorldPoint(2567, 3334, 0)), PLAGUE_CITY_SONG_OF_THE_ELVES(new Quest[]{Quest.PLAGUE_CITY, Quest.SONG_OF_THE_ELVES}, new WorldPoint(2567, 3334, 0)),
PRIEST_IN_PERIL(Quest.PRIEST_IN_PERIL, new WorldPoint(3219, 3473, 0)), PRIEST_IN_PERIL(Quest.PRIEST_IN_PERIL, new WorldPoint(3219, 3473, 0)),
THE_QUEEN_OF_THIEVES(Quest.THE_QUEEN_OF_THIEVES, new WorldPoint(1795, 3782, 0)), THE_QUEEN_OF_THIEVES(Quest.THE_QUEEN_OF_THIEVES, new WorldPoint(1795, 3782, 0)),
RAG_AND_BONE_MAN(new Quest[]{Quest.RAG_AND_BONE_MAN, Quest.RAG_AND_BONE_MAN_II}, new WorldPoint(3359, 3504, 0)), RAG_AND_BONE_MAN(new Quest[]{Quest.RAG_AND_BONE_MAN, Quest.RAG_AND_BONE_MAN_II}, new WorldPoint(3359, 3504, 0)),

View File

@@ -50,7 +50,10 @@ enum RareTreeLocation
new WorldPoint(2899, 2897, 0), new WorldPoint(2899, 2897, 0),
// Feldip Hills // Feldip Hills
new WorldPoint(2333, 3049, 0)), new WorldPoint(2333, 3049, 0),
// Prifddinas
new WorldPoint(3309, 6123, 0)),
SWAYING("Swaying tree", 40, SWAYING("Swaying tree", 40,
// The Fremennik Trials // The Fremennik Trials
@@ -78,7 +81,11 @@ enum RareTreeLocation
new WorldPoint(2726, 3501, 0), new WorldPoint(2726, 3501, 0),
new WorldPoint(2728, 3481, 0), new WorldPoint(2728, 3481, 0),
new WorldPoint(2748, 3466, 0), new WorldPoint(2748, 3466, 0),
new WorldPoint(2710, 3570, 0)), new WorldPoint(2710, 3570, 0),
// Prifddinas
new WorldPoint(2209, 3427, 0),
new WorldPoint(3233, 6179, 0)),
MAHOGANY("Mahogany tree", 50, MAHOGANY("Mahogany tree", 50,
// Zeah // Zeah
@@ -92,7 +99,10 @@ enum RareTreeLocation
new WorldPoint(3824, 3053, 0), new WorldPoint(3824, 3053, 0),
// Karamja // Karamja
new WorldPoint(2946, 2908, 0)), new WorldPoint(2946, 2908, 0),
// Prifddinas
new WorldPoint(3301, 6129, 0)),
TEAK_MAHOGANY("Teak/Mahogany trees", 50, TEAK_MAHOGANY("Teak/Mahogany trees", 50,
// Miscellania // Miscellania
@@ -126,6 +136,10 @@ enum RareTreeLocation
// Tirannwn // Tirannwn
new WorldPoint(2217, 3141, 0), new WorldPoint(2217, 3141, 0),
// Prifddinas
new WorldPoint(3288, 6066, 0),
new WorldPoint(3305, 6032, 0),
// Kandarin // Kandarin
new WorldPoint(2315, 3610, 0), new WorldPoint(2315, 3610, 0),
new WorldPoint(2331, 3514, 0), new WorldPoint(2331, 3514, 0),
@@ -202,6 +216,9 @@ enum RareTreeLocation
// Tirannwn // Tirannwn
new WorldPoint(2284, 3141, 0), new WorldPoint(2284, 3141, 0),
// Prifddinas
new WorldPoint(3229, 6101, 0),
// Kandarin // Kandarin
new WorldPoint(2371, 3427, 0), new WorldPoint(2371, 3427, 0),
new WorldPoint(2432, 3411, 0), new WorldPoint(2432, 3411, 0),

View File

@@ -139,6 +139,8 @@ enum TeleportLocationData
PHARAOHS_SCEPTRE_JALEUSTROPHOS(TeleportType.OTHER, "Pharaoh's Sceptre", "Jaleustrophos (Agility Pyramid)", new WorldPoint(3341, 2827, 0), "pharaohs_sceptre_teleport_icon.png"), PHARAOHS_SCEPTRE_JALEUSTROPHOS(TeleportType.OTHER, "Pharaoh's Sceptre", "Jaleustrophos (Agility Pyramid)", new WorldPoint(3341, 2827, 0), "pharaohs_sceptre_teleport_icon.png"),
PHARAOHS_SCEPTRE_JALDRAOCHT(TeleportType.OTHER, "Pharaoh's Sceptre", "Jaldraocht (Desert Treasure Pyramid)", new WorldPoint(3232, 2897, 0), "pharaohs_sceptre_teleport_icon.png"), PHARAOHS_SCEPTRE_JALDRAOCHT(TeleportType.OTHER, "Pharaoh's Sceptre", "Jaldraocht (Desert Treasure Pyramid)", new WorldPoint(3232, 2897, 0), "pharaohs_sceptre_teleport_icon.png"),
CAMULET_TEMPLE(TeleportType.OTHER, "Camulet", "Enakhra's Temple", new WorldPoint(3190, 2923, 0), "camulet_teleport_icon.png"), CAMULET_TEMPLE(TeleportType.OTHER, "Camulet", "Enakhra's Temple", new WorldPoint(3190, 2923, 0), "camulet_teleport_icon.png"),
TELEPORT_CRYSTAL_LLETYA(TeleportType.OTHER, "Teleport crystal", "Lletya", new WorldPoint(2330, 3172, 0), "teleport_crystal_icon.png"),
TELEPORT_CRYSTAL_PRIFDDINAS(TeleportType.OTHER, "Teleport crystal", "Prifddinas", new WorldPoint(3264, 6065, 0), "teleport_crystal_icon.png"),
// Wilderness // Wilderness
OBELISK_13(TeleportType.OTHER, "Obelisk", "13", new WorldPoint(3156, 3620, 0), "obelisk_icon.png"), OBELISK_13(TeleportType.OTHER, "Obelisk", "13", new WorldPoint(3156, 3620, 0), "obelisk_icon.png"),
@@ -167,7 +169,7 @@ enum TeleportLocationData
// Scrolls // Scrolls
DIGSITE_SCROLL(TeleportType.SCROLL, "Digsite Teleport", new WorldPoint(3324, 3412, 0), "scroll_teleport_icon.png"), DIGSITE_SCROLL(TeleportType.SCROLL, "Digsite Teleport", new WorldPoint(3324, 3412, 0), "scroll_teleport_icon.png"),
ELF_CAMP_SCROLL(TeleportType.SCROLL, "Elf Camp Teleport", new WorldPoint(2193, 3257, 0), "scroll_teleport_icon.png"), IORWERTH_CAMP_SCROLL(TeleportType.SCROLL, "Iorwerth Camp Teleport", new WorldPoint(2193, 3257, 0), "scroll_teleport_icon.png"),
FELDIP_HILLS_SCROLL(TeleportType.SCROLL, "Feldip Hills Teleport", new WorldPoint(2542, 2925, 0), "scroll_teleport_icon.png"), FELDIP_HILLS_SCROLL(TeleportType.SCROLL, "Feldip Hills Teleport", new WorldPoint(2542, 2925, 0), "scroll_teleport_icon.png"),
LUMBERYARD_SCROLL(TeleportType.SCROLL, "Lumberyard Teleport", new WorldPoint(3303, 3487, 0), "scroll_teleport_icon.png"), LUMBERYARD_SCROLL(TeleportType.SCROLL, "Lumberyard Teleport", new WorldPoint(3303, 3487, 0), "scroll_teleport_icon.png"),
LUNAR_ISLE_SCROLL(TeleportType.SCROLL, "Lunar Isle Teleport", new WorldPoint(2093, 3912, 0), "scroll_teleport_icon.png"), LUNAR_ISLE_SCROLL(TeleportType.SCROLL, "Lunar Isle Teleport", new WorldPoint(2093, 3912, 0), "scroll_teleport_icon.png"),

View File

@@ -114,6 +114,8 @@ enum TransportationPointLocation
CHARTER_PORT_PHASMATYS("Charter Ship", new WorldPoint(3702, 3503, 0)), CHARTER_PORT_PHASMATYS("Charter Ship", new WorldPoint(3702, 3503, 0)),
CHARTER_PORTSARIM("Charter Ship", new WorldPoint(3037, 3191, 0)), CHARTER_PORTSARIM("Charter Ship", new WorldPoint(3037, 3191, 0)),
CHARTER_TYRAS("Charter Ship", new WorldPoint(2141, 3123, 0)), CHARTER_TYRAS("Charter Ship", new WorldPoint(2141, 3123, 0)),
CHARTER_PRIFDDINAS("Charter Ship", new WorldPoint(2156, 3331, 0)),
CHARTER_PRIFDDINAS_INSTANCE("Charter Ship", new WorldPoint(3180, 6083, 0)),
//Minecarts/Carts //Minecarts/Carts
MINE_CART_ARCEUUS("Minecart", new WorldPoint(1673, 3832, 0)), MINE_CART_ARCEUUS("Minecart", new WorldPoint(1673, 3832, 0)),
@@ -155,6 +157,7 @@ enum TransportationPointLocation
SPIRITTREE_GNOMESTRONGHOLD("Spirit Tree", new WorldPoint(2459, 3446, 0)), SPIRITTREE_GNOMESTRONGHOLD("Spirit Tree", new WorldPoint(2459, 3446, 0)),
SPIRITTREE_GNOMEVILLAGE("Spirit Tree", new WorldPoint(2538, 3166, 0)), SPIRITTREE_GNOMEVILLAGE("Spirit Tree", new WorldPoint(2538, 3166, 0)),
SPIRITTREE_GRANDEXCHANGE("Spirit Tree", new WorldPoint(3184, 3510, 0)), SPIRITTREE_GRANDEXCHANGE("Spirit Tree", new WorldPoint(3184, 3510, 0)),
SPIRITTREE_PRIFDDINAS("Spirit Tree", new WorldPoint(3274, 6124, 0)),
//Carpets //Carpets
CARPET_KHARID("Carpet to Bedabin/Pollnivneach/Uzer", new WorldPoint(3311, 3107, 0)), CARPET_KHARID("Carpet to Bedabin/Pollnivneach/Uzer", new WorldPoint(3311, 3107, 0)),
@@ -172,6 +175,7 @@ enum TransportationPointLocation
TELEPORT_RUNE_ARDOUGNE("Teleport to Rune Essence", new WorldPoint(2681, 3325, 0)), TELEPORT_RUNE_ARDOUGNE("Teleport to Rune Essence", new WorldPoint(2681, 3325, 0)),
TELEPORT_RUNE_YANILLE("Teleport to Rune Essence", new WorldPoint(2592, 3089, 0)), TELEPORT_RUNE_YANILLE("Teleport to Rune Essence", new WorldPoint(2592, 3089, 0)),
TELEPORT_SORCERESS_GARDEN("Teleport to Sorceress's Garden", new WorldPoint(3320, 3141, 0)), TELEPORT_SORCERESS_GARDEN("Teleport to Sorceress's Garden", new WorldPoint(3320, 3141, 0)),
TELEPORT_PRIFDDINAS_LIBRARY("Teleport to Priffdinas Library", new WorldPoint(3254, 6082, 2)),
//Other //Other
ALTER_KOUREND_UNDERGROUND("Altar to Skotizo", new WorldPoint(1662, 10047, 0)), ALTER_KOUREND_UNDERGROUND("Altar to Skotizo", new WorldPoint(1662, 10047, 0)),

View File

@@ -94,6 +94,17 @@ public interface XpTrackerConfig extends Config
@ConfigItem( @ConfigItem(
position = 4, position = 4,
keyName = "skillTabOverlayMenuOptions",
name = "Add skill tab canvas menu option",
description = "Configures whether a menu option to show/hide canvas XP trackers will be added to skills on the skill tab"
)
default boolean skillTabOverlayMenuOptions()
{
return true;
}
@ConfigItem(
position = 5,
keyName = "onScreenDisplayMode", keyName = "onScreenDisplayMode",
name = "On-screen tracker display mode (top)", name = "On-screen tracker display mode (top)",
description = "Configures the information displayed in the first line of on-screen XP overlays" description = "Configures the information displayed in the first line of on-screen XP overlays"
@@ -104,7 +115,7 @@ public interface XpTrackerConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 4, position = 6,
keyName = "onScreenDisplayModeBottom", keyName = "onScreenDisplayModeBottom",
name = "On-screen tracker display mode (bottom)", name = "On-screen tracker display mode (bottom)",
description = "Configures the information displayed in the second line of on-screen XP overlays" description = "Configures the information displayed in the second line of on-screen XP overlays"

View File

@@ -31,6 +31,7 @@ import com.google.inject.Binder;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -42,6 +43,8 @@ import net.runelite.api.Actor;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Experience; import net.runelite.api.Experience;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.MenuAction;
import net.runelite.api.MenuEntry;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Skill; import net.runelite.api.Skill;
@@ -51,7 +54,11 @@ import net.runelite.api.events.ConfigChanged;
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;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcDespawned;
import net.runelite.api.widgets.WidgetID;
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.game.NPCManager; import net.runelite.client.game.NPCManager;
@@ -64,6 +71,7 @@ import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text;
import net.runelite.http.api.xp.XpClient; import net.runelite.http.api.xp.XpClient;
@PluginDescriptor( @PluginDescriptor(
@@ -79,6 +87,9 @@ public class XpTrackerPlugin extends Plugin
*/ */
private static final int XP_THRESHOLD = 10_000; private static final int XP_THRESHOLD = 10_000;
private static final String MENUOP_ADD_CANVAS_TRACKER = "Add to canvas";
private static final String MENUOP_REMOVE_CANVAS_TRACKER = "Remove from canvas";
static final List<Skill> COMBAT = ImmutableList.of( static final List<Skill> COMBAT = ImmutableList.of(
Skill.ATTACK, Skill.ATTACK,
Skill.STRENGTH, Skill.STRENGTH,
@@ -178,6 +189,8 @@ public class XpTrackerPlugin extends Plugin
eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged); eventBus.subscribe(ExperienceChanged.class, this, this::onExperienceChanged);
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
eventBus.subscribe(GameTick.class, this, this::onGameTick); eventBus.subscribe(GameTick.class, this, this::onGameTick);
eventBus.subscribe(MenuEntryAdded.class, this, this::onMenuEntryAdded);
eventBus.subscribe(MenuOptionClicked.class, this, this::onMenuOptionClicked);
} }
private void onGameStateChanged(GameStateChanged event) private void onGameStateChanged(GameStateChanged event)
@@ -402,6 +415,64 @@ public class XpTrackerPlugin extends Plugin
} }
} }
private void onMenuEntryAdded(final MenuEntryAdded event)
{
int widgetID = event.getActionParam1();
if (TO_GROUP(widgetID) != WidgetID.SKILLS_GROUP_ID
|| !event.getOption().startsWith("View")
|| !xpTrackerConfig.skillTabOverlayMenuOptions())
{
return;
}
// Get skill from menu option, eg. "View <col=ff981f>Attack</col> guide"
final String skillText = event.getOption().split(" ")[1];
final Skill skill = Skill.valueOf(Text.removeTags(skillText).toUpperCase());
MenuEntry[] menuEntries = client.getMenuEntries();
menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1);
MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry();
menuEntry.setTarget(skillText);
menuEntry.setOption(hasOverlay(skill) ? MENUOP_REMOVE_CANVAS_TRACKER : MENUOP_ADD_CANVAS_TRACKER);
menuEntry.setParam0(event.getActionParam0());
menuEntry.setParam1(widgetID);
menuEntry.setType(MenuAction.RUNELITE.getId());
client.setMenuEntries(menuEntries);
}
private void onMenuOptionClicked(MenuOptionClicked event)
{
if (event.getMenuAction().getId() != MenuAction.RUNELITE.getId()
|| TO_GROUP(event.getIdentifier()) != WidgetID.SKILLS_GROUP_ID)
{
return;
}
final Skill skill;
try
{
skill = Skill.valueOf(Text.removeTags(event.getTarget()).toUpperCase());
}
catch (IllegalArgumentException ex)
{
log.debug(null, ex);
return;
}
switch (event.getOption())
{
case MENUOP_ADD_CANVAS_TRACKER:
addOverlay(skill);
break;
case MENUOP_REMOVE_CANVAS_TRACKER:
removeOverlay(skill);
break;
}
}
XpSnapshotSingle getSkillSnapshot(Skill skill) XpSnapshotSingle getSkillSnapshot(Skill skill)
{ {
return xpState.getSkillSnapshot(skill); return xpState.getSkillSnapshot(skill);
@@ -589,6 +660,11 @@ public class XpTrackerPlugin extends Plugin
} }
} }
private boolean hasOverlay(final Skill skill)
{
return overlayManager.anyMatch(o -> o instanceof XpInfoBoxOverlay && ((XpInfoBoxOverlay) o).getSkill() == skill);
}
private void onConfigChanged(ConfigChanged event) private void onConfigChanged(ConfigChanged event)
{ {
if (!event.getGroup().equals("xpTracker")) if (!event.getGroup().equals("xpTracker"))

View File

@@ -34,6 +34,12 @@ public interface ZoomConfig extends Config
{ {
int OUTER_LIMIT_MIN = -400; int OUTER_LIMIT_MIN = -400;
int OUTER_LIMIT_MAX = 400; int OUTER_LIMIT_MAX = 400;
/**
* The largest (most zoomed in) value that can be used without the client crashing.
*
* Larger values trigger an overflow in the engine's fov to scale code.
*/
int INNER_ZOOM_LIMIT = 1004;
@ConfigItem( @ConfigItem(
keyName = "inner", keyName = "inner",
@@ -91,7 +97,7 @@ public interface ZoomConfig extends Config
) )
@Range( @Range(
min = OUTER_LIMIT_MIN, min = OUTER_LIMIT_MIN,
max = OUTER_LIMIT_MAX max = INNER_ZOOM_LIMIT
) )
default int ctrlZoomValue() default int ctrlZoomValue()
{ {

View File

@@ -25,30 +25,22 @@
*/ */
package net.runelite.client.rs; package net.runelite.client.rs;
import com.google.common.annotations.VisibleForTesting;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import javax.inject.Inject; import net.runelite.http.api.RuneLiteAPI;
import javax.inject.Singleton;
import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@Singleton
class ClientConfigLoader class ClientConfigLoader
{ {
private static final String CONFIG_URL = "http://oldschool.runescape.com/jav_config.ws"; public ClientConfigLoader()
private final OkHttpClient httpClient;
@Inject
@VisibleForTesting
ClientConfigLoader(final OkHttpClient httpClient)
{ {
this.httpClient = httpClient;
} }
RSConfig fetch() throws IOException private static final String CONFIG_URL = "http://oldschool.runescape.com/jav_config.ws";
static RSConfig fetch() throws IOException
{ {
final Request request = new Request.Builder() final Request request = new Request.Builder()
.url(CONFIG_URL) .url(CONFIG_URL)
@@ -56,8 +48,8 @@ class ClientConfigLoader
final RSConfig config = new RSConfig(); final RSConfig config = new RSConfig();
try (final Response response = httpClient.newCall(request).execute(); final BufferedReader in = new BufferedReader( try (final Response response = RuneLiteAPI.CLIENT.newCall(request).execute();
new InputStreamReader(response.body().byteStream()))) final BufferedReader in = new BufferedReader(new InputStreamReader(response.body().byteStream())))
{ {
String str; String str;

View File

@@ -215,6 +215,17 @@ public class OverlayManager
return removeIf; return removeIf;
} }
/**
* Returns whether an overlay exists which matches the given predicate.
*
* @param filter Filter predicate function
* @return {@code true} if any overlays match the given filter, {@code false} otherwise
*/
public synchronized boolean anyMatch(Predicate<Overlay> filter)
{
return overlays.stream().anyMatch(filter);
}
/** /**
* Clear all overlays * Clear all overlays
*/ */

View File

@@ -22,7 +22,7 @@
* (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.chatfilter; package net.runelite.client.util;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;

View File

@@ -46,6 +46,8 @@ public class Text
private static final Joiner COMMA_JOINER = Joiner.on(",").skipNulls(); private static final Joiner COMMA_JOINER = Joiner.on(",").skipNulls();
public static final CharMatcher JAGEX_PRINTABLE_CHAR_MATCHER = new JagexPrintableCharMatcher();
/** /**
* Splits comma separated values to list of strings * Splits comma separated values to list of strings
* *

View File

@@ -33,12 +33,17 @@ import javax.inject.Singleton;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.client.account.AccountSession; import net.runelite.client.account.AccountSession;
import net.runelite.client.account.SessionManager; import net.runelite.client.account.SessionManager;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyChanged;
import static net.runelite.client.util.Text.JAGEX_PRINTABLE_CHAR_MATCHER;
import net.runelite.http.api.ws.messages.party.Join; import net.runelite.http.api.ws.messages.party.Join;
import net.runelite.http.api.ws.messages.party.Part; import net.runelite.http.api.ws.messages.party.Part;
import net.runelite.http.api.ws.messages.party.PartyChatMessage;
import net.runelite.http.api.ws.messages.party.UserJoin; import net.runelite.http.api.ws.messages.party.UserJoin;
import net.runelite.http.api.ws.messages.party.UserPart; import net.runelite.http.api.ws.messages.party.UserPart;
import net.runelite.http.api.ws.messages.party.UserSync; import net.runelite.http.api.ws.messages.party.UserSync;
@@ -48,10 +53,12 @@ import net.runelite.http.api.ws.messages.party.UserSync;
public class PartyService public class PartyService
{ {
public static final int PARTY_MAX = 15; public static final int PARTY_MAX = 15;
private static final int MAX_MESSAGE_LEN = 150;
private final WSClient wsClient; private final WSClient wsClient;
private final SessionManager sessionManager; private final SessionManager sessionManager;
private final EventBus eventBus; private final EventBus eventBus;
private final ChatMessageManager chat;
private final List<PartyMember> members = new ArrayList<>(); private final List<PartyMember> members = new ArrayList<>();
@Getter @Getter
@@ -64,14 +71,16 @@ public class PartyService
private String username; private String username;
@Inject @Inject
private PartyService(final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus) private PartyService(final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat)
{ {
this.wsClient = wsClient; this.wsClient = wsClient;
this.sessionManager = sessionManager; this.sessionManager = sessionManager;
this.eventBus = eventBus; this.eventBus = eventBus;
this.chat = chat;
eventBus.subscribe(UserJoin.class, this, this::onUserJoin); eventBus.subscribe(UserJoin.class, this, this::onUserJoin);
eventBus.subscribe(UserPart.class, this, this::onUserPart); eventBus.subscribe(UserPart.class, this, this::onUserPart);
eventBus.subscribe(PartyChatMessage.class, this, this::onPartyChatMessage);
} }
public void changeParty(UUID newParty) public void changeParty(UUID newParty)
@@ -141,6 +150,26 @@ public class PartyService
members.removeIf(member -> member.getMemberId().equals(message.getMemberId())); members.removeIf(member -> member.getMemberId().equals(message.getMemberId()));
} }
private void onPartyChatMessage(final PartyChatMessage message)
{
// Remove non-printable characters, and <img> tags from message
String sentMesage = JAGEX_PRINTABLE_CHAR_MATCHER.retainFrom(message.getValue())
.replaceAll("<img=.+>", "");
// Cap the mesage length
if (sentMesage.length() > MAX_MESSAGE_LEN)
{
sentMesage = sentMesage.substring(0, MAX_MESSAGE_LEN);
}
chat.queue(QueuedMessage.builder()
.type(ChatMessageType.FRIENDSCHAT)
.sender("Party")
.name(getMemberById(message.getMemberId()).getName())
.runeLiteFormattedMessage(sentMesage)
.build());
}
public PartyMember getLocalMember() public PartyMember getLocalMember()
{ {
return getMemberByName(username); return getMemberByName(username);

View File

@@ -56,7 +56,7 @@
// C <chunk X 1> <chunk Y 1> <chunk X 2> <chunk Y 2> // C <chunk X 1> <chunk Y 1> <chunk X 2> <chunk Y 2>
// Sets the chunks relative to the last region/region1 to the current color and blending // Sets the chunks relative to the last region/region1 to the current color and blending
bounds 18 19 60 162 bounds 18 19 60 196
b 8 b 8
@@ -392,6 +392,9 @@ r 47 70
r 53 78 r 53 78
r 55 90 r 55 90
r 57 154 r 57 154
R 42 94 45 96
R 49 93 52 96
r 52 92
#b2b595 #b2b595
r 40 67 r 40 67
@@ -948,4 +951,13 @@ R 19 19 21 20
// Cosmic entity's plane // Cosmic entity's plane
#040404 #040404
r 32 75 r 32 75
b 0
#000000
// Song of the elves boss area
R 49 92 51 92
// Iorwerth dungeon
#030A0A
R 49 193 51 194

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info> * Copyright (c) 2019, Tomas Slusny <slusnucky@gmail.com>
* 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
@@ -35,4 +35,4 @@ public class RuneLiteModuleTest
{ {
Guice.createInjector(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true)); Guice.createInjector(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true));
} }
} }

View File

@@ -50,7 +50,6 @@ import net.runelite.client.RuneLite;
import net.runelite.client.RuneLiteModule; import net.runelite.client.RuneLiteModule;
import net.runelite.client.config.Config; import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
import net.runelite.client.rs.ClientUpdateCheckMode;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@@ -83,7 +82,7 @@ public class PluginManagerTest
public void before() throws IOException public void before() throws IOException
{ {
Injector injector = Guice.createInjector(Modules Injector injector = Guice.createInjector(Modules
.override(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true)) .override(new RuneLiteModule(() -> null, true))
.with(BoundFieldModule.of(this))); .with(BoundFieldModule.of(this)));
RuneLite.setInjector(injector); RuneLite.setInjector(injector);
@@ -107,7 +106,6 @@ public class PluginManagerTest
configClasses.add(clazz); configClasses.add(clazz);
} }
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -142,7 +140,7 @@ public class PluginManagerTest
{ {
List<Module> modules = new ArrayList<>(); List<Module> modules = new ArrayList<>();
modules.add(new GraphvizModule()); modules.add(new GraphvizModule());
modules.add(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true)); modules.add(new RuneLiteModule(() -> null, true));
PluginManager pluginManager = new PluginManager(true, null, null, null, null, null); PluginManager pluginManager = new PluginManager(true, null, null, null, null, null);
pluginManager.loadCorePlugins(); pluginManager.loadCorePlugins();

View File

@@ -226,4 +226,22 @@ public class ChatCommandsPluginTest
verify(configManager).setConfiguration("killcount.adam", "duel arena losses", 999); verify(configManager).setConfiguration("killcount.adam", "duel arena losses", 999);
} }
@Test
public void testAgilityLap()
{
final String NEW_PB = "Lap duration: <col=ff0000>1:01</col> (new personal best).";
when(client.getUsername()).thenReturn("Adam");
// This sets lastBoss
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Prifddinas Agility Course lap count is: <col=ff0000>2</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", NEW_PB, null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setConfiguration(eq("personalbest.adam"), eq("prifddinas agility course"), eq(61));
verify(configManager).setConfiguration(eq("killcount.adam"), eq("prifddinas agility course"), eq(2));
}
} }

View File

@@ -26,7 +26,6 @@
package net.runelite.client.rs; package net.runelite.client.rs;
import java.io.IOException; import java.io.IOException;
import okhttp3.OkHttpClient;
import org.junit.Test; import org.junit.Test;
/** /**
@@ -38,8 +37,7 @@ public class ClientConfigLoaderTest
@Test @Test
public void test() throws IOException public void test() throws IOException
{ {
final ClientConfigLoader loader = new ClientConfigLoader(new OkHttpClient()); final RSConfig config = ClientConfigLoader.fetch();
final RSConfig config = loader.fetch();
for (String key : config.getClassLoaderProperties().keySet()) for (String key : config.getClassLoaderProperties().keySet())
{ {