Merge pull request #2522 from deathbeam/hot-cold-map

Add support for map for hot/cold clues
This commit is contained in:
Adam
2018-05-11 19:59:26 -04:00
committed by GitHub
6 changed files with 167 additions and 105 deletions

View File

@@ -34,8 +34,7 @@ import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.regex.Matcher; import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.inject.Inject; import javax.inject.Inject;
@@ -78,6 +77,7 @@ import net.runelite.client.plugins.cluescrolls.clues.EmoteClue;
import net.runelite.client.plugins.cluescrolls.clues.FairyRingClue; import net.runelite.client.plugins.cluescrolls.clues.FairyRingClue;
import net.runelite.client.plugins.cluescrolls.clues.HotColdClue; import net.runelite.client.plugins.cluescrolls.clues.HotColdClue;
import net.runelite.client.plugins.cluescrolls.clues.LocationClueScroll; import net.runelite.client.plugins.cluescrolls.clues.LocationClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.LocationsClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.MapClue; import net.runelite.client.plugins.cluescrolls.clues.MapClue;
import net.runelite.client.plugins.cluescrolls.clues.NpcClueScroll; import net.runelite.client.plugins.cluescrolls.clues.NpcClueScroll;
import net.runelite.client.plugins.cluescrolls.clues.ObjectClueScroll; import net.runelite.client.plugins.cluescrolls.clues.ObjectClueScroll;
@@ -95,10 +95,6 @@ public class ClueScrollPlugin extends Plugin
{ {
private static final Duration WAIT_DURATION = Duration.ofMinutes(4); private static final Duration WAIT_DURATION = Duration.ofMinutes(4);
private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)");
private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\.");
private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*");
public static final BufferedImage CLUE_SCROLL_IMAGE; public static final BufferedImage CLUE_SCROLL_IMAGE;
public static final BufferedImage MAP_ARROW; public static final BufferedImage MAP_ARROW;
public static final BufferedImage EMOTE_IMAGE; public static final BufferedImage EMOTE_IMAGE;
@@ -144,10 +140,9 @@ public class ClueScrollPlugin extends Plugin
@Inject @Inject
private WorldMapPointManager worldMapPointManager; private WorldMapPointManager worldMapPointManager;
private ClueScrollWorldMapPoint worldMapPoint;
private Integer clueItemId; private Integer clueItemId;
private boolean clueItemChanged = false; private boolean clueItemChanged = false;
private boolean worldMapPointsSet = false;
static static
{ {
@@ -173,15 +168,10 @@ public class ClueScrollPlugin extends Plugin
return configManager.getConfig(ClueScrollConfig.class); return configManager.getConfig(ClueScrollConfig.class);
} }
@Override
protected void startUp() throws Exception
{
}
@Override @Override
protected void shutDown() throws Exception protected void shutDown() throws Exception
{ {
clearMapPoint(); resetClue();
} }
@Override @Override
@@ -198,46 +188,9 @@ public class ClueScrollPlugin extends Plugin
return; return;
} }
if (clue instanceof HotColdClue && event.getMessage().startsWith("The device is")) if (clue instanceof LocationsClueScroll)
{ {
HotColdClue hotColdClue = (HotColdClue) clue; ((LocationsClueScroll)clue).update(event.getMessage(), this);
String message = event.getMessage();
Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message);
Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message);
Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message);
// the order that these pattern matchers are checked is important
if (m1.find())
{
// final location for hot cold clue has been found
WorldPoint localWorld = client.getLocalPlayer().getWorldLocation();
if (localWorld != null)
{
hotColdClue.markFinalSpot(localWorld);
}
}
else if (m2.find())
{
String temperature = m2.group(1);
String difference = m2.group(2);
WorldPoint localWorld = client.getLocalPlayer().getWorldLocation();
if (localWorld != null)
{
hotColdClue.updatePossibleArea(localWorld, temperature, difference);
}
}
else if (m3.find())
{
String temperature = m3.group(1);
WorldPoint localWorld = client.getLocalPlayer().getWorldLocation();
if (localWorld != null)
{
hotColdClue.updatePossibleArea(localWorld, temperature, "");
}
}
} }
if (!event.getMessage().equals("The strange device cools as you find your treasure.") if (!event.getMessage().equals("The strange device cools as you find your treasure.")
@@ -305,6 +258,12 @@ public class ClueScrollPlugin extends Plugin
objectsToMark = null; objectsToMark = null;
equippedItems = null; equippedItems = null;
if (clue instanceof LocationsClueScroll)
{
final List<WorldPoint> locations = ((LocationsClueScroll) clue).getLocations();
addMapPoints(locations.toArray(new WorldPoint[locations.size()]));
}
// If we have location clue, set world location before all other types of clues // If we have location clue, set world location before all other types of clues
// to allow NPCs and objects to override it when needed // to allow NPCs and objects to override it when needed
if (clue instanceof LocationClueScroll) if (clue instanceof LocationClueScroll)
@@ -316,7 +275,7 @@ public class ClueScrollPlugin extends Plugin
client.setHintArrow(location); client.setHintArrow(location);
} }
setMapPoint(location); addMapPoints(location);
} }
if (clue instanceof NpcClueScroll) if (clue instanceof NpcClueScroll)
@@ -336,7 +295,7 @@ public class ClueScrollPlugin extends Plugin
client.setHintArrow(npcsToMark[0]); client.setHintArrow(npcsToMark[0]);
} }
setMapPoint(npcsToMark[0].getWorldLocation()); addMapPoints(npcsToMark[0].getWorldLocation());
} }
} }
} }
@@ -429,15 +388,15 @@ public class ClueScrollPlugin extends Plugin
clueItemId = null; clueItemId = null;
} }
if (clue instanceof HotColdClue) if (clue instanceof LocationsClueScroll)
{ {
((HotColdClue) clue).resetHotCold(); ((LocationsClueScroll) clue).reset();
} }
clueItemChanged = false; clueItemChanged = false;
clue = null; clue = null;
worldMapPointManager.removeIf(point -> point instanceof ClueScrollWorldMapPoint);
clearMapPoint(); worldMapPointsSet = false;
if (config.displayHintArrows()) if (config.displayHintArrows())
{ {
@@ -593,22 +552,18 @@ public class ClueScrollPlugin extends Plugin
return new WorldPoint(x2, y2, 0); return new WorldPoint(x2, y2, 0);
} }
private void setMapPoint(WorldPoint point) private void addMapPoints(WorldPoint... points)
{ {
if (worldMapPoint == null) if (worldMapPointsSet)
{ {
worldMapPoint = new ClueScrollWorldMapPoint(); return;
worldMapPointManager.add(worldMapPoint);
} }
worldMapPoint.setWorldPoint(point);
}
private void clearMapPoint() worldMapPointsSet = true;
{
if (worldMapPoint != null) for (final WorldPoint point : points)
{ {
worldMapPointManager.remove(worldMapPoint); worldMapPointManager.add(new ClueScrollWorldMapPoint(point));
worldMapPoint = null;
} }
} }
} }

