From d9a4132f62be2f7a1a0d743ae2341cf0839eafee Mon Sep 17 00:00:00 2001 From: Robbe Date: Sun, 30 Nov 2025 20:29:04 +0200 Subject: [PATCH 1/4] Add low HP notification feature for boats --- .../duckblade/osrs/sailing/SailingConfig.java | 32 ++++++++ .../shipcombat/LowHPNotification.java | 82 +++++++++++++++++++ .../osrs/sailing/module/SailingModule.java | 7 +- 3 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java diff --git a/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java b/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java index b5c0343d..d7f6c428 100644 --- a/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java +++ b/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java @@ -96,6 +96,14 @@ public interface SailingConfig extends Config ) String SECTION_OCEAN_ENCOUNTERS = "oceanEncounters"; + @ConfigSection( + name = "Ship Combat", + description = "Settings for ship combat and health monitoring.", + position = 1100, + closedByDefault = true + ) + String SECTION_SHIP_COMBAT = "shipCombat"; + @ConfigItem( keyName = "highlightRapids", name = "Highlight Rapids", @@ -759,4 +767,28 @@ default Notification notifyOceanManSpawn() { return Notification.OFF; } + + @ConfigItem( + keyName = "notifyLowBoatHP", + name = "Notify on Low Boat HP", + description = "Notify when your boat's hitpoints drop below the threshold.", + section = SECTION_SHIP_COMBAT, + position = 1 + ) + default Notification notifyLowBoatHP() + { + return Notification.OFF; + } + + @ConfigItem( + keyName = "lowBoatHPThreshold", + name = "Low HP Threshold", + description = "The hitpoint threshold at which to notify you. Notification will trigger when boat HP drops below this value.", + section = SECTION_SHIP_COMBAT, + position = 2 + ) + default int lowBoatHPThreshold() + { + return 50; + } } diff --git a/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java b/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java new file mode 100644 index 00000000..da288f30 --- /dev/null +++ b/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java @@ -0,0 +1,82 @@ +package com.duckblade.osrs.sailing.features.shipcombat; + +import com.duckblade.osrs.sailing.SailingConfig; +import com.duckblade.osrs.sailing.features.util.BoatTracker; +import com.duckblade.osrs.sailing.features.util.SailingUtil; +import com.duckblade.osrs.sailing.module.PluginLifecycleComponent; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.RequiredArgsConstructor; +import net.runelite.api.Client; +import net.runelite.api.events.GameTick; +import net.runelite.api.gameval.VarbitID; +import net.runelite.client.Notifier; +import net.runelite.client.eventbus.Subscribe; + +@Singleton +@RequiredArgsConstructor(onConstructor_ = @Inject) +public class LowHPNotification implements PluginLifecycleComponent +{ + private final SailingConfig config; + private final Client client; + private final BoatTracker boatTracker; + private final Notifier notifier; + + private boolean hasNotified = false; + + @Override + public boolean isEnabled(SailingConfig config) + { + return config.notifyLowBoatHP().isEnabled(); + } + + @Override + public void shutDown() + { + hasNotified = false; + } + + @Subscribe + public void onGameTick(GameTick e) + { + if (!SailingUtil.isSailing(client) || boatTracker.getBoat() == null) + { + hasNotified = false; + return; + } + + int currentHP = getBoatHP(); + + if (currentHP < 0) + { + hasNotified = false; + return; + } + + int threshold = config.lowBoatHPThreshold(); + + if (currentHP < threshold) + { + if (!hasNotified) + { + notifier.notify(config.notifyLowBoatHP(), "Your boat's hitpoints are low!"); + hasNotified = true; + } + } + else + { + hasNotified = false; + } + } + + private int getBoatHP() + { + int hp = client.getVarbitValue(VarbitID.SAILING_SIDEPANEL_BOAT_HP); + if (hp >= 0) + { + return hp; + } + + return -1; + } +} diff --git a/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java b/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java index 7ee332e8..c0f3e4f2 100644 --- a/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java +++ b/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java @@ -36,6 +36,7 @@ import com.duckblade.osrs.sailing.features.oceanencounters.MysteriousGlow; import com.duckblade.osrs.sailing.features.oceanencounters.OceanMan; import com.duckblade.osrs.sailing.features.salvaging.SalvagingHighlight; +import com.duckblade.osrs.sailing.features.shipcombat.LowHPNotification; import com.duckblade.osrs.sailing.features.util.BoatTracker; import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; @@ -95,7 +96,8 @@ Set lifecycleComponents( SeaChartPanelOverlay seaChartPanelOverlay, SeaChartTaskIndex seaChartTaskIndex, SpeedBoostInfoBox speedBoostInfoBox, - WeatherTaskTracker weatherTaskTracker + WeatherTaskTracker weatherTaskTracker, + LowHPNotification lowHPNotification ) { var builder = ImmutableSet.builder() @@ -133,7 +135,8 @@ Set lifecycleComponents( .add(seaChartPanelOverlay) .add(seaChartTaskIndex) .add(speedBoostInfoBox) - .add(weatherTaskTracker); + .add(weatherTaskTracker) + .add(lowHPNotification); // features still in development if (developerMode) From dcaa86ab24fc2ddf68b51315f7ee85a608c70025 Mon Sep 17 00:00:00 2001 From: Robbe <64053563+Robbejj@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:42:34 +0200 Subject: [PATCH 2/4] Fix formatting for LowHPNotification --- .../java/com/duckblade/osrs/sailing/module/SailingModule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java b/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java index 1df2bc58..7956d7ce 100644 --- a/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java +++ b/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java @@ -105,7 +105,7 @@ Set lifecycleComponents( NavigationOverlay navigationOverlay, TrueTileIndicator trueTileIndicator, WeatherTaskTracker weatherTaskTracker, - LowHPNotification lowHPNotification + LowHPNotification lowHPNotification ) { var builder = ImmutableSet.builder() @@ -148,7 +148,7 @@ Set lifecycleComponents( .add(speedBoostInfoBox) .add(trueTileIndicator) .add(weatherTaskTracker) - .add(lowHPNotification); + .add(lowHPNotification); // features still in development if (developerMode) From 1ba786645956de1feaafa6c546a903af4fb4c08f Mon Sep 17 00:00:00 2001 From: Rhea Date: Mon, 15 Dec 2025 23:34:07 -0500 Subject: [PATCH 3/4] mvoe to SECTION_NAVIGATION, skip boat tracker check --- .../duckblade/osrs/sailing/SailingConfig.java | 57 ++++++++----------- .../shipcombat/LowHPNotification.java | 18 +++--- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java b/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java index cc6ede05..25968c9f 100644 --- a/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java +++ b/src/main/java/com/duckblade/osrs/sailing/SailingConfig.java @@ -104,14 +104,6 @@ public interface SailingConfig extends Config closedByDefault = true ) String SECTION_SILLY = "silly"; - - @ConfigSection( - name = "Ship Combat", - description = "Settings for ship combat and health monitoring.", - position = 1200, - closedByDefault = true - ) - String SECTION_SHIP_COMBAT = "shipCombat"; @ConfigItem( keyName = "highlightRapids", @@ -277,6 +269,31 @@ default boolean navigationOverlaySpeed() return true; } + @ConfigItem( + keyName = "lowBoatHPNotify", + name = "Notify on Low Boat HP", + description = "Notify when your boat's hitpoints drop below the threshold.", + section = SECTION_NAVIGATION, + position = 13 + ) + default Notification lowBoatHPNotification() + { + return Notification.OFF; + } + + @ConfigItem( + keyName = "lowBoatHPThreshold", + name = "Low HP Threshold", + description = "The hitpoint threshold at which to notify you.", + section = SECTION_NAVIGATION, + position = 14 + ) + @Range(min = 1) + default int lowBoatHPThreshold() + { + return 50; + } + @ConfigItem( keyName = "highlightTrimmableSails", name = "Highlight Trimmable Sails", @@ -957,28 +974,4 @@ default int reverseBeepVolume() { return 25; } - - @ConfigItem( - keyName = "notifyLowBoatHP", - name = "Notify on Low Boat HP", - description = "Notify when your boat's hitpoints drop below the threshold.", - section = SECTION_SHIP_COMBAT, - position = 1 - ) - default Notification notifyLowBoatHP() - { - return Notification.OFF; - } - - @ConfigItem( - keyName = "lowBoatHPThreshold", - name = "Low HP Threshold", - description = "The hitpoint threshold at which to notify you. Notification will trigger when boat HP drops below this value.", - section = SECTION_SHIP_COMBAT, - position = 2 - ) - default int lowBoatHPThreshold() - { - return 50; - } } diff --git a/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java b/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java index da288f30..923e9b8e 100644 --- a/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java +++ b/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java @@ -1,7 +1,6 @@ package com.duckblade.osrs.sailing.features.shipcombat; import com.duckblade.osrs.sailing.SailingConfig; -import com.duckblade.osrs.sailing.features.util.BoatTracker; import com.duckblade.osrs.sailing.features.util.SailingUtil; import com.duckblade.osrs.sailing.module.PluginLifecycleComponent; import javax.inject.Inject; @@ -11,23 +10,28 @@ import net.runelite.api.events.GameTick; import net.runelite.api.gameval.VarbitID; import net.runelite.client.Notifier; +import net.runelite.client.config.Notification; import net.runelite.client.eventbus.Subscribe; @Singleton @RequiredArgsConstructor(onConstructor_ = @Inject) public class LowHPNotification implements PluginLifecycleComponent { - private final SailingConfig config; + private final Client client; - private final BoatTracker boatTracker; private final Notifier notifier; + private Notification notification; + private int threshold; + private boolean hasNotified = false; @Override public boolean isEnabled(SailingConfig config) { - return config.notifyLowBoatHP().isEnabled(); + notification = config.lowBoatHPNotification(); + threshold = config.lowBoatHPThreshold(); + return notification.isEnabled(); } @Override @@ -39,7 +43,7 @@ public void shutDown() @Subscribe public void onGameTick(GameTick e) { - if (!SailingUtil.isSailing(client) || boatTracker.getBoat() == null) + if (!SailingUtil.isSailing(client)) { hasNotified = false; return; @@ -53,13 +57,11 @@ public void onGameTick(GameTick e) return; } - int threshold = config.lowBoatHPThreshold(); - if (currentHP < threshold) { if (!hasNotified) { - notifier.notify(config.notifyLowBoatHP(), "Your boat's hitpoints are low!"); + notifier.notify(notification, "Your boat's hitpoints are low!"); hasNotified = true; } } From da147d113703e4017a1dbee683278dd86bda7bd7 Mon Sep 17 00:00:00 2001 From: Rhea Date: Mon, 15 Dec 2025 23:36:14 -0500 Subject: [PATCH 4/4] package/module fix --- .../{shipcombat => navigation}/LowHPNotification.java | 2 +- .../duckblade/osrs/sailing/module/SailingModule.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/com/duckblade/osrs/sailing/features/{shipcombat => navigation}/LowHPNotification.java (96%) diff --git a/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java b/src/main/java/com/duckblade/osrs/sailing/features/navigation/LowHPNotification.java similarity index 96% rename from src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java rename to src/main/java/com/duckblade/osrs/sailing/features/navigation/LowHPNotification.java index 923e9b8e..cd421561 100644 --- a/src/main/java/com/duckblade/osrs/sailing/features/shipcombat/LowHPNotification.java +++ b/src/main/java/com/duckblade/osrs/sailing/features/navigation/LowHPNotification.java @@ -1,4 +1,4 @@ -package com.duckblade.osrs.sailing.features.shipcombat; +package com.duckblade.osrs.sailing.features.navigation; import com.duckblade.osrs.sailing.SailingConfig; import com.duckblade.osrs.sailing.features.util.SailingUtil; diff --git a/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java b/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java index 5933782b..76449dd8 100644 --- a/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java +++ b/src/main/java/com/duckblade/osrs/sailing/module/SailingModule.java @@ -28,6 +28,7 @@ import com.duckblade.osrs.sailing.features.mes.HideStopNavigatingDuringTrials; import com.duckblade.osrs.sailing.features.mes.PrioritizeCargoHold; import com.duckblade.osrs.sailing.features.navigation.LightningCloudsOverlay; +import com.duckblade.osrs.sailing.features.navigation.LowHPNotification; import com.duckblade.osrs.sailing.features.navigation.NavigationOverlay; import com.duckblade.osrs.sailing.features.navigation.RapidsOverlay; import com.duckblade.osrs.sailing.features.navigation.TrueTileIndicator; @@ -40,7 +41,6 @@ import com.duckblade.osrs.sailing.features.oceanencounters.OceanMan; import com.duckblade.osrs.sailing.features.reversebeep.ReverseBeep; import com.duckblade.osrs.sailing.features.salvaging.SalvagingHighlight; -import com.duckblade.osrs.sailing.features.shipcombat.LowHPNotification; import com.duckblade.osrs.sailing.features.util.BoatTracker; import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; @@ -88,6 +88,7 @@ Set lifecycleComponents( LightningCloudsOverlay lightningCloudsOverlay, LostCargoHighlighter lostCargoHighlighter, LostShipment lostShipment, + LowHPNotification lowHPNotification, LuffOverlay luffOverlay, CrystalExtractorHighlight crystalExtractorHighlight, MermaidTaskSolver mermaidTaskSolver, @@ -104,8 +105,7 @@ Set lifecycleComponents( SpeedBoostInfoBox speedBoostInfoBox, NavigationOverlay navigationOverlay, TrueTileIndicator trueTileIndicator, - WeatherTaskTracker weatherTaskTracker, - LowHPNotification lowHPNotification + WeatherTaskTracker weatherTaskTracker ) { var builder = ImmutableSet.builder() @@ -132,6 +132,7 @@ Set lifecycleComponents( .add(lightningCloudsOverlay) .add(lostCargoHighlighter) .add(lostShipment) + .add(lowHPNotification) .add(luffOverlay) .add(crystalExtractorHighlight) .add(mermaidTaskSolver) @@ -148,8 +149,7 @@ Set lifecycleComponents( .add(seaChartTaskIndex) .add(speedBoostInfoBox) .add(trueTileIndicator) - .add(weatherTaskTracker) - .add(lowHPNotification); + .add(weatherTaskTracker); // features still in development //noinspection StatementWithEmptyBody