timers plugin: Improve imbued heart detection

As is the case with other graphics-based timers, the imbued heart timer
will not fire if other graphics animations are triggered (such as those
created when fighting the Dagannoth Kings). To add this timer more
reliably, this commit will add the timer when a Magic stat boost occurs
of the appropriate amount after recently clicking on an imbued heart.
Because the magic level boost, combined with an imbued heart click
check, is a reliable way to detect usage of an imbued heart, the
graphics check is removed.
This commit is contained in:
Jordan Atwood
2020-02-02 22:24:21 -08:00
committed by Adam
parent 14f939a3b5
commit c92f835102
4 changed files with 186 additions and 9 deletions

View File

@@ -32,10 +32,15 @@ import java.time.Duration;
import java.time.Instant;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.InventoryID;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
import net.runelite.api.Skill;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.StatChanged;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.ui.overlay.infobox.InfoBox;
@@ -53,9 +58,11 @@ import static org.mockito.ArgumentMatchers.nullable;
import org.mockito.Mock;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
@@ -369,4 +376,125 @@ public class TimersPluginTest
ElapsedTimer timer = (ElapsedTimer) captor.getValue();
assertEquals("00:06", timer.getText());
}
}
@Test
public void testImbuedHeartBoost()
{
when(timersConfig.showImbuedHeart()).thenReturn(true);
when(client.getTickCount()).thenReturn(100);
StatChanged event;
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
for (int level = 1, i = 0; level <= Experience.MAX_REAL_LEVEL; level++, i++)
{
event = new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level));
timersPlugin.onStatChanged(event);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(i + 1)).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.IMBUEDHEART, infoBox.getTimer());
}
}
@Test
public void testImbuedHeartBoostFromDrained()
{
when(timersConfig.showImbuedHeart()).thenReturn(true);
when(client.getTickCount()).thenReturn(100);
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
for (int level = 1, i = 0; level <= Experience.MAX_REAL_LEVEL; level++, i++)
{
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, level - 1));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level) - 1));
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(i + 1)).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.IMBUEDHEART, infoBox.getTimer());
}
}
@Test
public void testImbuedHeartBoostFromPartialBoost()
{
when(timersConfig.showImbuedHeart()).thenReturn(true);
when(client.getTickCount()).thenReturn(100);
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
for (int level = 10, i = 0; level <= Experience.MAX_REAL_LEVEL; level++, i++)
{
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, level + 1));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level)));
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(i + 1)).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.IMBUEDHEART, infoBox.getTimer());
}
}
@Test
public void testNonImbuedHeartBoost()
{
lenient().when(timersConfig.showImbuedHeart()).thenReturn(true);
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 1, 1));
// Simulate stat changes of imbued heart boost amount without having clicked the imbued heart
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 29, 34)); // equal to magic essence
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 39, 43)); // equal to magic potion
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 49, 54)); // equal to spicy stew
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 99, 109));
verifyNoInteractions(infoBoxManager);
}
@Test
public void testMagicLevelDrain()
{
lenient().when(timersConfig.showImbuedHeart()).thenReturn(true);
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 1, 1));
when(client.getTickCount()).thenReturn(100);
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
// Simulate stat changes draining to the imbued heart boost amount
for (int level = 1; level <= Experience.MAX_REAL_LEVEL; level++)
{
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, level));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level) + 1));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level)));
}
verifyNoInteractions(infoBoxManager);
}
private static int heartBoostedLevel(final int level)
{
return level + 1 + (level / 10);
}
}