diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java index 7c4d40e61c..92e852c7fa 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -101,6 +101,7 @@ public final class AnimationID public static final int SMITHING_SMELTING = 899; public static final int SMITHING_CANNONBALL = 827; //cball smithing uses this and SMITHING_SMELTING public static final int SMITHING_ANVIL = 898; + public static final int SMITHING_IMCANDO_HAMMER = 8911; public static final int FISHING_BIG_NET = 620; public static final int FISHING_NET = 621; public static final int FISHING_POLE_CAST = 623; // pole is in the water @@ -205,6 +206,7 @@ public final class AnimationID public static final int LEAGUE_HOME_TELEPORT_6 = 8807; public static final int CONSTRUCTION = 3676; + public static final int CONSTRUCTION_IMCANDO = 8192; public static final int SAND_COLLECTION = 895; public static final int PISCARILIUS_CRANE_REPAIR = 7199; public static final int HOME_MAKE_TABLET = 4067; diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 2a7a6ca2fe..095af54819 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -2174,4 +2174,19 @@ public interface Client extends GameEngine * use createBuffer to create a new byte buffer */ Buffer createBuffer(byte[] initialBytes); + + /** + * Get the list of message ids for the recently received cross-world messages. The upper 32 bits of the + * id is the world id, the lower is a sequence number per-world. + * + * @return + */ + long[] getCrossWorldMessageIds(); + + /** + * Get the index of the next message to be inserted in the cross world message id list + * + * @return + */ + int getCrossWorldMessageIdsIndex(); } diff --git a/runelite-api/src/main/java/net/runelite/api/PlayerComposition.java b/runelite-api/src/main/java/net/runelite/api/PlayerComposition.java index 1512b02f33..37b04762a1 100644 --- a/runelite-api/src/main/java/net/runelite/api/PlayerComposition.java +++ b/runelite-api/src/main/java/net/runelite/api/PlayerComposition.java @@ -38,6 +38,13 @@ public interface PlayerComposition */ boolean isFemale(); + /** + * Get the body part colors for this player composition. + * + * @return an array of the colors, always size 5 + */ + int[] getColors(); + /** * Gets an array of IDs related to equipment slots. *
diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java
index a6a4b1af61..d1fb730f86 100644
--- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java
+++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java
@@ -433,7 +433,8 @@ public enum WidgetInfo
EXPERIENCE_TRACKER_WIDGET(WidgetID.EXPERIENCE_TRACKER_GROUP_ID, WidgetID.ExperienceTracker.WIDGET),
EXPERIENCE_TRACKER_BOTTOM_BAR(WidgetID.EXPERIENCE_TRACKER_GROUP_ID, WidgetID.ExperienceTracker.BOTTOM_BAR),
- FISHING_TRAWLER_TIMER(WidgetID.FISHING_TRAWLER_GROUP_ID, 14),
+ FISHING_TRAWLER_CONTRIBUTION(WidgetID.FISHING_TRAWLER_GROUP_ID, 14),
+ FISHING_TRAWLER_TIMER(WidgetID.FISHING_TRAWLER_GROUP_ID, 15),
TITHE_FARM(WidgetID.TITHE_FARM_GROUP_ID, 3),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java
index ef9754d6ff..147b0427bb 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/ArdougneDiaryRequirement.java
@@ -105,7 +105,7 @@ public class ArdougneDiaryRequirement extends GenericDiaryRequirement
add("Smith a Dragon sq shield in West Ardougne.",
new SkillRequirement(Skill.SMITHING, 60),
new QuestRequirement(Quest.LEGENDS_QUEST));
- add("Craft some Death runes.",
+ add("Craft some Death runes from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 65),
new QuestRequirement(Quest.MOURNINGS_END_PART_II));
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java
index 30f7843199..fc4efddea2 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java
@@ -84,7 +84,7 @@ public class FaladorDiaryRequirement extends GenericDiaryRequirement
new SkillRequirement(Skill.MAGIC, 37));
// HARD
- add("Craft 140 Mind runes simultaneously.",
+ add("Craft 140 Mind runes simultaneously from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 56));
add("Change your family crest to the Saradomin symbol.",
new SkillRequirement(Skill.PRAYER, 70));
@@ -106,7 +106,7 @@ public class FaladorDiaryRequirement extends GenericDiaryRequirement
new QuestRequirement(Quest.GRIM_TALES));
// ELITE
- add("Craft 252 Air Runes simultaneously.",
+ add("Craft 252 Air Runes simultaneously from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 88));
add("Purchase a White 2h Sword from Sir Vyvin.",
new QuestRequirement(Quest.WANTED));
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
index 46c708efbb..f4a8808322 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
@@ -111,7 +111,7 @@ public class FremennikDiaryRequirement extends GenericDiaryRequirement
new QuestRequirement(Quest.THE_GIANT_DWARF, true));
// ELITE
- add("Craft 56 astral runes at once.",
+ add("Craft 56 astral runes at once from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 82),
new QuestRequirement(Quest.LUNAR_DIPLOMACY));
add("Create a dragonstone amulet in the Neitiznot furnace.",
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java
index acdae10ce3..db04602d53 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java
@@ -96,7 +96,7 @@ public class KaramjaDiaryRequirement extends GenericDiaryRequirement
);
// HARD
- add("Craft some nature runes.",
+ add("Craft some nature runes from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 44),
new QuestRequirement(Quest.RUNE_MYSTERIES));
add("Cook a karambwan thoroughly.",
@@ -122,7 +122,7 @@ public class KaramjaDiaryRequirement extends GenericDiaryRequirement
new QuestRequirement(Quest.SHILO_VILLAGE));
// ELITE
- add("Craft 56 Nature runes at once.",
+ add("Craft 56 Nature runes at once from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 91));
add("Check the health of a palm tree in Brimhaven.",
new SkillRequirement(Skill.FARMING, 68));
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java
index 182b288a3b..2cde458c8e 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KourendDiaryRequirement.java
@@ -110,7 +110,7 @@ public class KourendDiaryRequirement extends GenericDiaryRequirement
new QuestRequirement(Quest.DREAM_MENTOR));
//ELITE
- add("Craft one or more Blood runes.",
+ add("Craft one or more Blood runes from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 77),
new SkillRequirement(Skill.MINING, 38),
new SkillRequirement(Skill.CRAFTING, 38),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java
index 7238e18a55..f729082db2 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java
@@ -43,7 +43,7 @@ public class LumbridgeDiaryRequirement extends GenericDiaryRequirement
new SkillRequirement(Skill.SLAYER, 7));
add("Have Sedridor teleport you to the Essence Mine.",
new QuestRequirement(Quest.RUNE_MYSTERIES));
- add("Craft some water runes.",
+ add("Craft some water runes from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 5),
new QuestRequirement(Quest.RUNE_MYSTERIES));
add("Chop and burn some oak logs in Lumbridge.",
@@ -94,7 +94,7 @@ public class LumbridgeDiaryRequirement extends GenericDiaryRequirement
add("Squeeze past the jutting wall on your way to the cosmic altar.",
new SkillRequirement(Skill.AGILITY, 46),
new QuestRequirement(Quest.LOST_CITY));
- add("Craft 56 Cosmic runes simultaneously.",
+ add("Craft 56 Cosmic runes simultaneously from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 59),
new QuestRequirement(Quest.LOST_CITY));
add("Travel from Lumbridge to Edgeville on a Waka Canoe.",
@@ -128,7 +128,7 @@ public class LumbridgeDiaryRequirement extends GenericDiaryRequirement
new SkillRequirement(Skill.WOODCUTTING, 75));
add("Smith an Adamant platebody down Draynor sewer.",
new SkillRequirement(Skill.SMITHING, 88));
- add("Craft 140 or more Water runes at once.",
+ add("Craft 140 or more Water runes at once from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 76),
new QuestRequirement(Quest.RUNE_MYSTERIES));
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java
index bff800b4c2..b5c8aeb2db 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java
@@ -46,7 +46,7 @@ public class VarrockDiaryRequirement extends GenericDiaryRequirement
new SkillRequirement(Skill.AGILITY, 13));
add("Spin a bowl on the pottery wheel and fire it in the oven in Barb Village.",
new SkillRequirement(Skill.CRAFTING, 8));
- add("Craft some Earth runes.",
+ add("Craft some Earth runes from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 9));
add("Catch some trout in the River Lum at Barbarian Village.",
new SkillRequirement(Skill.FISHING, 20));
@@ -112,7 +112,7 @@ public class VarrockDiaryRequirement extends GenericDiaryRequirement
new SkillRequirement(Skill.SMITHING, 89),
new SkillRequirement(Skill.FLETCHING, 81),
new QuestRequirement(Quest.THE_TOURIST_TRAP));
- add("Craft 100 or more earth runes simultaneously.",
+ add("Craft 100 or more earth runes simultaneously from Essence.",
new SkillRequirement(Skill.RUNECRAFT, 78),
new QuestRequirement(Quest.RUNE_MYSTERIES));
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java
index 1f9aeeaa25..535a50b19a 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java
@@ -39,6 +39,7 @@ import net.runelite.api.GameObject;
import net.runelite.api.GameState;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
+import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
import static net.runelite.api.ObjectID.CANNON_BASE;
import net.runelite.api.Player;
@@ -301,6 +302,23 @@ public class CannonPlugin extends Plugin
cannonPlaced = true;
addCounter();
cballsLeft = 0;
+
+ final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
+ if (inventory != null)
+ {
+ int invCballs = inventory.count(ItemID.GRANITE_CANNONBALL) > 0
+ ? inventory.count(ItemID.GRANITE_CANNONBALL)
+ : inventory.count(ItemID.CANNONBALL);
+ // Cannonballs are always forcibly loaded after the furnace is added. If the player has more than
+ // the max number of cannon balls in their inventory, the cannon will always be fully filled.
+ // This is preferable to using the proceeding "You load the cannon with x cannon balls" message
+ // since it will show a lower number of cannon balls if the cannon is already partially-filled
+ // prior to being placed.
+ if (invCballs >= MAX_CBALLS)
+ {
+ cballsLeft = MAX_CBALLS;
+ }
+ }
}
if (event.getMessage().contains("You pick up the cannon")
@@ -366,6 +384,15 @@ public class CannonPlugin extends Plugin
}
}
+ if (event.getMessage().startsWith("Your cannon contains"))
+ {
+ Matcher m = NUMBER_PATTERN.matcher(event.getMessage());
+ if (m.find())
+ {
+ cballsLeft = Integer.parseInt(m.group());
+ }
+ }
+
if (event.getMessage().startsWith("You unload your cannon and receive Cannonball")
|| event.getMessage().startsWith("You unload your cannon and receive Granite cannonball"))
{
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java
index d33a0e6b29..8fc616fcde 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java
@@ -1156,6 +1156,18 @@ public class ClueScrollPlugin extends Plugin
return mapClue.getObjectId() == -1 && itemId == ItemID.SPADE;
}
+ else if (c instanceof SkillChallengeClue)
+ {
+ SkillChallengeClue challengeClue = (SkillChallengeClue) c;
+
+ for (ItemRequirement ir : challengeClue.getItemRequirements())
+ {
+ if (ir.fulfilledBy(itemId))
+ {
+ return true;
+ }
+ }
+ }
return false;
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java
index a36b967fae..e76e588cc5 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java
@@ -179,7 +179,12 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
any("", item(ItemID.GRACEFUL_GLOVES), item(ItemID.GRACEFUL_GLOVES_11859), item(ItemID.GRACEFUL_GLOVES_13587), item(ItemID.GRACEFUL_GLOVES_13588), item(ItemID.GRACEFUL_GLOVES_13599), item(ItemID.GRACEFUL_GLOVES_13600), item(ItemID.GRACEFUL_GLOVES_13611), item(ItemID.GRACEFUL_GLOVES_13612), item(ItemID.GRACEFUL_GLOVES_13623), item(ItemID.GRACEFUL_GLOVES_13624), item(ItemID.GRACEFUL_GLOVES_13635), item(ItemID.GRACEFUL_GLOVES_13636), item(ItemID.GRACEFUL_GLOVES_13675), item(ItemID.GRACEFUL_GLOVES_13676), item(ItemID.GRACEFUL_GLOVES_21073), item(ItemID.GRACEFUL_GLOVES_21075), item(ItemID.GRACEFUL_GLOVES_24755), item(ItemID.GRACEFUL_GLOVES_24757), item(ItemID.GRACEFUL_GLOVES_25081), item(ItemID.GRACEFUL_GLOVES_25083)),
any("", item(ItemID.GRACEFUL_BOOTS), item(ItemID.GRACEFUL_BOOTS_11861), item(ItemID.GRACEFUL_BOOTS_13589), item(ItemID.GRACEFUL_BOOTS_13590), item(ItemID.GRACEFUL_BOOTS_13601), item(ItemID.GRACEFUL_BOOTS_13602), item(ItemID.GRACEFUL_BOOTS_13613), item(ItemID.GRACEFUL_BOOTS_13614), item(ItemID.GRACEFUL_BOOTS_13625), item(ItemID.GRACEFUL_BOOTS_13626), item(ItemID.GRACEFUL_BOOTS_13637), item(ItemID.GRACEFUL_BOOTS_13638), item(ItemID.GRACEFUL_BOOTS_13677), item(ItemID.GRACEFUL_BOOTS_13678), item(ItemID.GRACEFUL_BOOTS_21076), item(ItemID.GRACEFUL_BOOTS_21078), item(ItemID.GRACEFUL_BOOTS_24758), item(ItemID.GRACEFUL_BOOTS_24760), item(ItemID.GRACEFUL_BOOTS_25084), item(ItemID.GRACEFUL_BOOTS_25086)))),
new SkillChallengeClue("Mix an anti-venom potion.", item(ItemID.ANTIDOTE4_5952), xOfItem(ItemID.ZULRAHS_SCALES, 20)),
- new SkillChallengeClue("Mine a piece of Runite ore", "mine a piece of runite ore whilst sporting the finest mining gear.", true, ANY_PICKAXE, all("Prospector kit", item(ItemID.PROSPECTOR_HELMET), any("", item(ItemID.PROSPECTOR_JACKET), item(ItemID.VARROCK_ARMOUR_4)), item(ItemID.PROSPECTOR_LEGS), item(ItemID.PROSPECTOR_BOOTS))),
+ new SkillChallengeClue("Mine a piece of Runite ore", "mine a piece of runite ore whilst sporting the finest mining gear.", true, ANY_PICKAXE,
+ all("Prospector kit",
+ any("", item(ItemID.PROSPECTOR_HELMET), item(ItemID.GOLDEN_PROSPECTOR_HELMET)),
+ any("", item(ItemID.PROSPECTOR_JACKET), item(ItemID.VARROCK_ARMOUR_4), item(ItemID.GOLDEN_PROSPECTOR_JACKET)),
+ any("", item(ItemID.PROSPECTOR_LEGS), item(ItemID.GOLDEN_PROSPECTOR_LEGS)),
+ any("", item(ItemID.PROSPECTOR_BOOTS), item(ItemID.GOLDEN_PROSPECTOR_BOOTS)))),
new SkillChallengeClue("Steal a gem from the Ardougne market."),
new SkillChallengeClue("Pickpocket an elf."),
new SkillChallengeClue("Bind a blood rune at the blood altar.", item(ItemID.DARK_ESSENCE_FRAGMENTS)),
@@ -188,7 +193,12 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
new SkillChallengeClue("Cremate a set of fiyr remains.", any("Magic or Redwood Pyre Logs", item(ItemID.MAGIC_PYRE_LOGS), item(ItemID.REDWOOD_PYRE_LOGS)), item(ItemID.TINDERBOX), item(ItemID.FIYR_REMAINS)),
new SkillChallengeClue("Dissect a sacred eel.", item(ItemID.KNIFE), any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.FISHING_BAIT)),
new SkillChallengeClue("Kill a lizardman shaman."),
- new SkillChallengeClue("Catch an Anglerfish.", "angle for an anglerfish whilst sporting the finest fishing gear.", true, any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.SANDWORMS), all("Angler's outfit", item(ItemID.ANGLER_HAT), item(ItemID.ANGLER_TOP), item(ItemID.ANGLER_WADERS), item(ItemID.ANGLER_BOOTS))),
+ new SkillChallengeClue("Catch an Anglerfish.", "angle for an anglerfish whilst sporting the finest fishing gear.", true, any("Fishing rod", item(ItemID.FISHING_ROD), item(ItemID.PEARL_FISHING_ROD)), item(ItemID.SANDWORMS),
+ all("Angler's outfit",
+ any("", item(ItemID.ANGLER_HAT), item(ItemID.SPIRIT_ANGLER_HEADBAND)),
+ any("", item(ItemID.ANGLER_TOP), item(ItemID.SPIRIT_ANGLER_TOP)),
+ any("", item(ItemID.ANGLER_WADERS), item(ItemID.SPIRIT_ANGLER_WADERS)),
+ any("", item(ItemID.ANGLER_BOOTS), item(ItemID.SPIRIT_ANGLER_BOOTS)))),
new SkillChallengeClue("Chop a redwood log.", "chop a redwood log whilst sporting the finest lumberjack gear.", true, ANY_AXE, all("Lumberjack outfit", item(ItemID.LUMBERJACK_HAT), item(ItemID.LUMBERJACK_TOP), item(ItemID.LUMBERJACK_LEGS), item(ItemID.LUMBERJACK_BOOTS))),
new SkillChallengeClue("Craft a light orb in the Dorgesh-Kaan bank.", item(ItemID.CAVE_GOBLIN_WIRE), item(ItemID.EMPTY_LIGHT_ORB)),
new SkillChallengeClue("Kill a reanimated Abyssal Demon.", "kill a reanimated abyssal.", xOfItem(ItemID.SOUL_RUNE, 4), xOfItem(ItemID.BLOOD_RUNE, 1), any("Nature Rune x4", xOfItem(ItemID.NATURE_RUNE, 4), item(ItemID.BRYOPHYTAS_STAFF)), range("Ensouled abyssal head", ItemID.ENSOULED_ABYSSAL_HEAD, ItemID.ENSOULED_ABYSSAL_HEAD_13508)),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingConfig.java
index 4aed364903..f0f37fdbc5 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingConfig.java
@@ -173,22 +173,22 @@ public interface FishingConfig extends Config
@ConfigItem(
position = 11,
- keyName = "trawlerNotification",
- name = "Trawler activity notification",
- description = "Send a notification when fishing trawler activity drops below 15%."
+ keyName = "trawlerTimer",
+ name = "Trawler timer in M:SS",
+ description = "Trawler timer will display a more accurate timer in M:SS format."
)
- default boolean trawlerNotification()
+ default boolean trawlerTimer()
{
return true;
}
@ConfigItem(
position = 12,
- keyName = "trawlerTimer",
- name = "Trawler timer in MM:SS",
- description = "Trawler Timer will display a more accurate timer in MM:SS format."
+ keyName = "trawlerContribution",
+ name = "Trawler contribution",
+ description = "Display the exact number of trawler contribution points gained."
)
- default boolean trawlerTimer()
+ default boolean trawlerContribution()
{
return true;
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java
index e782b81428..66e57e7d52 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java
@@ -57,7 +57,6 @@ import net.runelite.api.events.InteractingChanged;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
-import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
@@ -86,8 +85,7 @@ public class FishingPlugin extends Plugin
{
private static final int TRAWLER_SHIP_REGION_NORMAL = 7499;
private static final int TRAWLER_SHIP_REGION_SINKING = 8011;
- private static final int TRAWLER_TIME_LIMIT_IN_SECONDS = 614;
- private static final int TRAWLER_ACTIVITY_THRESHOLD = Math.round(0.15f * 255);
+ private static final int TRAWLER_TIME_LIMIT_IN_SECONDS = 314;
private Instant trawlerStartTime;
@@ -124,8 +122,6 @@ public class FishingPlugin extends Plugin
@Inject
private FishingSpotMinimapOverlay fishingSpotMinimapOverlay;
- private boolean trawlerNotificationSent;
-
@Provides
FishingConfig provideConfig(ConfigManager configManager)
{
@@ -150,7 +146,6 @@ public class FishingPlugin extends Plugin
overlayManager.remove(fishingSpotMinimapOverlay);
fishingSpots.clear();
minnowSpots.clear();
- trawlerNotificationSent = false;
currentSpot = null;
trawlerStartTime = null;
}
@@ -328,10 +323,8 @@ public class FishingPlugin extends Plugin
}
}
- if (config.trawlerTimer())
- {
- updateTrawlerTimer();
- }
+ updateTrawlerTimer();
+ updateTrawlerContribution();
}
@Subscribe
@@ -362,40 +355,42 @@ public class FishingPlugin extends Plugin
}
}
- @Subscribe
- public void onVarbitChanged(VarbitChanged event)
- {
- if (!config.trawlerNotification() || client.getGameState() != GameState.LOGGED_IN)
- {
- return;
- }
-
- int regionID = client.getLocalPlayer().getWorldLocation().getRegionID();
-
- if ((regionID == TRAWLER_SHIP_REGION_NORMAL || regionID == TRAWLER_SHIP_REGION_SINKING)
- && client.getVar(Varbits.FISHING_TRAWLER_ACTIVITY) <= TRAWLER_ACTIVITY_THRESHOLD)
- {
- if (!trawlerNotificationSent)
- {
- notifier.notify("You have low Fishing Trawler activity!");
- trawlerNotificationSent = true;
- }
- }
- else
- {
- trawlerNotificationSent = false;
- }
- }
-
@Subscribe
public void onWidgetLoaded(WidgetLoaded event)
{
if (event.getGroupId() == WidgetID.FISHING_TRAWLER_GROUP_ID)
{
trawlerStartTime = Instant.now();
+ log.debug("Trawler session started");
}
}
+ /**
+ * Updates the trawler contribution value
+ */
+ private void updateTrawlerContribution()
+ {
+ int regionID = client.getLocalPlayer().getWorldLocation().getRegionID();
+ if (regionID != TRAWLER_SHIP_REGION_NORMAL && regionID != TRAWLER_SHIP_REGION_SINKING)
+ {
+ return;
+ }
+
+ if (!config.trawlerContribution())
+ {
+ return;
+ }
+
+ Widget trawlerContributionWidget = client.getWidget(WidgetInfo.FISHING_TRAWLER_CONTRIBUTION);
+ if (trawlerContributionWidget == null)
+ {
+ return;
+ }
+
+ int trawlerContribution = client.getVar(Varbits.FISHING_TRAWLER_ACTIVITY);
+ trawlerContributionWidget.setText("Contribution: " + trawlerContribution);
+ }
+
/**
* Changes the Fishing Trawler timer widget from minutes to minutes and seconds
*/
@@ -414,6 +409,11 @@ public class FishingPlugin extends Plugin
return;
}
+ if (!config.trawlerTimer())
+ {
+ return;
+ }
+
Widget trawlerTimerWidget = client.getWidget(WidgetInfo.FISHING_TRAWLER_TIMER);
if (trawlerTimerWidget == null)
{
@@ -438,7 +438,7 @@ public class FishingPlugin extends Plugin
}
else
{
- trawlerText.append("00");
+ trawlerText.append('0');
}
trawlerText.append(':');
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java
new file mode 100644
index 0000000000..441820c465
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendlist/FriendListConfig.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021, Maciej
You can only add cannonballs of the same kind.");
+
+ plugin.onChatMessage(message);
+
+ assertEquals(20, plugin.getCballsLeft());
+ }
+
+ @Test
+ public void addMaxCannonballs()
+ {
+ final ItemContainer inventory = mock(ItemContainer.class);
+ when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory);
+ when(inventory.count(ItemID.CANNONBALL)).thenReturn(100);
+ when(inventory.count(ItemID.GRANITE_CANNONBALL)).thenReturn(0);
+
+ plugin.onChatMessage(ADD_FURNACE);
+ assertTrue(plugin.isCannonPlaced());
+
+ assertEquals(30, plugin.getCballsLeft());
+
+ plugin.onChatMessage(loadCannonballs(30));
+ assertEquals(30, plugin.getCballsLeft());
+ }
+
+ @Test
+ public void addNotMaxCannonballs()
+ {
+ final ItemContainer inventory = mock(ItemContainer.class);
+ when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory);
+ when(inventory.count(ItemID.GRANITE_CANNONBALL)).thenReturn(12);
+
+ plugin.onChatMessage(ADD_FURNACE);
+ assertTrue(plugin.isCannonPlaced());
+
+ assertEquals(0, plugin.getCballsLeft());
+
+ plugin.onChatMessage(loadCannonballs(12));
+ assertEquals(12, plugin.getCballsLeft());
+ }
+
+ @Test
+ public void addReclaimedCannonballs()
+ {
+ final ItemContainer inventory = mock(ItemContainer.class);
+ when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory);
+ when(inventory.count(ItemID.CANNONBALL)).thenReturn(1250);
+
+ plugin.onChatMessage(ADD_FURNACE);
+ assertTrue(plugin.isCannonPlaced());
+
+ assertEquals(30, plugin.getCballsLeft());
+
+ plugin.onChatMessage(loadCannonballs(18));
+ assertEquals(30, plugin.getCballsLeft());
+ }
+
+ private static ChatMessage loadCannonballs(final int numCannonballs)
+ {
+ final ChatMessage message = new ChatMessage();
+ message.setType(ChatMessageType.GAMEMESSAGE);
+
+ // Cannons use the same chat message for loading cannonballs regardless of whether they're normal or granite.
+ if (numCannonballs == 1)
+ {
+ message.setMessage("You load the cannon with one cannonball.");
+ }
+ else
+ {
+ message.setMessage(String.format("You load the cannon with %s cannonballs.", numCannonballs));
+ }
+
+ return message;
+ }
+
+}
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java
new file mode 100644
index 0000000000..4b3fd12f32
--- /dev/null
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/friendlist/FriendListPluginTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2021, Maciej