grounditems: add numerical despawn timers
This commit is contained in:
@@ -31,6 +31,7 @@ import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Units;
|
||||
import net.runelite.client.config.ConfigSection;
|
||||
import net.runelite.client.plugins.grounditems.config.DespawnTimerMode;
|
||||
import net.runelite.client.plugins.grounditems.config.HighlightTier;
|
||||
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
|
||||
@@ -375,13 +376,13 @@ public interface GroundItemsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "groundItemTimers",
|
||||
name = "Show despawn timers",
|
||||
name = "Despawn timer",
|
||||
description = "Shows despawn timers for items you've dropped and received as loot",
|
||||
position = 28
|
||||
)
|
||||
default boolean groundItemTimers()
|
||||
default DespawnTimerMode groundItemTimers()
|
||||
{
|
||||
return false;
|
||||
return DespawnTimerMode.OFF;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
|
||||
@@ -47,6 +47,7 @@ import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.client.plugins.grounditems.GroundItemsPlugin.MAX_QUANTITY;
|
||||
import net.runelite.client.plugins.grounditems.config.DespawnTimerMode;
|
||||
import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU;
|
||||
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
@@ -175,7 +176,7 @@ public class GroundItemsOverlay extends Overlay
|
||||
plugin.setHighlightBoxBounds(null);
|
||||
|
||||
final boolean onlyShowLoot = config.onlyShowLoot();
|
||||
final boolean groundItemTimers = config.groundItemTimers();
|
||||
final DespawnTimerMode groundItemTimers = config.groundItemTimers();
|
||||
final boolean outline = config.textOutline();
|
||||
|
||||
for (GroundItem item : groundItemList)
|
||||
@@ -347,9 +348,38 @@ public class GroundItemsOverlay extends Overlay
|
||||
drawRectangle(graphics, itemHighlightBox, topItem && mouseInHighlightBox ? Color.GREEN : color, highlighted != null, false);
|
||||
}
|
||||
|
||||
if (groundItemTimers || plugin.isHotKeyPressed())
|
||||
// When the hotkey is pressed the hidden/highlight boxes are drawn to the right of the text,
|
||||
// so always draw the pie since it is on the left hand side.
|
||||
if (groundItemTimers == DespawnTimerMode.PIE || plugin.isHotKeyPressed())
|
||||
{
|
||||
drawTimerOverlay(graphics, textX, textY, item);
|
||||
drawTimerPieOverlay(graphics, textX, textY, item);
|
||||
}
|
||||
else if (groundItemTimers == DespawnTimerMode.SECONDS || groundItemTimers == DespawnTimerMode.TICKS)
|
||||
{
|
||||
Instant despawnTime = calculateDespawnTime(item);
|
||||
Color timerColor = getItemTimerColor(item);
|
||||
if (despawnTime != null && timerColor != null)
|
||||
{
|
||||
long despawnTimeMillis = despawnTime.toEpochMilli() - Instant.now().toEpochMilli();
|
||||
final String timerText;
|
||||
if (groundItemTimers == DespawnTimerMode.SECONDS)
|
||||
{
|
||||
timerText = String.format(" - %.1f", despawnTimeMillis / 1000f);
|
||||
}
|
||||
else // TICKS
|
||||
{
|
||||
timerText = String.format(" - %d", despawnTimeMillis / 600);
|
||||
}
|
||||
|
||||
// The timer text is drawn separately to have its own color, and is intentionally not included
|
||||
// in the getCanvasTextLocation() call because the timer text can change per frame and we do not
|
||||
// use a monospaced font, which causes the text location on screen to jump around slightly each frame.
|
||||
textComponent.setText(timerText);
|
||||
textComponent.setColor(timerColor);
|
||||
textComponent.setOutline(outline);
|
||||
textComponent.setPosition(new java.awt.Point(textX + fm.stringWidth(itemString), textY));
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
textComponent.setText(itemString);
|
||||
@@ -362,12 +392,12 @@ public class GroundItemsOverlay extends Overlay
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawTimerOverlay(Graphics2D graphics, int textX, int textY, GroundItem groundItem)
|
||||
private Instant calculateDespawnTime(GroundItem groundItem)
|
||||
{
|
||||
// We can only accurately guess despawn times for our own pvm loot and dropped items
|
||||
if (groundItem.getLootType() != LootType.PVM && groundItem.getLootType() != LootType.DROPPED)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Loot appears to others after 1 minute, and despawns after 2 minutes
|
||||
@@ -377,18 +407,17 @@ public class GroundItemsOverlay extends Overlay
|
||||
Instant spawnTime = groundItem.getSpawnTime();
|
||||
if (spawnTime == null)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
Instant despawnTime;
|
||||
Instant now = Instant.now();
|
||||
Color fillColor;
|
||||
if (client.isInInstancedRegion())
|
||||
{
|
||||
// Items in the Kraken instance appear to never despawn?
|
||||
if (isInKraken())
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
else if (isInKBDorNMZ())
|
||||
{
|
||||
@@ -410,7 +439,7 @@ public class GroundItemsOverlay extends Overlay
|
||||
// Dropped items in the NMZ instance appear to never despawn?
|
||||
if (groundItem.getLootType() == LootType.DROPPED)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -422,8 +451,6 @@ public class GroundItemsOverlay extends Overlay
|
||||
{
|
||||
despawnTime = spawnTime.plus(DESPAWN_TIME_INSTANCE);
|
||||
}
|
||||
|
||||
fillColor = PRIVATE_TIMER_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -435,21 +462,53 @@ public class GroundItemsOverlay extends Overlay
|
||||
{
|
||||
despawnTime = spawnTime.plus(DESPAWN_TIME_LOOT);
|
||||
}
|
||||
|
||||
// If it has not yet been a minute, the item is private
|
||||
if (spawnTime.plus(1, ChronoUnit.MINUTES).isAfter(now))
|
||||
{
|
||||
fillColor = PRIVATE_TIMER_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
fillColor = PUBLIC_TIMER_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
if (now.isBefore(spawnTime) || now.isAfter(despawnTime))
|
||||
{
|
||||
// that's weird
|
||||
return null;
|
||||
}
|
||||
|
||||
return despawnTime;
|
||||
}
|
||||
|
||||
private Color getItemTimerColor(GroundItem groundItem)
|
||||
{
|
||||
// We can only accurately guess despawn times for our own pvm loot and dropped items
|
||||
if (groundItem.getLootType() != LootType.PVM && groundItem.getLootType() != LootType.DROPPED)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Instant spawnTime = groundItem.getSpawnTime();
|
||||
if (spawnTime == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Instant now = Instant.now();
|
||||
|
||||
// If it has not yet been a minute, the item is private
|
||||
if (client.isInInstancedRegion() || spawnTime.plus(1, ChronoUnit.MINUTES).isAfter(now))
|
||||
{
|
||||
return PRIVATE_TIMER_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PUBLIC_TIMER_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTimerPieOverlay(Graphics2D graphics, int textX, int textY, GroundItem groundItem)
|
||||
{
|
||||
Instant now = Instant.now();
|
||||
Instant spawnTime = groundItem.getSpawnTime();
|
||||
Instant despawnTime = calculateDespawnTime(groundItem);
|
||||
Color fillColor = getItemTimerColor(groundItem);
|
||||
|
||||
if (spawnTime == null || despawnTime == null || fillColor == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Hydrox6 <ikada@protonmail.ch>
|
||||
* 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.grounditems.config;
|
||||
|
||||
public enum DespawnTimerMode
|
||||
{
|
||||
OFF,
|
||||
PIE,
|
||||
TICKS,
|
||||
SECONDS
|
||||
}
|
||||
Reference in New Issue
Block a user