View File

@@ -27,44 +27,46 @@ package net.runelite.client.plugins.cluescrolls;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint;
class ClueScrollWorldMapPoint extends WorldMapPoint class ClueScrollWorldMapPoint extends WorldMapPoint
{ {
private final BufferedImage worldMapImage; private static final BufferedImage CLUE_SCROLL_WORLD_IMAGE;
private final Point imagePoint; private static final Point CLUE_SCROLL_WORLD_IMAGE_POINT;
private final BufferedImage edgeSnapImage;
ClueScrollWorldMapPoint() static
{ {
super(null, null); CLUE_SCROLL_WORLD_IMAGE = new BufferedImage(ClueScrollPlugin.MAP_ARROW.getWidth(), ClueScrollPlugin.MAP_ARROW.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics graphics = CLUE_SCROLL_WORLD_IMAGE.getGraphics();
graphics.drawImage(ClueScrollPlugin.MAP_ARROW, 0, 0, null);
graphics.drawImage(ClueScrollPlugin.CLUE_SCROLL_IMAGE, 0, 2, null);
CLUE_SCROLL_WORLD_IMAGE_POINT = new Point(
CLUE_SCROLL_WORLD_IMAGE.getWidth() / 2,
CLUE_SCROLL_WORLD_IMAGE.getHeight());
}
ClueScrollWorldMapPoint(final WorldPoint worldPoint)
{
super(worldPoint, null);
this.setSnapToEdge(true); this.setSnapToEdge(true);
this.setJumpOnClick(true); this.setJumpOnClick(true);
this.setImage(CLUE_SCROLL_WORLD_IMAGE);
worldMapImage = new BufferedImage(ClueScrollPlugin.MAP_ARROW.getWidth(), ClueScrollPlugin.MAP_ARROW.getHeight(), BufferedImage.TYPE_INT_ARGB); this.setImagePoint(CLUE_SCROLL_WORLD_IMAGE_POINT);
Graphics graphics = worldMapImage.getGraphics();
graphics.drawImage(ClueScrollPlugin.MAP_ARROW, 0, 0, null);
graphics.drawImage(ClueScrollPlugin.CLUE_SCROLL_IMAGE, 0, 2, null);
imagePoint = new Point(worldMapImage.getWidth() / 2, worldMapImage.getHeight());
this.setImage(worldMapImage);
this.setImagePoint(imagePoint);
edgeSnapImage = ClueScrollPlugin.CLUE_SCROLL_IMAGE;
} }
@Override @Override
public void onEdgeSnap() public void onEdgeSnap()
{ {
this.setImage(edgeSnapImage); this.setImage(ClueScrollPlugin.CLUE_SCROLL_IMAGE);
this.setImagePoint(null); this.setImagePoint(null);
} }
@Override @Override
public void onEdgeUnsnap() public void onEdgeUnsnap()
{ {
this.setImage(worldMapImage); this.setImage(CLUE_SCROLL_WORLD_IMAGE);
this.setImagePoint(imagePoint); this.setImagePoint(CLUE_SCROLL_WORLD_IMAGE_POINT);
} }
} }

View File

@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.plugins.cluescrolls.clues; package net.runelite.client.plugins.cluescrolls.clues;
import com.google.common.collect.Lists;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@@ -36,6 +37,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.runelite.api.NPC; import net.runelite.api.NPC;
@@ -56,8 +59,11 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public class HotColdClue extends ClueScroll implements TextClueScroll, NpcClueScroll public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll
{ {
private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)");
private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\.");
private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*");
private static final HotColdClue CLUE = private static final HotColdClue CLUE =
new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.",
"Jorral", "Jorral",
@@ -71,6 +77,22 @@ public class HotColdClue extends ClueScroll implements TextClueScroll, NpcClueSc
private WorldPoint location; private WorldPoint location;
private WorldPoint lastWorldPoint; private WorldPoint lastWorldPoint;
public static HotColdClue forText(String text)
{
if (CLUE.text.equalsIgnoreCase(text))
{
return CLUE;
}
return null;
}
@Override
public List<WorldPoint> getLocations()
{
return Lists.transform(digLocations, HotColdLocation::getWorldPoint);
}
@Override @Override
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
{ {
@@ -225,17 +247,60 @@ public class HotColdClue extends ClueScroll implements TextClueScroll, NpcClueSc
} }
} }
public static HotColdClue forText(String text) @Override
public void update(final String message, final ClueScrollPlugin plugin)
{ {
if (CLUE.text.equalsIgnoreCase(text)) if (!message.startsWith("The device is"))
{ {
return CLUE; return;
} }
return null; Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message);
Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message);
Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message);
// the order that these pattern matchers are checked is important
if (m1.find())
{
// final location for hot cold clue has been found
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
if (localWorld != null)
{
markFinalSpot(localWorld);
}
}
else if (m2.find())
{
String temperature = m2.group(1);
String difference = m2.group(2);
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
if (localWorld != null)
{
updatePossibleArea(localWorld, temperature, difference);
}
}
else if (m3.find())
{
String temperature = m3.group(1);
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
if (localWorld != null)
{
updatePossibleArea(localWorld, temperature, "");
}
}
} }
public void updatePossibleArea(WorldPoint currentWp, String temperature, String difference) @Override
public void reset()
{
this.lastWorldPoint = null;
digLocations.clear();
}
private void updatePossibleArea(WorldPoint currentWp, String temperature, String difference)
{ {
this.location = null; this.location = null;
@@ -347,15 +412,9 @@ public class HotColdClue extends ClueScroll implements TextClueScroll, NpcClueSc
return (firstDistance < secondDistance); return (firstDistance < secondDistance);
} }
public void markFinalSpot(WorldPoint wp) private void markFinalSpot(WorldPoint wp)
{ {
this.location = wp; this.location = wp;
resetHotCold(); reset();
}
public void resetHotCold()
{
this.lastWorldPoint = null;
digLocations.clear();
} }
} }

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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.cluescrolls.clues;
import java.util.List;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
public interface LocationsClueScroll
{
void update(String message, ClueScrollPlugin plugin);
void reset();
List<WorldPoint> getLocations();
}

