diff --git a/pom.xml b/pom.xml index 9437d2f488..d9a35dbab6 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ UTF-8 + false 1.8 1.18.4 8.3 @@ -53,7 +54,7 @@ 0.7 3.0.2 - 3.6.1 + 3.8.1 2.17 3.0.0-M1 2.5.3 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 d57b288af4..07a2f68ce6 100644 --- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -164,6 +164,7 @@ public final class AnimationID public static final int BLOCK_SHIELD = 1156; public static final int BLOCK_SWORD = 388; public static final int BLOCK_UNARMED = 424; // Same Animation as failed pickpocked + public static final int DRAGONFIRE_SHIELD_SPECIAL = 6696; // NPC animations public static final int TZTOK_JAD_RANGE_ATTACK = 2652; 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 4b0748ff0e..f19fdea2e3 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1685,4 +1685,13 @@ public interface Client extends GameShell */ void sortMenuEntries(); + /** + * Add player to friendlist + */ + void addFriend(String name); + + /** + * Remove player from friendlist + */ + void removeFriend(String name); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java index 7db0667088..31a987bf14 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java @@ -36,6 +36,7 @@ import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.Point; import net.runelite.api.Tile; +import net.runelite.api.coords.LocalPoint; import net.runelite.client.game.AgilityShortcut; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; @@ -45,6 +46,7 @@ import net.runelite.client.ui.overlay.OverlayUtil; @Singleton class AgilityOverlay extends Overlay { + private static final int MAX_DISTANCE = 2350; private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE; private final Client client; @@ -63,6 +65,7 @@ class AgilityOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { + LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation(); Point mousePosition = client.getMouseCanvasPosition(); final List marksOfGrace = plugin.getMarksOfGrace(); plugin.getObstacles().forEach((object, obstacle) -> @@ -74,7 +77,8 @@ class AgilityOverlay extends Overlay } Tile tile = obstacle.getTile(); - if (tile.getPlane() == client.getPlane()) + if (tile.getPlane() == client.getPlane() + && object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) { // This assumes that the obstacle is not clickable. if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId())) @@ -117,7 +121,8 @@ class AgilityOverlay extends Overlay { for (Tile markOfGraceTile : marksOfGrace) { - if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null) + if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null + && markOfGraceTile.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE) { final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index 18124aae0d..dbd1bc413a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -138,7 +138,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("46 is my number. My body is the colour of burnt orange and crawls among those with eight. Three mouths I have, yet I cannot eat. My blinking blue eye hides my grave.", new WorldPoint(3170, 3885, 0), "Sapphire respawn in the Spider's Nest, lvl 46 Wilderness. Dig under the sapphire spawn."), new CrypticClue("Green is the colour of my death as the winter-guise, I swoop towards the ground.", new WorldPoint(2780, 3783, 0), "Players need to slide down to where Trollweiss grows on Trollweiss Mountain."), new CrypticClue("Talk to a party-goer in Falador.", "Lucy", new WorldPoint(3046, 3382, 0), "Lucy is the bartender on the first floor of the party room."), - new CrypticClue("He knows just how easy it is to lose track of time.", "Brother Kojo", new WorldPoint(2570, 3250, 0), "Speak to brother Kojo in the Clock Tower. Answer: 22"), + new CrypticClue("He knows just how easy it is to lose track of time.", "Brother Kojo", new WorldPoint(2570, 3250, 0), "Speak to Brother Kojo in the Clock Tower. Answer: 22"), new CrypticClue("A great view - watch the rapidly drying hides get splashed. Check the box you are sitting on.", BOXES, new WorldPoint(2523, 3493, 1), "Almera's House north of Baxtorian Falls, search boxes on the first floor."), new CrypticClue("Search the Coffin in Edgeville.", COFFIN, new WorldPoint(3091, 3477, 0), "Search the coffin located by the Wilderness teleport lever."), new CrypticClue("When no weapons are at hand, then is the time to reflect. In Saradomin's name, redemption draws closer...", DRAWERS_350, new WorldPoint(2818, 3351, 0), "On Entrana, search the southern drawer in the house with the cooking range."), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 5e2ec78add..121b1f395c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1692,4 +1692,4 @@ default CharterOption charterOption() { return true; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java index 13d25db98a..75335426cb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npcunaggroarea/NpcAggroAreaPlugin.java @@ -515,10 +515,16 @@ public class NpcAggroAreaPlugin extends Plugin void doNotification() { + if (!this.sendNotification) + { + return; + } + if (hasSentNotification) { return; } + final Player local = client.getLocalPlayer(); hasSentNotification = true; notifier.notify("[" + local.getName() + "]'s aggression timer has run out!"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java index 4332d38aa2..bc2ea6d984 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/safespot/SafeSpotPlugin.java @@ -119,15 +119,14 @@ public class SafeSpotPlugin extends Plugin updateSafeSpots(); } } + else if (tickCount > 0) + { + tickCount--; + } else { safeSpotsRenderable = false; } - if (tickCount > 0) - { - tickCount--; - safeSpotsRenderable = true; - } } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 53d957dcf3..97b51e82fb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -74,7 +74,8 @@ enum GameTimer MINIGAME_TELEPORT(SpriteID.TAB_QUESTS_RED_MINIGAMES, GameTimerImageType.SPRITE, "Minigame Teleport", 20, ChronoUnit.MINUTES), SKULL(SpriteID.PLAYER_KILLER_SKULL_523, GameTimerImageType.SPRITE, "Skull", 20, ChronoUnit.MINUTES), ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Antipoison"), - ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom"); + ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom"), + DRAGON_FIRE_SHIELD(ItemID.DRAGONFIRE_SHIELD_11284, GameTimerImageType.ITEM, "Dragonfire Shield Special", 2, ChronoUnit.MINUTES); @Getter(AccessLevel.PACKAGE) private final Duration duration; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java index 39f228d994..320509b301 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersConfig.java @@ -210,4 +210,14 @@ public interface TimersConfig extends Config { return true; } + + @ConfigItem( + keyName = "showDfsSpecial", + name = "Dragonfire Shield special timer", + description = "Configures whether the special attack cooldown timer for the Dragonfire Shield is displayed" + ) + default boolean showDFSSpecial() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index 1b3cbfeb62..36ac85610f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -736,6 +736,11 @@ public class TimersPlugin extends Plugin } } + if (config.showDFSSpecial() && lastAnimation == AnimationID.DRAGONFIRE_SHIELD_SPECIAL) + { + createGameTimer(DRAGON_FIRE_SHIELD); + } + lastAnimation = client.getLocalPlayer().getAnimation(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index bb5fbda991..67552394c9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.worldhopper; +import com.google.common.collect.Ordering; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -33,7 +34,7 @@ import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Map; -import javax.inject.Singleton; +import java.util.function.Function; import javax.swing.JPanel; import javax.swing.SwingUtilities; import lombok.AccessLevel; @@ -46,7 +47,6 @@ import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldType; @Slf4j -@Singleton class WorldSwitcherPanel extends PluginPanel { private static final Color ODD_ROW = new Color(44, 44, 44); @@ -161,24 +161,28 @@ class WorldSwitcherPanel extends PluginPanel switch (orderIndex) { case PING: - return Integer.compare(r1.getPing(), r2.getPing()) * (ascendingOrder ? 1 : -1); + // Leave worlds with unknown ping at the bottom + return getCompareValue(r1, r2, row -> + { + int ping = row.getPing(); + return ping > 0 ? ping : null; + }); case WORLD: - return Integer.compare(r1.getWorld().getId(), r2.getWorld().getId()) * (ascendingOrder ? 1 : -1); + return getCompareValue(r1, r2, row -> row.getWorld().getId()); case PLAYERS: - return Integer.compare(r1.getUpdatedPlayerCount(), r2.getUpdatedPlayerCount()) * (ascendingOrder ? 1 : -1); + return getCompareValue(r1, r2, WorldTableRow::getUpdatedPlayerCount); case ACTIVITY: - return r1.getWorld().getActivity().compareTo(r2.getWorld().getActivity()) * -1 * (ascendingOrder ? 1 : -1); + // Leave empty activity worlds on the bottom of the list + return getCompareValue(r1, r2, row -> + { + String activity = row.getWorld().getActivity(); + return !activity.equals("-") ? activity : null; + }); default: return 0; } }); - // Leave empty activity worlds on the bottom of the list - if (orderIndex == WorldOrder.ACTIVITY) - { - rows.sort((r1, r2) -> r1.getWorld().getActivity().equals("-") ? 1 : -1); - } - rows.sort((r1, r2) -> { boolean b1 = plugin.isFavorite(r1.getWorld()); @@ -199,6 +203,17 @@ class WorldSwitcherPanel extends PluginPanel listContainer.repaint(); } + private int getCompareValue(WorldTableRow row1, WorldTableRow row2, Function compareByFn) + { + Ordering ordering = Ordering.natural(); + if (!ascendingOrder) + { + ordering = ordering.reverse(); + } + ordering = ordering.nullsLast(); + return ordering.compare(compareByFn.apply(row1), compareByFn.apply(row2)); + } + void updateFavoriteMenu(int world, boolean favorite) { for (WorldTableRow row : rows) @@ -398,4 +413,4 @@ class WorldSwitcherPanel extends PluginPanel ACTIVITY, PING } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java b/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java index 6b61a6a78f..1a528f75aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ContainableFrame.java @@ -125,23 +125,28 @@ public class ContainableFrame extends JFrame if (forcedWidthIncrease || expandResizeType == ExpandResizeType.KEEP_GAME_SIZE) { final int newWindowWidth = getWidth() + increment; - final Rectangle screenBounds = getGraphicsConfiguration().getBounds(); - final boolean wouldExpandThroughEdge = getX() + newWindowWidth > screenBounds.getX() + screenBounds.getWidth(); int newWindowX = getX(); - if (wouldExpandThroughEdge) + if (containedInScreen) { - if (!isFrameCloseToRightEdge() || isFrameCloseToLeftEdge()) + final Rectangle screenBounds = getGraphicsConfiguration().getBounds(); + final boolean wouldExpandThroughEdge = getX() + newWindowWidth > screenBounds.getX() + screenBounds.getWidth(); + + if (wouldExpandThroughEdge) { - // Move the window to the edge - newWindowX = (int) (screenBounds.getX() + screenBounds.getWidth()) - getWidth(); + + if (!isFrameCloseToRightEdge() || isFrameCloseToLeftEdge()) + { + // Move the window to the edge + newWindowX = (int) (screenBounds.getX() + screenBounds.getWidth()) - getWidth(); + } + + // Expand the window to the left as the user probably don't want the + // window to go through the screen + newWindowX -= increment; + + expandedClientOppositeDirection = true; } - - // Expand the window to the left as the user probably don't want the - // window to go through the screen - newWindowX -= increment; - - expandedClientOppositeDirection = true; } setBounds(newWindowX, getY(), newWindowWidth, getHeight()); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index c552baaa6a..c00cc189ad 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1622,4 +1622,20 @@ public abstract class RSClientMixin implements RSClient return hideFriendAttackOptions && (p.isFriended() || p.isClanMember()); } + + @Inject + @Override + public void addFriend(String friend) + { + RSFriendSystem friendSystem = getFriendManager(); + friendSystem.addFriend(friend); + } + + @Inject + @Override + public void removeFriend(String friend) + { + RSFriendSystem friendSystem = getFriendManager(); + friendSystem.removeFriend(friend); + } } \ No newline at end of file diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java index 017971b308..ce0977f4a8 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSFriendSystem.java @@ -13,4 +13,10 @@ public interface RSFriendSystem extends FriendManager @Import("isFriended") boolean isFriended(RSUsername var1, boolean var2); + + @Import("addFriend") + void addFriend(String username); + + @Import("removeFriend") + void removeFriend(String username); }