grounditems: add numerical despawn timers

This commit is contained in:
Hydrox6
2020-11-03 09:27:36 +00:00
committed by Adam
parent a658d94db0
commit 8868d71c10
3 changed files with 117 additions and 24 deletions

View File

@@ -31,6 +31,7 @@ import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Units; import net.runelite.client.config.Units;
import net.runelite.client.config.ConfigSection; 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.HighlightTier;
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
@@ -375,13 +376,13 @@ public interface GroundItemsConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "groundItemTimers", keyName = "groundItemTimers",
name = "Show despawn timers", name = "Despawn timer",
description = "Shows despawn timers for items you've dropped and received as loot", description = "Shows despawn timers for items you've dropped and received as loot",
position = 28 position = 28
) )
default boolean groundItemTimers() default DespawnTimerMode groundItemTimers()
{ {
return false; return DespawnTimerMode.OFF;
} }
@ConfigItem( @ConfigItem(

View File

@@ -47,6 +47,7 @@ import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import static net.runelite.client.plugins.grounditems.GroundItemsPlugin.MAX_QUANTITY; 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 static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU;
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
@@ -175,7 +176,7 @@ public class GroundItemsOverlay extends Overlay
plugin.setHighlightBoxBounds(null); plugin.setHighlightBoxBounds(null);
final boolean onlyShowLoot = config.onlyShowLoot(); final boolean onlyShowLoot = config.onlyShowLoot();
final boolean groundItemTimers = config.groundItemTimers(); final DespawnTimerMode groundItemTimers = config.groundItemTimers();
final boolean outline = config.textOutline(); final boolean outline = config.textOutline();
for (GroundItem item : groundItemList) for (GroundItem item : groundItemList)
@@ -347,9 +348,38 @@ public class GroundItemsOverlay extends Overlay
drawRectangle(graphics, itemHighlightBox, topItem && mouseInHighlightBox ? Color.GREEN : color, highlighted != null, false); 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); textComponent.setText(itemString);
@@ -362,12 +392,12 @@ public class GroundItemsOverlay extends Overlay
return null; 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 // We can only accurately guess despawn times for our own pvm loot and dropped items
if (groundItem.getLootType() != LootType.PVM && groundItem.getLootType() != LootType.DROPPED) if (groundItem.getLootType() != LootType.PVM && groundItem.getLootType() != LootType.DROPPED)
{ {
return; return null;
} }
// Loot appears to others after 1 minute, and despawns after 2 minutes // 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(); Instant spawnTime = groundItem.getSpawnTime();
if (spawnTime == null) if (spawnTime == null)
{ {
return; return null;
} }
Instant despawnTime; Instant despawnTime;
Instant now = Instant.now(); Instant now = Instant.now();
Color fillColor;
if (client.isInInstancedRegion()) if (client.isInInstancedRegion())
{ {
// Items in the Kraken instance appear to never despawn? // Items in the Kraken instance appear to never despawn?
if (isInKraken()) if (isInKraken())
{ {
return; return null;
} }
else if (isInKBDorNMZ()) else if (isInKBDorNMZ())
{ {
@@ -410,7 +439,7 @@ public class GroundItemsOverlay extends Overlay
// Dropped items in the NMZ instance appear to never despawn? // Dropped items in the NMZ instance appear to never despawn?
if (groundItem.getLootType() == LootType.DROPPED) if (groundItem.getLootType() == LootType.DROPPED)
{ {
return; return null;
} }
else else
{ {
@@ -422,8 +451,6 @@ public class GroundItemsOverlay extends Overlay
{ {
despawnTime = spawnTime.plus(DESPAWN_TIME_INSTANCE); despawnTime = spawnTime.plus(DESPAWN_TIME_INSTANCE);
} }
fillColor = PRIVATE_TIMER_COLOR;
} }
else else
{ {
@@ -435,21 +462,53 @@ public class GroundItemsOverlay extends Overlay
{ {
despawnTime = spawnTime.plus(DESPAWN_TIME_LOOT); 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)) if (now.isBefore(spawnTime) || now.isAfter(despawnTime))
{ {
// that's weird // 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; return;
} }

View File

@@ -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
}