View File

@@ -56,7 +56,8 @@ public class WorldMapOverlayMouseListener extends MouseListener
@Override @Override
public MouseEvent mousePressed(MouseEvent e) public MouseEvent mousePressed(MouseEvent e)
{ {
List<WorldMapPoint> worldMapPoints = worldMapPointManager.getWorldMapPoints(); final List<WorldMapPoint> worldMapPoints = worldMapPointManager.getWorldMapPoints();
if (SwingUtilities.isLeftMouseButton(e) && !worldMapPoints.isEmpty()) if (SwingUtilities.isLeftMouseButton(e) && !worldMapPoints.isEmpty())
{ {
Point mousePos = clientProvider.get().getMouseCanvasPosition(); Point mousePos = clientProvider.get().getMouseCanvasPosition();
@@ -84,7 +85,8 @@ public class WorldMapOverlayMouseListener extends MouseListener
@Override @Override
public MouseEvent mouseMoved(MouseEvent mouseEvent) public MouseEvent mouseMoved(MouseEvent mouseEvent)
{ {
List<WorldMapPoint> worldMapPoints = worldMapPointManager.getWorldMapPoints(); final List<WorldMapPoint> worldMapPoints = worldMapPointManager.getWorldMapPoints();
if (worldMapPoints.isEmpty()) if (worldMapPoints.isEmpty())
{ {
return mouseEvent; return mouseEvent;

View File

@@ -26,6 +26,7 @@ package net.runelite.client.ui.overlay.worldmap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Predicate;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
@@ -45,4 +46,9 @@ public class WorldMapPointManager
{ {
worldMapPoints.remove(worldMapPoint); worldMapPoints.remove(worldMapPoint);
} }
public void removeIf(Predicate<WorldMapPoint> filter)
{
worldMapPoints.removeIf(filter);
}
} }