Merge pull request #988 from sdburns1998/idle
Idlenotifier: Animation fallback & inventory idle notifications
This commit is contained in:
@@ -32,10 +32,10 @@ import net.runelite.client.config.ConfigItem;
|
|||||||
public interface IdleNotifierConfig extends Config
|
public interface IdleNotifierConfig extends Config
|
||||||
{
|
{
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "animationidle",
|
keyName = "animationidle",
|
||||||
name = "Idle Animation Notifications",
|
name = "Idle Animation Notifications",
|
||||||
description = "Configures if idle animation notifications are enabled",
|
description = "Configures if idle animation notifications are enabled",
|
||||||
position = 1
|
position = 1
|
||||||
)
|
)
|
||||||
default boolean animationIdle()
|
default boolean animationIdle()
|
||||||
{
|
{
|
||||||
@@ -43,21 +43,32 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "animationidlesound",
|
keyName = "outOfItemsIdle",
|
||||||
name = "Idle Animation Sound",
|
name = "Out of Items Idle Notifications",
|
||||||
description = "Plays a custom sound accompanying Idle Animation notifications",
|
position = 2,
|
||||||
position = 2
|
description = "Configures if notifications for running out of items for another action are enabled."
|
||||||
)
|
)
|
||||||
default boolean animationIdleSound()
|
default boolean outOfItemsIdle()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "animationidlesound",
|
||||||
|
name = "Idle Animation Sound",
|
||||||
|
description = "Plays a custom sound accompanying Idle Animation notifications",
|
||||||
|
position = 3
|
||||||
|
)
|
||||||
|
default boolean animationIdleSound()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "interactionidle",
|
keyName = "interactionidle",
|
||||||
name = "Idle Interaction Notifications",
|
name = "Idle Interaction Notifications",
|
||||||
description = "Configures if idle interaction notifications are enabled e.g. combat, fishing",
|
description = "Configures if idle interaction notifications are enabled e.g. combat, fishing",
|
||||||
position = 3
|
position = 4
|
||||||
)
|
)
|
||||||
default boolean interactionIdle()
|
default boolean interactionIdle()
|
||||||
{
|
{
|
||||||
@@ -65,21 +76,21 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "interactionidlesound",
|
keyName = "interactionidlesound",
|
||||||
name = "Idle Interaction Sound",
|
name = "Idle Interaction Sound",
|
||||||
description = "Plays a custom sound accompanying Idle Interaction notifications",
|
description = "Plays a custom sound accompanying Idle Interaction notifications",
|
||||||
position = 4
|
position = 5
|
||||||
)
|
)
|
||||||
default boolean interactionIdleSound()
|
default boolean interactionIdleSound()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "logoutidle",
|
keyName = "logoutidle",
|
||||||
name = "Idle Logout Notifications",
|
name = "Idle Logout Notifications",
|
||||||
description = "Configures if the idle logout notifications are enabled",
|
description = "Configures if the idle logout notifications are enabled",
|
||||||
position = 5
|
position = 6
|
||||||
)
|
)
|
||||||
default boolean logoutIdle()
|
default boolean logoutIdle()
|
||||||
{
|
{
|
||||||
@@ -87,21 +98,21 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "outofcombatsound",
|
keyName = "outofcombatsound",
|
||||||
name = "Out of Combat Sound",
|
name = "Out of Combat Sound",
|
||||||
description = "Plays a custom sound whenever you leave combat",
|
description = "Plays a custom sound whenever you leave combat",
|
||||||
position = 6
|
position = 7
|
||||||
)
|
)
|
||||||
default boolean outOfCombatSound()
|
default boolean outOfCombatSound()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
position = 7,
|
position = 8,
|
||||||
keyName = "skullNotification",
|
keyName = "skullNotification",
|
||||||
name = "Skull Notification",
|
name = "Skull Notification",
|
||||||
description = "Receive a notification when you skull."
|
description = "Receive a notification when you skull."
|
||||||
)
|
)
|
||||||
default boolean showSkullNotification()
|
default boolean showSkullNotification()
|
||||||
{
|
{
|
||||||
@@ -109,10 +120,10 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
position = 8,
|
position = 9,
|
||||||
keyName = "unskullNotification",
|
keyName = "unskullNotification",
|
||||||
name = "Unskull Notification",
|
name = "Unskull Notification",
|
||||||
description = "Receive a notification when you unskull."
|
description = "Receive a notification when you unskull."
|
||||||
)
|
)
|
||||||
default boolean showUnskullNotification()
|
default boolean showUnskullNotification()
|
||||||
{
|
{
|
||||||
@@ -120,10 +131,10 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "timeout",
|
keyName = "timeout",
|
||||||
name = "Idle Notification Delay (ms)",
|
name = "Idle Notification Delay (ms)",
|
||||||
description = "The notification delay after the player is idle",
|
description = "The notification delay after the player is idle",
|
||||||
position = 9
|
position = 10
|
||||||
)
|
)
|
||||||
default int getIdleNotificationDelay()
|
default int getIdleNotificationDelay()
|
||||||
{
|
{
|
||||||
@@ -131,10 +142,10 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "hitpoints",
|
keyName = "hitpoints",
|
||||||
name = "Hitpoints Notification Threshold",
|
name = "Hitpoints Notification Threshold",
|
||||||
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
|
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
|
||||||
position = 10
|
position = 11
|
||||||
)
|
)
|
||||||
default int getHitpointsThreshold()
|
default int getHitpointsThreshold()
|
||||||
{
|
{
|
||||||
@@ -142,21 +153,21 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "playHealthSound",
|
keyName = "playHealthSound",
|
||||||
name = "Play sound for Low Health",
|
name = "Play sound for Low Health",
|
||||||
description = "Will play a sound for every Low Health notification sent",
|
description = "Will play a sound for every Low Health notification sent",
|
||||||
position = 12
|
position = 12
|
||||||
)
|
)
|
||||||
default boolean getPlayHealthSound()
|
default boolean getPlayHealthSound()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "prayer",
|
keyName = "prayer",
|
||||||
name = "Prayer Notification Threshold",
|
name = "Prayer Notification Threshold",
|
||||||
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
|
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
|
||||||
position = 12
|
position = 13
|
||||||
)
|
)
|
||||||
default int getPrayerThreshold()
|
default int getPrayerThreshold()
|
||||||
{
|
{
|
||||||
@@ -164,21 +175,21 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "playPrayerSound",
|
keyName = "playPrayerSound",
|
||||||
name = "Play sound for Low Prayer",
|
name = "Play sound for Low Prayer",
|
||||||
description = "Will play a sound for every Low Prayer notification sent",
|
description = "Will play a sound for every Low Prayer notification sent",
|
||||||
position = 13
|
position = 14
|
||||||
)
|
)
|
||||||
default boolean getPlayPrayerSound()
|
default boolean getPlayPrayerSound()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "oxygen",
|
keyName = "oxygen",
|
||||||
name = "Oxygen Notification Threshold",
|
name = "Oxygen Notification Threshold",
|
||||||
position = 14,
|
position = 15,
|
||||||
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
|
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
|
||||||
)
|
)
|
||||||
default int getOxygenThreshold()
|
default int getOxygenThreshold()
|
||||||
{
|
{
|
||||||
@@ -186,10 +197,10 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "spec",
|
keyName = "spec",
|
||||||
name = "Special Attack Energy Notification Threshold",
|
name = "Special Attack Energy Notification Threshold",
|
||||||
position = 15,
|
position = 16,
|
||||||
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
|
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
|
||||||
)
|
)
|
||||||
default int getSpecEnergyThreshold()
|
default int getSpecEnergyThreshold()
|
||||||
{
|
{
|
||||||
@@ -197,34 +208,34 @@ public interface IdleNotifierConfig extends Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "specSound",
|
keyName = "specSound",
|
||||||
name = "Special Attack Energy Sound",
|
name = "Special Attack Energy Sound",
|
||||||
description = "Plays a custom sound accompanying Special Attack energy notifications",
|
description = "Plays a custom sound accompanying Special Attack energy notifications",
|
||||||
position = 16
|
position = 17
|
||||||
)
|
)
|
||||||
default boolean getSpecSound()
|
default boolean getSpecSound()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "overspec",
|
keyName = "overspec",
|
||||||
name = "Over Special Energy Notification",
|
name = "Over Special Energy Notification",
|
||||||
description = "Will repeat notifications for any value over the special energy threshold",
|
description = "Will repeat notifications for any value over the special energy threshold",
|
||||||
position = 17
|
position = 18
|
||||||
)
|
)
|
||||||
default boolean getOverSpecEnergy()
|
default boolean getOverSpecEnergy()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "pkers",
|
keyName = "pkers",
|
||||||
name = "PKer Notifier",
|
name = "PKer Notifier",
|
||||||
position = 18,
|
position = 19,
|
||||||
description = "Notifies if an attackable player based on your level range appears on screen.",
|
description = "Notifies if an attackable player based on your level range appears on screen.",
|
||||||
group = "PvP",
|
group = "PvP",
|
||||||
warning = "This will not notify you if the player is in your cc or is online on your friends list."
|
warning = "This will not notify you if the player is in your cc or is online on your friends list."
|
||||||
)
|
)
|
||||||
default boolean notifyPkers()
|
default boolean notifyPkers()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.google.inject.Provides;
|
|||||||
import java.awt.TrayIcon;
|
import java.awt.TrayIcon;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,6 +45,9 @@ import net.runelite.api.Constants;
|
|||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.GraphicID;
|
import net.runelite.api.GraphicID;
|
||||||
import net.runelite.api.Hitsplat;
|
import net.runelite.api.Hitsplat;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
import net.runelite.api.NPCDefinition;
|
import net.runelite.api.NPCDefinition;
|
||||||
import net.runelite.api.Player;
|
import net.runelite.api.Player;
|
||||||
@@ -58,6 +62,7 @@ import net.runelite.api.events.GameStateChanged;
|
|||||||
import net.runelite.api.events.GameTick;
|
import net.runelite.api.events.GameTick;
|
||||||
import net.runelite.api.events.HitsplatApplied;
|
import net.runelite.api.events.HitsplatApplied;
|
||||||
import net.runelite.api.events.InteractingChanged;
|
import net.runelite.api.events.InteractingChanged;
|
||||||
|
import net.runelite.api.events.ItemContainerChanged;
|
||||||
import net.runelite.api.events.PlayerSpawned;
|
import net.runelite.api.events.PlayerSpawned;
|
||||||
import net.runelite.api.events.SpotAnimationChanged;
|
import net.runelite.api.events.SpotAnimationChanged;
|
||||||
import net.runelite.client.Notifier;
|
import net.runelite.client.Notifier;
|
||||||
@@ -117,7 +122,12 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
private int lastCombatCountdown = 0;
|
private int lastCombatCountdown = 0;
|
||||||
private Instant sixHourWarningTime;
|
private Instant sixHourWarningTime;
|
||||||
private boolean ready;
|
private boolean ready;
|
||||||
|
private Instant lastTimeItemsUsedUp;
|
||||||
|
private List<Integer> itemIdsPrevious = new ArrayList<>();
|
||||||
|
private List<Integer> itemQuantitiesPrevious = new ArrayList<>();
|
||||||
|
private final List<Integer> itemQuantitiesChange = new ArrayList<>();
|
||||||
private boolean lastInteractWasCombat;
|
private boolean lastInteractWasCombat;
|
||||||
|
private boolean interactingNotified;
|
||||||
private SkullIcon lastTickSkull = null;
|
private SkullIcon lastTickSkull = null;
|
||||||
private boolean isFirstTick = true;
|
private boolean isFirstTick = true;
|
||||||
|
|
||||||
@@ -146,6 +156,7 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
private boolean getSpecSound;
|
private boolean getSpecSound;
|
||||||
private boolean getOverSpecEnergy;
|
private boolean getOverSpecEnergy;
|
||||||
private boolean notifyPkers;
|
private boolean notifyPkers;
|
||||||
|
private boolean outOfItemsIdle;
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
IdleNotifierConfig provideConfig(ConfigManager configManager)
|
IdleNotifierConfig provideConfig(ConfigManager configManager)
|
||||||
@@ -222,6 +233,17 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
/* Fishing */
|
/* Fishing */
|
||||||
case FISHING_CRUSHING_INFERNAL_EELS:
|
case FISHING_CRUSHING_INFERNAL_EELS:
|
||||||
case FISHING_CUTTING_SACRED_EELS:
|
case FISHING_CUTTING_SACRED_EELS:
|
||||||
|
case FISHING_BIG_NET:
|
||||||
|
case FISHING_NET:
|
||||||
|
case FISHING_POLE_CAST:
|
||||||
|
case FISHING_CAGE:
|
||||||
|
case FISHING_HARPOON:
|
||||||
|
case FISHING_BARBTAIL_HARPOON:
|
||||||
|
case FISHING_DRAGON_HARPOON:
|
||||||
|
case FISHING_INFERNAL_HARPOON:
|
||||||
|
case FISHING_OILY_ROD:
|
||||||
|
case FISHING_KARAMBWAN:
|
||||||
|
case FISHING_BAREHAND:
|
||||||
/* Mining(Normal) */
|
/* Mining(Normal) */
|
||||||
case MINING_BRONZE_PICKAXE:
|
case MINING_BRONZE_PICKAXE:
|
||||||
case MINING_IRON_PICKAXE:
|
case MINING_IRON_PICKAXE:
|
||||||
@@ -236,7 +258,7 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
case MINING_3A_PICKAXE:
|
case MINING_3A_PICKAXE:
|
||||||
case DENSE_ESSENCE_CHIPPING:
|
case DENSE_ESSENCE_CHIPPING:
|
||||||
case DENSE_ESSENCE_CHISELING:
|
case DENSE_ESSENCE_CHISELING:
|
||||||
/* Herblore */
|
/* Herblore */
|
||||||
case HERBLORE_PESTLE_AND_MORTAR:
|
case HERBLORE_PESTLE_AND_MORTAR:
|
||||||
case HERBLORE_POTIONMAKING:
|
case HERBLORE_POTIONMAKING:
|
||||||
case HERBLORE_MAKE_TAR:
|
case HERBLORE_MAKE_TAR:
|
||||||
@@ -258,13 +280,14 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
case FARMING_HARVEST_FRUIT_TREE:
|
case FARMING_HARVEST_FRUIT_TREE:
|
||||||
case FARMING_HARVEST_FLOWER:
|
case FARMING_HARVEST_FLOWER:
|
||||||
case FARMING_HARVEST_ALLOTMENT:
|
case FARMING_HARVEST_ALLOTMENT:
|
||||||
/* Misc */
|
/* Misc */
|
||||||
case PISCARILIUS_CRANE_REPAIR:
|
case PISCARILIUS_CRANE_REPAIR:
|
||||||
case HOME_MAKE_TABLET:
|
case HOME_MAKE_TABLET:
|
||||||
case SAND_COLLECTION:
|
case SAND_COLLECTION:
|
||||||
resetTimers();
|
resetTimers();
|
||||||
lastAnimation = animation;
|
lastAnimation = animation;
|
||||||
lastAnimating = Instant.now();
|
lastAnimating = Instant.now();
|
||||||
|
interactingNotified = false;
|
||||||
break;
|
break;
|
||||||
case MAGIC_LUNAR_SHARED:
|
case MAGIC_LUNAR_SHARED:
|
||||||
if (graphic == GraphicID.BAKE_PIE)
|
if (graphic == GraphicID.BAKE_PIE)
|
||||||
@@ -272,10 +295,12 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
resetTimers();
|
resetTimers();
|
||||||
lastAnimation = animation;
|
lastAnimation = animation;
|
||||||
lastAnimating = Instant.now();
|
lastAnimating = Instant.now();
|
||||||
|
interactingNotified = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IDLE:
|
case IDLE:
|
||||||
lastAnimating = Instant.now();
|
lastAnimating = Instant.now();
|
||||||
|
interactingNotified = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// On unknown animation simply assume the animation is invalid and dont throw notification
|
// On unknown animation simply assume the animation is invalid and dont throw notification
|
||||||
@@ -299,6 +324,84 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onItemContainerChanged(ItemContainerChanged event)
|
||||||
|
{
|
||||||
|
ItemContainer itemContainer = event.getItemContainer();
|
||||||
|
|
||||||
|
if (itemContainer != client.getItemContainer(InventoryID.INVENTORY) || !config.outOfItemsIdle())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item[] items = itemContainer.getItems();
|
||||||
|
ArrayList<Integer> itemQuantities = new ArrayList<>();
|
||||||
|
ArrayList<Integer> itemIds = new ArrayList<>();
|
||||||
|
|
||||||
|
// Populate list of items in inventory without duplicates
|
||||||
|
for (Item value : items)
|
||||||
|
{
|
||||||
|
int itemId = OutOfItemsMapping.mapFirst(value.getId());
|
||||||
|
if (itemIds.indexOf(itemId) == -1) // -1 if item not yet in list
|
||||||
|
{
|
||||||
|
itemIds.add(itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate quantity of each item in inventory
|
||||||
|
for (int j = 0; j < itemIds.size(); j++)
|
||||||
|
{
|
||||||
|
itemQuantities.add(0);
|
||||||
|
for (Item item : items)
|
||||||
|
{
|
||||||
|
if (itemIds.get(j) == OutOfItemsMapping.mapFirst(item.getId()))
|
||||||
|
{
|
||||||
|
itemQuantities.set(j, itemQuantities.get(j) + item.getQuantity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
itemQuantitiesChange.clear();
|
||||||
|
|
||||||
|
// Calculate the quantity of each item consumed by the last action
|
||||||
|
if (!itemIdsPrevious.isEmpty())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < itemIdsPrevious.size(); i++)
|
||||||
|
{
|
||||||
|
int id = itemIdsPrevious.get(i);
|
||||||
|
int currentIndex = itemIds.indexOf(id);
|
||||||
|
int currentQuantity;
|
||||||
|
if (currentIndex != -1) // -1 if item is no longer in inventory
|
||||||
|
{
|
||||||
|
currentQuantity = itemQuantities.get(currentIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentQuantity = 0;
|
||||||
|
}
|
||||||
|
itemQuantitiesChange.add(currentQuantity - itemQuantitiesPrevious.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemIdsPrevious = itemIds;
|
||||||
|
itemQuantitiesPrevious = itemQuantities;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check we have enough items left for another action.
|
||||||
|
for (int i = 0; i < itemQuantitiesPrevious.size(); i++)
|
||||||
|
{
|
||||||
|
if (-itemQuantitiesChange.get(i) * 2 > itemQuantitiesPrevious.get(i))
|
||||||
|
{
|
||||||
|
lastTimeItemsUsedUp = Instant.now();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemIdsPrevious = itemIds;
|
||||||
|
itemQuantitiesPrevious = itemQuantities;
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onInteractingChanged(InteractingChanged event)
|
public void onInteractingChanged(InteractingChanged event)
|
||||||
{
|
{
|
||||||
@@ -432,6 +535,7 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
|| client.getKeyboardIdleTicks() < 10)
|
|| client.getKeyboardIdleTicks() < 10)
|
||||||
{
|
{
|
||||||
resetTimers();
|
resetTimers();
|
||||||
|
resetOutOfItemsIdleChecks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,14 +549,13 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
notifier.notify("[" + local.getName() + "] is about to log out from being online for 6 hours!");
|
notifier.notify("[" + local.getName() + "] is about to log out from being online for 6 hours!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.animationIdle && checkAnimationIdle(waitDuration, local))
|
if (this.outOfItemsIdle && checkOutOfItemsIdle(waitDuration))
|
||||||
{
|
{
|
||||||
notifier.notify("[" + local.getName() + "] is now idle!");
|
notifier.notify("[" + local.getName() + "] has run out of items!");
|
||||||
if (this.animationIdleSound)
|
// If this triggers, don't also trigger animation idle notification afterwards.
|
||||||
{
|
lastAnimation = IDLE;
|
||||||
soundManager.playSound(Sound.IDLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.interactionIdle && checkInteractionIdle(waitDuration, local))
|
if (this.interactionIdle && checkInteractionIdle(waitDuration, local))
|
||||||
{
|
{
|
||||||
if (lastInteractWasCombat)
|
if (lastInteractWasCombat)
|
||||||
@@ -471,6 +574,16 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
soundManager.playSound(Sound.IDLE);
|
soundManager.playSound(Sound.IDLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
interactingNotified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.animationIdle && checkAnimationIdle(waitDuration, local))
|
||||||
|
{
|
||||||
|
notifier.notify("[" + local.getName() + "] is now idle!");
|
||||||
|
if (this.animationIdleSound)
|
||||||
|
{
|
||||||
|
soundManager.playSound(Sound.IDLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkLowHitpoints())
|
if (checkLowHitpoints())
|
||||||
@@ -689,7 +802,7 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
|
|
||||||
private boolean checkAnimationIdle(Duration waitDuration, Player local)
|
private boolean checkAnimationIdle(Duration waitDuration, Player local)
|
||||||
{
|
{
|
||||||
if (lastAnimation == IDLE)
|
if (lastAnimation == IDLE || interactingNotified)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -713,6 +826,23 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkOutOfItemsIdle(Duration waitDuration)
|
||||||
|
{
|
||||||
|
if (lastTimeItemsUsedUp == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Instant.now().compareTo(lastTimeItemsUsedUp.plus(waitDuration)) >= 0)
|
||||||
|
{
|
||||||
|
resetTimers();
|
||||||
|
resetOutOfItemsIdleChecks();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void resetTimers()
|
private void resetTimers()
|
||||||
{
|
{
|
||||||
final Player local = client.getLocalPlayer();
|
final Player local = client.getLocalPlayer();
|
||||||
@@ -732,6 +862,14 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetOutOfItemsIdleChecks()
|
||||||
|
{
|
||||||
|
lastTimeItemsUsedUp = null;
|
||||||
|
itemQuantitiesChange.clear();
|
||||||
|
itemIdsPrevious.clear();
|
||||||
|
itemQuantitiesPrevious.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private void skullNotifier()
|
private void skullNotifier()
|
||||||
{
|
{
|
||||||
final Player local = client.getLocalPlayer();
|
final Player local = client.getLocalPlayer();
|
||||||
@@ -796,5 +934,6 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
this.getSpecSound = config.getSpecSound();
|
this.getSpecSound = config.getSpecSound();
|
||||||
this.getOverSpecEnergy = config.getOverSpecEnergy();
|
this.getOverSpecEnergy = config.getOverSpecEnergy();
|
||||||
this.notifyPkers = config.notifyPkers();
|
this.notifyPkers = config.notifyPkers();
|
||||||
|
this.outOfItemsIdle = config.outOfItemsIdle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Twiglet1022 <https://github.com/Twiglet1022>
|
||||||
|
* 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.idlenotifier;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import java.util.Collection;
|
||||||
|
import static net.runelite.api.ItemID.*;
|
||||||
|
|
||||||
|
public enum OutOfItemsMapping
|
||||||
|
{
|
||||||
|
AERIAL_FISHING_CUTTING(BLUEGILL, COMMON_TENCH, MOTTLED_EEL, GREATER_SIREN);
|
||||||
|
|
||||||
|
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create();
|
||||||
|
private final int groupedItemKey;
|
||||||
|
private final int[] groupedItemIDs;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for (final OutOfItemsMapping item : values())
|
||||||
|
{
|
||||||
|
for (int itemId : item.groupedItemIDs)
|
||||||
|
{
|
||||||
|
MAPPINGS.put(itemId, item.groupedItemKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutOfItemsMapping(int groupedItemKey, int... groupedItemIDs)
|
||||||
|
{
|
||||||
|
this.groupedItemKey = groupedItemKey;
|
||||||
|
this.groupedItemIDs = groupedItemIDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some actions consume multiple different items. To properly handle these
|
||||||
|
* cases for the out of items notification the different items must be
|
||||||
|
* recognised as belonging to a single group.
|
||||||
|
*
|
||||||
|
* Map an item that is part of a group of items that are consumed by a single
|
||||||
|
* action to the first item in that group.
|
||||||
|
*/
|
||||||
|
public static int mapFirst(int itemId)
|
||||||
|
{
|
||||||
|
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
||||||
|
|
||||||
|
if (mapping == null || mapping.isEmpty())
|
||||||
|
{
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapping.iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user