diff --git a/src/main/java/com/duckblade/osrs/sailing/features/facilities/LuffOverlay.java b/src/main/java/com/duckblade/osrs/sailing/features/facilities/LuffOverlay.java index 68246c9..e8bca11 100644 --- a/src/main/java/com/duckblade/osrs/sailing/features/facilities/LuffOverlay.java +++ b/src/main/java/com/duckblade/osrs/sailing/features/facilities/LuffOverlay.java @@ -5,6 +5,7 @@ import com.duckblade.osrs.sailing.features.util.SailingUtil; import com.duckblade.osrs.sailing.model.Boat; import com.duckblade.osrs.sailing.module.PluginLifecycleComponent; +import com.google.common.collect.ImmutableSet; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -14,6 +15,10 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.gameval.SpotanimID; +import net.runelite.api.gameval.VarbitID; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; @@ -26,6 +31,15 @@ public class LuffOverlay extends Overlay implements PluginLifecycleComponent { + private static final int SAIL_VFX_DISTANCE = 512; + + private static final ImmutableSet FULL_WIND_SAIL_VFX_IDS = ImmutableSet.of( + SpotanimID.VFX_WIND_SAIL_RAFT01_FULL01, + SpotanimID.VFX_WIND_SAIL_SMALL01_FULL01, + SpotanimID.VFX_WIND_SAIL_LARGE01_FULL01, + SpotanimID.VFX_WIND_SAIL_3X10_01 + ); + private final Client client; private final SailingConfig config; private final BoatTracker boatTracker; @@ -70,8 +84,7 @@ public Dimension render(Graphics2D g) return null; } - // Core behaviour: only show when the luff action is actually available - if (!sail.isOpShown(0)) + if (!isTrimWindowActive(sail)) { return null; } @@ -93,4 +106,36 @@ else if (mode == SailingConfig.SailHighlightMode.SAIL) return null; } + + private boolean isTrimWindowActive(GameObject sail) + { + if (client.getVarbitValue(VarbitID.SAILING_BOAT_TIME_TRIM_WINDOW) > 0 || + client.getServerVarbitValue(VarbitID.SAILING_BOAT_TIME_TRIM_WINDOW) > 0) + { + return true; + } + + // The Red Reef update appears to leave this varbit unset while showing the trim window via full-wind sail vfx. + return hasFullWindSailVfx(sail); + } + + private boolean hasFullWindSailVfx(GameObject sail) + { + LocalPoint sailLocation = sail.getLocalLocation(); + for (GraphicsObject graphicsObject : sail.getWorldView().getGraphicsObjects()) + { + LocalPoint graphicsLocation = graphicsObject.getLocation(); + if (!FULL_WIND_SAIL_VFX_IDS.contains(graphicsObject.getId()) || + graphicsObject.finished() || + graphicsLocation == null || + sailLocation.distanceTo(graphicsLocation) > SAIL_VFX_DISTANCE) + { + continue; + } + + return true; + } + + return false; + } }