diff --git a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java index 2ddf7e4198..bbacd1914a 100644 --- a/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java +++ b/runelite-api/src/main/java/net/runelite/api/coords/WorldPoint.java @@ -326,4 +326,36 @@ public class WorldPoint { return ((x >> 6) << 8) | (y >> 6); } + + /** + * Converts the passed region ID and coordinates to a world coordinate + */ + public static WorldPoint fromRegion(int regionId, int regionX, int regionY, int plane) + { + return new WorldPoint( + ((regionId >>> 8) << 6) + regionX, + ((regionId & 0xff) << 6) + regionY, + plane); + } + + /** + * Gets the X-axis coordinate of the region coordinate + */ + public int getRegionX() + { + return getRegionOffset(x); + } + + /** + * Gets the Y-axis coordinate of the region coordinate + */ + public int getRegionY() + { + return getRegionOffset(y); + } + + private static int getRegionOffset(final int position) + { + return position & 0x3f; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/ColorTileMarker.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/ColorTileMarker.java new file mode 100644 index 0000000000..6a6a30a065 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/ColorTileMarker.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.groundmarkers; + +import java.awt.Color; +import lombok.Value; +import net.runelite.api.coords.WorldPoint; + +/** + * Used to denote marked tiles and their colors. + * Note: This is not used for serialization of ground markers; see {@link GroundMarkerPoint} + */ +@Value +class ColorTileMarker +{ + private WorldPoint worldPoint; + private Color color; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java index d77f3ab9f5..ba8cb98e14 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerConfig.java @@ -23,7 +23,6 @@ * (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.groundmarkers; import java.awt.Color; @@ -45,4 +44,14 @@ public interface GroundMarkerConfig extends Config { return Color.YELLOW; } + + @ConfigItem( + keyName = "rememberTileColors", + name = "Remember color per tile", + description = "Color tiles using the color from time of placement" + ) + default boolean rememberTileColors() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java index 3b87dd1802..a097d47d29 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerInputListener.java @@ -64,4 +64,4 @@ public class GroundMarkerInputListener implements KeyListener plugin.setHotKeyPressed(false); } } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java index ccd6fd7483..768d90b51b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerOverlay.java @@ -25,10 +25,11 @@ */ package net.runelite.client.plugins.groundmarkers; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Polygon; -import java.util.List; +import java.util.Collection; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.Perspective; @@ -42,6 +43,8 @@ import net.runelite.client.ui.overlay.OverlayUtil; public class GroundMarkerOverlay extends Overlay { + private static final int MAX_DRAW_DISTANCE = 32; + private final Client client; private final GroundMarkerConfig config; private final GroundMarkerPlugin plugin; @@ -60,25 +63,33 @@ public class GroundMarkerOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - List points = plugin.getPoints(); - for (WorldPoint point : points) + final Collection points = plugin.getPoints(); + for (final ColorTileMarker point : points) { - if (point.getPlane() != client.getPlane()) + WorldPoint worldPoint = point.getWorldPoint(); + if (worldPoint.getPlane() != client.getPlane()) { continue; } - drawTile(graphics, point); + Color tileColor = point.getColor(); + if (tileColor == null || !config.rememberTileColors()) + { + // If this is an old tile which has no color, or rememberTileColors is off, use marker color + tileColor = config.markerColor(); + } + + drawTile(graphics, worldPoint, tileColor); } return null; } - private void drawTile(Graphics2D graphics, WorldPoint point) + private void drawTile(Graphics2D graphics, WorldPoint point, Color color) { WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); - if (point.distanceTo(playerLocation) >= 32) + if (point.distanceTo(playerLocation) >= MAX_DRAW_DISTANCE) { return; } @@ -95,6 +106,6 @@ public class GroundMarkerOverlay extends Overlay return; } - OverlayUtil.renderPolygon(graphics, poly, config.markerColor()); + OverlayUtil.renderPolygon(graphics, poly, color); } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index 2cb7ebf1c2..40e7ff72cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -69,19 +69,23 @@ public class GroundMarkerPlugin extends Plugin private static final String CONFIG_GROUP = "groundMarker"; private static final String MARK = "Mark tile"; private static final String WALK_HERE = "Walk here"; + private static final String REGION_PREFIX = "region_"; - private static final Gson gson = new Gson(); + private static final Gson GSON = new Gson(); @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) private boolean hotKeyPressed; @Getter(AccessLevel.PACKAGE) - private final List points = new ArrayList<>(); + private final List points = new ArrayList<>(); @Inject private Client client; + @Inject + private GroundMarkerConfig config; + @Inject private GroundMarkerInputListener inputListener; @@ -101,24 +105,25 @@ public class GroundMarkerPlugin extends Plugin { if (points == null || points.isEmpty()) { - configManager.unsetConfiguration(CONFIG_GROUP, "region_" + regionId); + configManager.unsetConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId); return; } - String json = gson.toJson(points); - configManager.setConfiguration(CONFIG_GROUP, "region_" + regionId, json); + String json = GSON.toJson(points); + configManager.setConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId, json); } private Collection getPoints(int regionId) { - String json = configManager.getConfiguration(CONFIG_GROUP, "region_" + regionId); + String json = configManager.getConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId); if (Strings.isNullOrEmpty(json)) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } - return gson.fromJson(json, new TypeToken>() - { - }.getType()); + + // CHECKSTYLE:OFF + return GSON.fromJson(json, new TypeToken>(){}.getType()); + // CHECKSTYLE:ON } @Provides @@ -132,45 +137,45 @@ public class GroundMarkerPlugin extends Plugin points.clear(); int[] regions = client.getMapRegions(); + + if (regions == null) + { + return; + } + for (int regionId : regions) { // load points for region log.debug("Loading points for region {}", regionId); Collection regionPoints = getPoints(regionId); - Collection worldPoints = translateToWorld(regionPoints); - points.addAll(worldPoints); + Collection colorTileMarkers = translateToColorTileMarker(regionPoints); + points.addAll(colorTileMarkers); } } /** - * Translate a collection of ground marker points to world points, accounting for instances + * Translate a collection of ground marker points to color tile markers, accounting for instances * - * @param points - * @return + * @param points {@link GroundMarkerPoint}s to be converted to {@link ColorTileMarker}s + * @return A collection of color tile markers, converted from the passed ground marker points, accounting for local + * instance points. See {@link WorldPoint#toLocalInstance(Client, WorldPoint)} */ - private Collection translateToWorld(Collection points) + private Collection translateToColorTileMarker(Collection points) { if (points.isEmpty()) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } return points.stream() - .map(point -> + .map(point -> new ColorTileMarker( + WorldPoint.fromRegion(point.getRegionId(), point.getRegionX(), point.getRegionY(), point.getZ()), + point.getColor())) + .flatMap(colorTile -> { - int regionId = point.getRegionId(); - int regionX = point.getRegionX(); - int regionY = point.getRegionY(); - int z = point.getZ(); - - // world point of the tile marker - return new WorldPoint( - ((regionId >>> 8) << 6) + regionX, - ((regionId & 0xff) << 6) + regionY, - z - ); + final Collection localWorldPoints = WorldPoint.toLocalInstance(client, colorTile.getWorldPoint()); + return localWorldPoints.stream().map(wp -> new ColorTileMarker(wp, colorTile.getColor())); }) - .flatMap(wp -> WorldPoint.toLocalInstance(client, wp).stream()) .collect(Collectors.toList()); } @@ -234,6 +239,7 @@ public class GroundMarkerPlugin extends Plugin { overlayManager.add(overlay); keyManager.registerKeyListener(inputListener); + loadPoints(); } @Override @@ -241,10 +247,10 @@ public class GroundMarkerPlugin extends Plugin { overlayManager.remove(overlay); keyManager.unregisterKeyListener(inputListener); + points.clear(); } - - protected void markTile(LocalPoint localPoint) + private void markTile(LocalPoint localPoint) { if (localPoint == null) { @@ -254,21 +260,21 @@ public class GroundMarkerPlugin extends Plugin WorldPoint worldPoint = WorldPoint.fromLocalInstance(client, localPoint); int regionId = worldPoint.getRegionID(); - GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getX() & 0x3f, worldPoint.getY() & 0x3f, client.getPlane()); + GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getRegionX(), worldPoint.getRegionY(), client.getPlane(), config.markerColor()); log.debug("Updating point: {} - {}", point, worldPoint); - List points = new ArrayList<>(getPoints(regionId)); - if (points.contains(point)) + List groundMarkerPoints = new ArrayList<>(getPoints(regionId)); + if (groundMarkerPoints.contains(point)) { - points.remove(point); + groundMarkerPoints.remove(point); } else { - points.add(point); + groundMarkerPoints.add(point); } - savePoints(regionId, points); + savePoints(regionId, groundMarkerPoints); loadPoints(); } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java index b31db32222..3e10a654c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPoint.java @@ -23,16 +23,22 @@ * (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.groundmarkers; +import java.awt.Color; +import lombok.EqualsAndHashCode; import lombok.Value; +/** + * Used for serialization of ground marker points. + */ @Value -public class GroundMarkerPoint +@EqualsAndHashCode(exclude = { "color" }) +class GroundMarkerPoint { private int regionId; private int regionX; private int regionY; private int z; -} \ No newline at end of file + private Color color; +}