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.util.Arrays;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.List;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
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.HotColdClue;
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.NpcClueScroll;
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 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 MAP_ARROW;
public static final BufferedImage EMOTE_IMAGE;
@@ -144,10 +140,9 @@ public class ClueScrollPlugin extends Plugin
@Inject
private WorldMapPointManager worldMapPointManager;
private ClueScrollWorldMapPoint worldMapPoint;
private Integer clueItemId;
private boolean clueItemChanged = false;
private boolean worldMapPointsSet = false;
static
{
@@ -173,15 +168,10 @@ public class ClueScrollPlugin extends Plugin
return configManager.getConfig(ClueScrollConfig.class);
}
@Override
protected void startUp() throws Exception
{
}
@Override
protected void shutDown() throws Exception
{
clearMapPoint();
resetClue();
}
@Override
@@ -198,46 +188,9 @@ public class ClueScrollPlugin extends Plugin
return;
}
if (clue instanceof HotColdClue && event.getMessage().startsWith("The device is"))
if (clue instanceof LocationsClueScroll)
{
HotColdClue hotColdClue = (HotColdClue) clue;
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, "");
}
}
((LocationsClueScroll)clue).update(event.getMessage(), this);
}
if (!event.getMessage().equals("The strange device cools as you find your treasure.")
@@ -305,6 +258,12 @@ public class ClueScrollPlugin extends Plugin
objectsToMark = 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
// to allow NPCs and objects to override it when needed
if (clue instanceof LocationClueScroll)
@@ -316,7 +275,7 @@ public class ClueScrollPlugin extends Plugin
client.setHintArrow(location);
}
setMapPoint(location);
addMapPoints(location);
}
if (clue instanceof NpcClueScroll)
@@ -336,7 +295,7 @@ public class ClueScrollPlugin extends Plugin
client.setHintArrow(npcsToMark[0]);
}
setMapPoint(npcsToMark[0].getWorldLocation());
addMapPoints(npcsToMark[0].getWorldLocation());
}
}
}
@@ -429,15 +388,15 @@ public class ClueScrollPlugin extends Plugin
clueItemId = null;
}
if (clue instanceof HotColdClue)
if (clue instanceof LocationsClueScroll)
{
((HotColdClue) clue).resetHotCold();
((LocationsClueScroll) clue).reset();
}
clueItemChanged = false;
clue = null;
clearMapPoint();
worldMapPointManager.removeIf(point -> point instanceof ClueScrollWorldMapPoint);
worldMapPointsSet = false;
if (config.displayHintArrows())
{
@@ -593,22 +552,18 @@ public class ClueScrollPlugin extends Plugin
return new WorldPoint(x2, y2, 0);
}
private void setMapPoint(WorldPoint point)
private void addMapPoints(WorldPoint... points)
{
if (worldMapPoint == null)
if (worldMapPointsSet)
{
worldMapPoint = new ClueScrollWorldMapPoint();
worldMapPointManager.add(worldMapPoint);
return;
}
worldMapPoint.setWorldPoint(point);
}
private void clearMapPoint()
{
if (worldMapPoint != null)
worldMapPointsSet = true;
for (final WorldPoint point : points)
{
worldMapPointManager.remove(worldMapPoint);
worldMapPoint = null;
worldMapPointManager.add(new ClueScrollWorldMapPoint(point));
}
}
}

View File

@@ -27,44 +27,46 @@ package net.runelite.client.plugins.cluescrolls;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import net.runelite.api.Point;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.ui.overlay.worldmap.WorldMapPoint;
class ClueScrollWorldMapPoint extends WorldMapPoint
{
private final BufferedImage worldMapImage;
private final Point imagePoint;
private final BufferedImage edgeSnapImage;
private static final BufferedImage CLUE_SCROLL_WORLD_IMAGE;
private static final Point CLUE_SCROLL_WORLD_IMAGE_POINT;
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.setJumpOnClick(true);
worldMapImage = new BufferedImage(ClueScrollPlugin.MAP_ARROW.getWidth(), ClueScrollPlugin.MAP_ARROW.getHeight(), BufferedImage.TYPE_INT_ARGB);
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;
this.setImage(CLUE_SCROLL_WORLD_IMAGE);
this.setImagePoint(CLUE_SCROLL_WORLD_IMAGE_POINT);
}
@Override
public void onEdgeSnap()
{
this.setImage(edgeSnapImage);
this.setImage(ClueScrollPlugin.CLUE_SCROLL_IMAGE);
this.setImagePoint(null);
}
@Override
public void onEdgeUnsnap()
{
this.setImage(worldMapImage);
this.setImagePoint(imagePoint);
this.setImage(CLUE_SCROLL_WORLD_IMAGE);
this.setImagePoint(CLUE_SCROLL_WORLD_IMAGE_POINT);
}
}

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.client.plugins.cluescrolls.clues;
import com.google.common.collect.Lists;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
@@ -36,6 +37,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.runelite.api.NPC;
@@ -56,8 +59,11 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
@Getter
@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 =
new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.",
"Jorral",
@@ -71,6 +77,22 @@ public class HotColdClue extends ClueScroll implements TextClueScroll, NpcClueSc
private WorldPoint location;
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
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;
@@ -347,15 +412,9 @@ public class HotColdClue extends ClueScroll implements TextClueScroll, NpcClueSc
return (firstDistance < secondDistance);
}
public void markFinalSpot(WorldPoint wp)
private void markFinalSpot(WorldPoint wp)
{
this.location = wp;
resetHotCold();
}
public void resetHotCold()
{
this.lastWorldPoint = null;
digLocations.clear();
reset();
}
}

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

View File

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