timers plugin: add support for ring of endurance to stam timer
This commit is contained in:
@@ -40,7 +40,7 @@ import static net.runelite.client.util.RSTimeUnit.GAME_TICKS;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
enum GameTimer
|
||||
{
|
||||
STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", 2, ChronoUnit.MINUTES, true),
|
||||
STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", true),
|
||||
ANTIFIRE(ItemID.ANTIFIRE_POTION4, GameTimerImageType.ITEM, "Antifire", 6, ChronoUnit.MINUTES),
|
||||
EXANTIFIRE(ItemID.EXTENDED_ANTIFIRE4, GameTimerImageType.ITEM, "Extended antifire", 12, ChronoUnit.MINUTES),
|
||||
OVERLOAD(ItemID.OVERLOAD_4, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true),
|
||||
@@ -78,8 +78,8 @@ enum GameTimer
|
||||
DIVINE_MAGIC(ItemID.DIVINE_MAGIC_POTION4, GameTimerImageType.ITEM, "Divine Magic", 5, ChronoUnit.MINUTES),
|
||||
DIVINE_BASTION(ItemID.DIVINE_BASTION_POTION4, GameTimerImageType.ITEM, "Divine Bastion", 5, ChronoUnit.MINUTES),
|
||||
DIVINE_BATTLEMAGE(ItemID.DIVINE_BATTLEMAGE_POTION4, GameTimerImageType.ITEM, "Divine Battlemage", 5, ChronoUnit.MINUTES),
|
||||
ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Antipoison"),
|
||||
ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom");
|
||||
ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Antipoison", false),
|
||||
ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom", false);
|
||||
|
||||
@Nullable
|
||||
private final Duration duration;
|
||||
@@ -110,12 +110,12 @@ enum GameTimer
|
||||
this(imageId, idType, description, null, time, unit, false);
|
||||
}
|
||||
|
||||
GameTimer(int imageId, GameTimerImageType idType, String description)
|
||||
GameTimer(int imageId, GameTimerImageType idType, String description, boolean removedOnDeath)
|
||||
{
|
||||
this.duration = null;
|
||||
this.graphicId = null;
|
||||
this.description = description;
|
||||
this.removedOnDeath = false;
|
||||
this.removedOnDeath = removedOnDeath;
|
||||
this.imageId = imageId;
|
||||
this.imageType = idType;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.timers;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
@@ -107,6 +108,7 @@ public class TimersPlugin extends Plugin
|
||||
private static final String SUPER_ANTIFIRE_EXPIRED_MESSAGE = "<col=7f007f>Your super antifire potion has expired.</col>";
|
||||
private static final String KILLED_TELEBLOCK_OPPONENT_TEXT = "Your Tele Block has been removed because you killed ";
|
||||
private static final String PRAYER_ENHANCE_EXPIRED = "<col=ff0000>Your prayer enhance effect has worn off.</col>";
|
||||
private static final String ENDURANCE_EFFECT_MESSAGE = "Your Ring of endurance doubles the duration of your stamina potion's effect.";
|
||||
|
||||
private static final Pattern DEADMAN_HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+)\\. It will expire in 1 minute, 15 seconds\\.</col>");
|
||||
private static final Pattern FULL_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+)\\. It will expire in 5 minutes\\.</col>");
|
||||
@@ -118,6 +120,9 @@ public class TimersPlugin extends Plugin
|
||||
private TimerTimer freezeTimer;
|
||||
private int freezeTime = -1; // time frozen, in game ticks
|
||||
|
||||
private TimerTimer staminaTimer;
|
||||
private boolean wasWearingEndurance;
|
||||
|
||||
private int lastRaidVarb;
|
||||
private int lastWildernessVarb;
|
||||
private int lastVengCooldownVarb;
|
||||
@@ -163,6 +168,7 @@ public class TimersPlugin extends Plugin
|
||||
widgetHiddenChangedOnPvpWorld = false;
|
||||
lastPoisonVarp = 0;
|
||||
nextPoisonTick = 0;
|
||||
staminaTimer = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -379,7 +385,7 @@ public class TimersPlugin extends Plugin
|
||||
|| event.getId() == ItemID.EGNIOL_POTION_4))
|
||||
{
|
||||
// Needs menu option hook because mixes use a common drink message, distinct from their standard potion messages
|
||||
createGameTimer(STAMINA);
|
||||
createStaminaTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -438,14 +444,20 @@ public class TimersPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.showStamina() && (event.getMessage().equals(STAMINA_DRINK_MESSAGE) || event.getMessage().equals(STAMINA_SHARED_DRINK_MESSAGE)))
|
||||
if (event.getMessage().equals(ENDURANCE_EFFECT_MESSAGE))
|
||||
{
|
||||
createGameTimer(STAMINA);
|
||||
wasWearingEndurance = true;
|
||||
}
|
||||
|
||||
if (config.showStamina() && (event.getMessage().equals(STAMINA_EXPIRED_MESSAGE) || event.getMessage().equals(GAUNTLET_ENTER_MESSAGE)))
|
||||
if (config.showStamina() && (event.getMessage().equals(STAMINA_DRINK_MESSAGE) || event.getMessage().equals(STAMINA_SHARED_DRINK_MESSAGE)))
|
||||
{
|
||||
createStaminaTimer();
|
||||
}
|
||||
|
||||
if (event.getMessage().equals(STAMINA_EXPIRED_MESSAGE) || event.getMessage().equals(GAUNTLET_ENTER_MESSAGE))
|
||||
{
|
||||
removeGameTimer(STAMINA);
|
||||
staminaTimer = null;
|
||||
}
|
||||
|
||||
if (config.showAntiFire() && event.getMessage().equals(ANTIFIRE_DRINK_MESSAGE))
|
||||
@@ -797,34 +809,50 @@ public class TimersPlugin extends Plugin
|
||||
}
|
||||
|
||||
/**
|
||||
* remove SOTD timer when weapon is changed
|
||||
*
|
||||
* @param itemContainerChanged
|
||||
* Remove SOTD timer and update stamina timer when equipment is changed.
|
||||
*/
|
||||
@Subscribe
|
||||
public void onItemContainerChanged(ItemContainerChanged itemContainerChanged)
|
||||
{
|
||||
ItemContainer container = itemContainerChanged.getItemContainer();
|
||||
if (container == client.getItemContainer(InventoryID.EQUIPMENT))
|
||||
if (itemContainerChanged.getContainerId() != InventoryID.EQUIPMENT.getId())
|
||||
{
|
||||
Item weapon = container.getItem(EquipmentInventorySlot.WEAPON.getSlotIdx());
|
||||
return;
|
||||
}
|
||||
|
||||
if (weapon == null)
|
||||
{
|
||||
removeGameTimer(STAFF_OF_THE_DEAD);
|
||||
return;
|
||||
}
|
||||
ItemContainer container = itemContainerChanged.getItemContainer();
|
||||
|
||||
switch (weapon.getId())
|
||||
Item weapon = container.getItem(EquipmentInventorySlot.WEAPON.getSlotIdx());
|
||||
if (weapon == null ||
|
||||
(weapon.getId() != ItemID.STAFF_OF_THE_DEAD &&
|
||||
weapon.getId() != ItemID.TOXIC_STAFF_OF_THE_DEAD &&
|
||||
weapon.getId() != ItemID.STAFF_OF_LIGHT &&
|
||||
weapon.getId() != ItemID.TOXIC_STAFF_UNCHARGED))
|
||||
{
|
||||
// remove sotd timer if the staff has been unwielded
|
||||
removeGameTimer(STAFF_OF_THE_DEAD);
|
||||
}
|
||||
|
||||
if (wasWearingEndurance)
|
||||
{
|
||||
Item ring = container.getItem(EquipmentInventorySlot.RING.getSlotIdx());
|
||||
|
||||
// when using the last ring charge the ring changes to the uncharged version, ignore that and don't
|
||||
// halve the timer
|
||||
if (ring == null || (ring.getId() != ItemID.RING_OF_ENDURANCE && ring.getId() != ItemID.RING_OF_ENDURANCE_UNCHARGED_24844))
|
||||
{
|
||||
case ItemID.STAFF_OF_THE_DEAD:
|
||||
case ItemID.TOXIC_STAFF_OF_THE_DEAD:
|
||||
case ItemID.STAFF_OF_LIGHT:
|
||||
case ItemID.TOXIC_STAFF_UNCHARGED:
|
||||
// don't reset timer if still wielding staff
|
||||
return;
|
||||
default:
|
||||
removeGameTimer(STAFF_OF_THE_DEAD);
|
||||
wasWearingEndurance = false;
|
||||
if (staminaTimer != null)
|
||||
{
|
||||
// Remaining duration gets divided by 2
|
||||
Duration remainingDuration = Duration.between(Instant.now(), staminaTimer.getEndTime()).dividedBy(2);
|
||||
// This relies on the chat message to be removed, which could be after the timer has been culled;
|
||||
// so check there is still remaining time
|
||||
if (!remainingDuration.isNegative() && !remainingDuration.isZero())
|
||||
{
|
||||
log.debug("Halving stamina timer");
|
||||
staminaTimer.setDuration(remainingDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -856,6 +884,12 @@ public class TimersPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void createStaminaTimer()
|
||||
{
|
||||
Duration duration = Duration.ofMinutes(wasWearingEndurance ? 4 : 2);
|
||||
staminaTimer = createGameTimer(STAMINA, duration);
|
||||
}
|
||||
|
||||
private TimerTimer createGameTimer(final GameTimer timer)
|
||||
{
|
||||
if (timer.getDuration() == null)
|
||||
|
||||
@@ -39,8 +39,8 @@ import net.runelite.client.plugins.Plugin;
|
||||
public class Timer extends InfoBox
|
||||
{
|
||||
private final Instant startTime;
|
||||
private final Instant endTime;
|
||||
private final Duration duration;
|
||||
private Instant endTime;
|
||||
private Duration duration;
|
||||
|
||||
public Timer(long period, ChronoUnit unit, BufferedImage image, Plugin plugin)
|
||||
{
|
||||
@@ -94,4 +94,9 @@ public class Timer extends InfoBox
|
||||
return timeLeft.isZero() || timeLeft.isNegative();
|
||||
}
|
||||
|
||||
public void setDuration(Duration duration)
|
||||
{
|
||||
this.duration = duration;
|
||||
endTime = startTime.plus(duration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,16 +28,21 @@ import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.time.Duration;
|
||||
import java.util.EnumSet;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -45,6 +50,7 @@ import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
@@ -189,4 +195,42 @@ public class TimersPluginTest
|
||||
|
||||
verify(infoBoxManager, atLeastOnce()).removeIf(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStamina()
|
||||
{
|
||||
when(timersConfig.showStamina()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your stamina potion.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.STAMINA, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(2), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEndurance()
|
||||
{
|
||||
when(timersConfig.showStamina()).thenReturn(true);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "Your Ring of endurance doubles the duration of your stamina potion's effect.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your stamina potion.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.STAMINA, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(4), infoBox.getDuration());
|
||||
|
||||
// unwield ring
|
||||
timersPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), mock(ItemContainer.class)));
|
||||
// some time has elapsed in the test; this should be just under 2 mins
|
||||
int mins = (int) infoBox.getDuration().toMinutes();
|
||||
assertTrue(mins == 1 || mins == 2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user