cluescroll plugin: Clear stale location clue hint arrows
Location clue scrolls added a hint arrow when the player was nearby one of the clue's locations. It did not, however clear that arrow if the locations were changed and the previously-set hint arrow location was no longer marked. This commit updates this behavior to clear the active hint arrow each game tick before re-adding any location hint arrows. (and if no NPC hint arrows are set) Fixes runelite/runelite#10370
This commit is contained in:
@@ -396,14 +396,17 @@ public class ClueScrollPlugin extends Plugin
|
|||||||
if (clue instanceof LocationClueScroll)
|
if (clue instanceof LocationClueScroll)
|
||||||
{
|
{
|
||||||
final WorldPoint[] locations = ((LocationClueScroll) clue).getLocations();
|
final WorldPoint[] locations = ((LocationClueScroll) clue).getLocations();
|
||||||
|
final boolean npcHintArrowMarked = client.getHintArrowNpc() != null && npcsToMark.contains(client.getHintArrowNpc());
|
||||||
|
|
||||||
|
if (!npcHintArrowMarked)
|
||||||
|
{
|
||||||
|
client.clearHintArrow();
|
||||||
|
}
|
||||||
|
|
||||||
for (WorldPoint location : locations)
|
for (WorldPoint location : locations)
|
||||||
{
|
{
|
||||||
// Only set the location hint arrow if we do not already have more accurate location
|
// Only set the location hint arrow if we do not already have more accurate location
|
||||||
if (location.isInScene(client)
|
if (location.isInScene(client) && config.displayHintArrows() && !npcHintArrowMarked)
|
||||||
&& config.displayHintArrows()
|
|
||||||
&& (client.getHintArrowNpc() == null
|
|
||||||
|| !npcsToMark.contains(client.getHintArrowNpc())))
|
|
||||||
{
|
{
|
||||||
client.setHintArrow(location);
|
client.setHintArrow(location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,68 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.cluescrolls;
|
package net.runelite.client.plugins.cluescrolls;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
import com.google.inject.testing.fieldbinder.Bind;
|
||||||
|
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||||
|
import net.runelite.api.ChatMessageType;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.Player;
|
||||||
import net.runelite.api.coords.WorldPoint;
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.GameTick;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class ClueScrollPluginTest
|
public class ClueScrollPluginTest
|
||||||
{
|
{
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ClueScrollPlugin plugin;
|
||||||
|
|
||||||
|
@Bind
|
||||||
|
@Named("developerMode")
|
||||||
|
boolean developerMode;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
ClueScrollConfig config;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
ItemManager itemManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before()
|
||||||
|
{
|
||||||
|
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getGetMirrorPoint()
|
public void getGetMirrorPoint()
|
||||||
{
|
{
|
||||||
@@ -61,4 +116,51 @@ public class ClueScrollPluginTest
|
|||||||
converted = ClueScrollPlugin.getMirrorPoint(point, false);
|
converted = ClueScrollPlugin.getMirrorPoint(point, false);
|
||||||
assertEquals(point, converted);
|
assertEquals(point, converted);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
public void testLocationHintArrowCleared()
|
||||||
|
{
|
||||||
|
final Widget clueWidget = mock(Widget.class);
|
||||||
|
when(clueWidget.getText()).thenReturn("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Reldo may have a clue.");
|
||||||
|
final ChatMessage hotColdMessage = new ChatMessage();
|
||||||
|
hotColdMessage.setType(ChatMessageType.GAMEMESSAGE);
|
||||||
|
final Player localPlayer = mock(Player.class);
|
||||||
|
|
||||||
|
when(client.getWidget(WidgetInfo.CLUE_SCROLL_TEXT)).thenReturn(clueWidget);
|
||||||
|
when(client.getLocalPlayer()).thenReturn(localPlayer);
|
||||||
|
when(client.getPlane()).thenReturn(0);
|
||||||
|
when(client.getCachedNPCs()).thenReturn(new NPC[] {});
|
||||||
|
when(config.displayHintArrows()).thenReturn(true);
|
||||||
|
|
||||||
|
// The hint arrow should be reset each game tick from when the clue is read onward
|
||||||
|
// This is to verify the arrow is cleared the correct number of times during the clue updating process.
|
||||||
|
int clueSetupHintArrowClears = 0;
|
||||||
|
|
||||||
|
// Initialize a beginner hot-cold clue (which will have an end point of LUMBRIDGE_COW_FIELD)
|
||||||
|
plugin.onGameTick(new GameTick());
|
||||||
|
verify(client, times(++clueSetupHintArrowClears)).clearHintArrow();
|
||||||
|
|
||||||
|
// Perform the first hot-cold check in Lumbridge near sheep pen (get 2 possible points: LUMBRIDGE_COW_FIELD and DRAYNOR_WHEAT_FIELD)
|
||||||
|
when(localPlayer.getWorldLocation()).thenReturn(new WorldPoint(3208, 3254, 0));
|
||||||
|
hotColdMessage.setMessage("The device is hot.");
|
||||||
|
plugin.onChatMessage(hotColdMessage);
|
||||||
|
|
||||||
|
// Move to SW of DRAYNOR_WHEAT_FIELD (hint arrow should be visible here)
|
||||||
|
when(localPlayer.getWorldLocation()).thenReturn(new WorldPoint(3105, 3265, 0));
|
||||||
|
when(client.getBaseX()).thenReturn(3056);
|
||||||
|
when(client.getBaseY()).thenReturn(3216);
|
||||||
|
plugin.onGameTick(new GameTick());
|
||||||
|
verify(client, times(++clueSetupHintArrowClears)).clearHintArrow();
|
||||||
|
verify(client).setHintArrow(HotColdLocation.DRAYNOR_WHEAT_FIELD.getWorldPoint());
|
||||||
|
|
||||||
|
// Test in that location (get 1 possible location: LUMBRIDGE_COW_FIELD)
|
||||||
|
hotColdMessage.setMessage("The device is hot, and warmer than last time.");
|
||||||
|
plugin.onChatMessage(hotColdMessage);
|
||||||
|
plugin.onGameTick(new GameTick());
|
||||||
|
|
||||||
|
// Hint arrow should be cleared and not re-set now as the only remaining location is outside of the current
|
||||||
|
// scene
|
||||||
|
verify(client, times(++clueSetupHintArrowClears)).clearHintArrow();
|
||||||
|
verify(client, times(1)).setHintArrow(any(WorldPoint.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user