Merge remote-tracking branch 'runelite/master'
This commit is contained in:
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
object ProjectVersions {
|
object ProjectVersions {
|
||||||
const val launcherVersion = "2.2.0"
|
const val launcherVersion = "2.2.0"
|
||||||
const val rlVersion = "1.7.19"
|
const val rlVersion = "1.7.20-SNAPSHOT"
|
||||||
|
|
||||||
const val openosrsVersion = "4.9.10"
|
const val openosrsVersion = "4.9.10"
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import lombok.Value;
|
|||||||
@Value
|
@Value
|
||||||
public class ItemStats
|
public class ItemStats
|
||||||
{
|
{
|
||||||
private boolean quest;
|
|
||||||
private boolean equipable;
|
private boolean equipable;
|
||||||
private double weight;
|
private double weight;
|
||||||
@SerializedName("ge_limit")
|
@SerializedName("ge_limit")
|
||||||
@@ -79,7 +78,7 @@ public class ItemStats
|
|||||||
newEquipment = equipment;
|
newEquipment = equipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ItemStats(quest, equipable, newWeight, 0, newEquipment);
|
return new ItemStats(equipable, newWeight, 0, newEquipment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -854,6 +854,7 @@ public class WidgetID
|
|||||||
static class Pvp
|
static class Pvp
|
||||||
{
|
{
|
||||||
static final int KILLDEATH_RATIO = 26;
|
static final int KILLDEATH_RATIO = 26;
|
||||||
|
static final int WILDERNESS_SKULL_CONTAINER = 44;
|
||||||
static final int SKULL_CONTAINER = 45;
|
static final int SKULL_CONTAINER = 45;
|
||||||
static final int SAFE_ZONE = 47;
|
static final int SAFE_ZONE = 47;
|
||||||
static final int WILDERNESS_LEVEL = 50; // this can also be the Deadman Mode "Protection" text
|
static final int WILDERNESS_LEVEL = 50; // this can also be the Deadman Mode "Protection" text
|
||||||
|
|||||||
@@ -503,6 +503,7 @@ public enum WidgetInfo
|
|||||||
SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT),
|
SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT),
|
||||||
SPELL_KOUREND_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.KOUREND_HOME_TELEPORT),
|
SPELL_KOUREND_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.KOUREND_HOME_TELEPORT),
|
||||||
|
|
||||||
|
PVP_WILDERNESS_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.WILDERNESS_SKULL_CONTAINER),
|
||||||
PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER),
|
PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER),
|
||||||
PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE),
|
PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE),
|
||||||
|
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ public class RuneLite
|
|||||||
if (!isOutdated)
|
if (!isOutdated)
|
||||||
{
|
{
|
||||||
// Add core overlays
|
// Add core overlays
|
||||||
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
|
WidgetOverlay.createOverlays(overlayManager, client).forEach(overlayManager::add);
|
||||||
overlayManager.add(worldMapOverlay.get());
|
overlayManager.add(worldMapOverlay.get());
|
||||||
eventBus.register(worldMapOverlay.get());
|
eventBus.register(worldMapOverlay.get());
|
||||||
overlayManager.add(tooltipOverlay.get());
|
overlayManager.add(tooltipOverlay.get());
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class InteractHighlightOverlay extends Overlay
|
|||||||
this.modelOutlineRenderer = modelOutlineRenderer;
|
this.modelOutlineRenderer = modelOutlineRenderer;
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
setPriority(OverlayPriority.LOW);
|
setPriority(OverlayPriority.HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class ItemStatOverlay extends Overlay
|
|||||||
{
|
{
|
||||||
// Unarmed attack speed is 4
|
// Unarmed attack speed is 4
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final ItemStats UNARMED = new ItemStats(false, true, 0, 0,
|
static final ItemStats UNARMED = new ItemStats(true, 0, 0,
|
||||||
ItemEquipmentStats.builder()
|
ItemEquipmentStats.builder()
|
||||||
.aspeed(4)
|
.aspeed(4)
|
||||||
.build());
|
.build());
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
|
|
||||||
// Chest loot handling
|
// Chest loot handling
|
||||||
private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!";
|
private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!";
|
||||||
|
private static final Pattern ROGUES_CHEST_PATTERN = Pattern.compile("You find (a|some)([a-z\\s]*) inside.");
|
||||||
private static final Pattern LARRAN_LOOTED_PATTERN = Pattern.compile("You have opened Larran's (big|small) chest .*");
|
private static final Pattern LARRAN_LOOTED_PATTERN = Pattern.compile("You have opened Larran's (big|small) chest .*");
|
||||||
// Used by Stone Chest, Isle of Souls chest, Dark Chest
|
// Used by Stone Chest, Isle of Souls chest, Dark Chest
|
||||||
private static final String OTHER_CHEST_LOOTED_MESSAGE = "You steal some loot from the chest.";
|
private static final String OTHER_CHEST_LOOTED_MESSAGE = "You steal some loot from the chest.";
|
||||||
@@ -167,6 +168,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
put(7323, "Grubby Chest").
|
put(7323, "Grubby Chest").
|
||||||
put(8593, "Isle of Souls Chest").
|
put(8593, "Isle of Souls Chest").
|
||||||
put(7827, "Dark Chest").
|
put(7827, "Dark Chest").
|
||||||
|
put(13117, "Rogues' Chest").
|
||||||
build();
|
build();
|
||||||
|
|
||||||
// Shade chest loot handling
|
// Shade chest loot handling
|
||||||
@@ -646,7 +648,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
|
|
||||||
if (message.equals(CHEST_LOOTED_MESSAGE) || message.equals(OTHER_CHEST_LOOTED_MESSAGE)
|
if (message.equals(CHEST_LOOTED_MESSAGE) || message.equals(OTHER_CHEST_LOOTED_MESSAGE)
|
||||||
|| message.equals(DORGESH_KAAN_CHEST_LOOTED_MESSAGE) || message.startsWith(GRUBBY_CHEST_LOOTED_MESSAGE)
|
|| message.equals(DORGESH_KAAN_CHEST_LOOTED_MESSAGE) || message.startsWith(GRUBBY_CHEST_LOOTED_MESSAGE)
|
||||||
|| LARRAN_LOOTED_PATTERN.matcher(message).matches())
|
|| LARRAN_LOOTED_PATTERN.matcher(message).matches() || ROGUES_CHEST_PATTERN.matcher(message).matches())
|
||||||
{
|
{
|
||||||
final int regionID = client.getLocalPlayer().getWorldLocation().getRegionID();
|
final int regionID = client.getLocalPlayer().getWorldLocation().getRegionID();
|
||||||
if (!CHEST_EVENT_TYPES.containsKey(regionID))
|
if (!CHEST_EVENT_TYPES.containsKey(regionID))
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.npchighlight;
|
|||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Binder;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -38,6 +39,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -77,7 +79,7 @@ import net.runelite.client.util.WildcardMatcher;
|
|||||||
tags = {"highlight", "minimap", "npcs", "overlay", "respawn", "tags"}
|
tags = {"highlight", "minimap", "npcs", "overlay", "respawn", "tags"}
|
||||||
)
|
)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class NpcIndicatorsPlugin extends Plugin
|
public class NpcIndicatorsPlugin extends Plugin implements NpcIndicatorsService
|
||||||
{
|
{
|
||||||
private static final int MAX_ACTOR_VIEW_RANGE = 15;
|
private static final int MAX_ACTOR_VIEW_RANGE = 15;
|
||||||
|
|
||||||
@@ -173,12 +175,20 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
*/
|
*/
|
||||||
private boolean skipNextSpawnCheck = false;
|
private boolean skipNextSpawnCheck = false;
|
||||||
|
|
||||||
|
private final List<Predicate<NPC>> higlightPredicates = new ArrayList<>();
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
NpcIndicatorsConfig provideConfig(ConfigManager configManager)
|
NpcIndicatorsConfig provideConfig(ConfigManager configManager)
|
||||||
{
|
{
|
||||||
return configManager.getConfig(NpcIndicatorsConfig.class);
|
return configManager.getConfig(NpcIndicatorsConfig.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Binder binder)
|
||||||
|
{
|
||||||
|
binder.bind(NpcIndicatorsService.class).toInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
@@ -187,7 +197,7 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
clientThread.invoke(() ->
|
clientThread.invoke(() ->
|
||||||
{
|
{
|
||||||
skipNextSpawnCheck = true;
|
skipNextSpawnCheck = true;
|
||||||
rebuildAllNpcs();
|
rebuild();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +240,7 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clientThread.invoke(this::rebuildAllNpcs);
|
clientThread.invoke(this::rebuild);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -394,7 +404,23 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
memorizeNpc(npc);
|
memorizeNpc(npc);
|
||||||
spawnedNpcsThisTick.add(npc);
|
spawnedNpcsThisTick.add(npc);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Predicate<NPC> predicate : higlightPredicates)
|
||||||
|
{
|
||||||
|
if (predicate.test(npc))
|
||||||
|
{
|
||||||
|
highlightedNpcs.add(npc);
|
||||||
|
if (!client.isInInstancedRegion())
|
||||||
|
{
|
||||||
|
memorizeNpc(npc);
|
||||||
|
spawnedNpcsThisTick.add(npc);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -534,8 +560,8 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
return Text.fromCSV(configNpcs);
|
return Text.fromCSV(configNpcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@Override
|
||||||
void rebuildAllNpcs()
|
public void rebuild()
|
||||||
{
|
{
|
||||||
highlights = getHighlights();
|
highlights = getHighlights();
|
||||||
highlightedNpcs.clear();
|
highlightedNpcs.clear();
|
||||||
@@ -548,6 +574,7 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outer:
|
||||||
for (NPC npc : client.getNpcs())
|
for (NPC npc : client.getNpcs())
|
||||||
{
|
{
|
||||||
final String npcName = npc.getName();
|
final String npcName = npc.getName();
|
||||||
@@ -573,6 +600,19 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Predicate<NPC> predicate : higlightPredicates)
|
||||||
|
{
|
||||||
|
if (predicate.test(npc))
|
||||||
|
{
|
||||||
|
if (!client.isInInstancedRegion())
|
||||||
|
{
|
||||||
|
memorizeNpc(npc);
|
||||||
|
}
|
||||||
|
highlightedNpcs.add(npc);
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NPC is not highlighted
|
// NPC is not highlighted
|
||||||
memorizedNpcs.remove(npc.getIndex());
|
memorizedNpcs.remove(npc.getIndex());
|
||||||
}
|
}
|
||||||
@@ -680,4 +720,16 @@ public class NpcIndicatorsPlugin extends Plugin
|
|||||||
despawnedNpcsThisTick.clear();
|
despawnedNpcsThisTick.clear();
|
||||||
teleportGraphicsObjectSpawnedThisTick.clear();
|
teleportGraphicsObjectSpawnedThisTick.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerHighlighter(Predicate<NPC> p)
|
||||||
|
{
|
||||||
|
higlightPredicates.add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterHighlighter(Predicate<NPC> p)
|
||||||
|
{
|
||||||
|
higlightPredicates.remove(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Adam <Adam@sigterm.info>
|
||||||
|
* 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.npchighlight;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
|
||||||
|
public interface NpcIndicatorsService
|
||||||
|
{
|
||||||
|
void registerHighlighter(Predicate<NPC> p);
|
||||||
|
void unregisterHighlighter(Predicate<NPC> p);
|
||||||
|
void rebuild();
|
||||||
|
}
|
||||||
@@ -25,8 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.slayer;
|
package net.runelite.client.plugins.slayer;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import net.runelite.client.config.Alpha;
|
|
||||||
import net.runelite.client.config.Config;
|
import net.runelite.client.config.Config;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
import net.runelite.client.config.ConfigGroup;
|
||||||
import net.runelite.client.config.ConfigItem;
|
import net.runelite.client.config.ConfigItem;
|
||||||
@@ -101,18 +99,6 @@ public interface SlayerConfig extends Config
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Alpha
|
|
||||||
@ConfigItem(
|
|
||||||
position = 6,
|
|
||||||
keyName = "targetColor",
|
|
||||||
name = "Target Color",
|
|
||||||
description = "Color of the highlighted targets"
|
|
||||||
)
|
|
||||||
default Color getTargetColor()
|
|
||||||
{
|
|
||||||
return Color.RED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
position = 7,
|
position = 7,
|
||||||
keyName = "weaknessPrompt",
|
keyName = "weaknessPrompt",
|
||||||
|
|||||||
@@ -39,9 +39,11 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import joptsimple.internal.Strings;
|
import joptsimple.internal.Strings;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -60,6 +62,7 @@ import static net.runelite.api.Skill.SLAYER;
|
|||||||
import net.runelite.api.coords.WorldPoint;
|
import net.runelite.api.coords.WorldPoint;
|
||||||
import net.runelite.api.events.ActorDeath;
|
import net.runelite.api.events.ActorDeath;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.CommandExecuted;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
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;
|
||||||
@@ -81,18 +84,23 @@ import net.runelite.client.events.ChatInput;
|
|||||||
import net.runelite.client.events.ConfigChanged;
|
import net.runelite.client.events.ConfigChanged;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDependency;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.plugins.npchighlight.NpcIndicatorsPlugin;
|
||||||
|
import net.runelite.client.plugins.npchighlight.NpcIndicatorsService;
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
import net.runelite.client.util.ColorUtil;
|
import net.runelite.client.util.ColorUtil;
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
import net.runelite.http.api.chat.ChatClient;
|
import net.runelite.http.api.chat.ChatClient;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Slayer",
|
name = "Slayer",
|
||||||
description = "Show additional slayer task related information",
|
description = "Show additional slayer task related information",
|
||||||
tags = {"combat", "notifications", "overlay", "tasks"}
|
tags = {"combat", "notifications", "overlay", "tasks"}
|
||||||
)
|
)
|
||||||
|
@PluginDependency(NpcIndicatorsPlugin.class)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SlayerPlugin extends Plugin
|
public class SlayerPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@@ -151,15 +159,9 @@ public class SlayerPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ClientThread clientThread;
|
private ClientThread clientThread;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private TargetClickboxOverlay targetClickboxOverlay;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TargetWeaknessOverlay targetWeaknessOverlay;
|
private TargetWeaknessOverlay targetWeaknessOverlay;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private TargetMinimapOverlay targetMinimapOverlay;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChatMessageManager chatMessageManager;
|
private ChatMessageManager chatMessageManager;
|
||||||
|
|
||||||
@@ -172,8 +174,15 @@ public class SlayerPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ChatClient chatClient;
|
private ChatClient chatClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private NpcIndicatorsService npcIndicatorsService;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private List<NPC> highlightedTargets = new ArrayList<>();
|
private final List<NPC> targets = new ArrayList<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named("developerMode")
|
||||||
|
boolean developerMode;
|
||||||
|
|
||||||
private final Set<NPC> taggedNpcs = new HashSet<>();
|
private final Set<NPC> taggedNpcs = new HashSet<>();
|
||||||
private int taggedNpcsDiedPrevTick;
|
private int taggedNpcsDiedPrevTick;
|
||||||
@@ -201,13 +210,16 @@ public class SlayerPlugin extends Plugin
|
|||||||
private boolean loginFlag;
|
private boolean loginFlag;
|
||||||
private final List<String> targetNames = new ArrayList<>();
|
private final List<String> targetNames = new ArrayList<>();
|
||||||
|
|
||||||
|
public final Predicate<NPC> isTarget = (n) -> config.highlightTargets() && targets.contains(n);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
|
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
||||||
|
npcIndicatorsService.registerHighlighter(isTarget);
|
||||||
|
|
||||||
overlayManager.add(overlay);
|
overlayManager.add(overlay);
|
||||||
overlayManager.add(targetClickboxOverlay);
|
|
||||||
overlayManager.add(targetWeaknessOverlay);
|
overlayManager.add(targetWeaknessOverlay);
|
||||||
overlayManager.add(targetMinimapOverlay);
|
|
||||||
|
|
||||||
if (client.getGameState() == GameState.LOGGED_IN)
|
if (client.getGameState() == GameState.LOGGED_IN)
|
||||||
{
|
{
|
||||||
@@ -224,23 +236,21 @@ public class SlayerPlugin extends Plugin
|
|||||||
getStringProfileConfig(SlayerConfig.TASK_LOC_KEY), false));
|
getStringProfileConfig(SlayerConfig.TASK_LOC_KEY), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
|
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
||||||
|
npcIndicatorsService.unregisterHighlighter(isTarget);
|
||||||
|
npcIndicatorsService.rebuild();
|
||||||
|
|
||||||
overlayManager.remove(overlay);
|
overlayManager.remove(overlay);
|
||||||
overlayManager.remove(targetClickboxOverlay);
|
|
||||||
overlayManager.remove(targetWeaknessOverlay);
|
overlayManager.remove(targetWeaknessOverlay);
|
||||||
overlayManager.remove(targetMinimapOverlay);
|
|
||||||
removeCounter();
|
removeCounter();
|
||||||
highlightedTargets.clear();
|
targets.clear();
|
||||||
taggedNpcs.clear();
|
taggedNpcs.clear();
|
||||||
cachedXp = -1;
|
cachedXp = -1;
|
||||||
|
|
||||||
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -260,7 +270,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
taskName = "";
|
taskName = "";
|
||||||
amount = 0;
|
amount = 0;
|
||||||
loginFlag = true;
|
loginFlag = true;
|
||||||
highlightedTargets.clear();
|
targets.clear();
|
||||||
taggedNpcs.clear();
|
taggedNpcs.clear();
|
||||||
break;
|
break;
|
||||||
case LOGGED_IN:
|
case LOGGED_IN:
|
||||||
@@ -279,6 +289,16 @@ public class SlayerPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onCommandExecuted(CommandExecuted commandExecuted)
|
||||||
|
{
|
||||||
|
if (developerMode && commandExecuted.getCommand().equals("task"))
|
||||||
|
{
|
||||||
|
setTask(commandExecuted.getArguments()[0], 42, 42);
|
||||||
|
log.debug("Set task to {}", commandExecuted.getArguments()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
int getIntProfileConfig(String key)
|
int getIntProfileConfig(String key)
|
||||||
{
|
{
|
||||||
@@ -313,13 +333,16 @@ public class SlayerPlugin extends Plugin
|
|||||||
setProfileConfig(SlayerConfig.TASK_LOC_KEY, taskLocation);
|
setProfileConfig(SlayerConfig.TASK_LOC_KEY, taskLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe(
|
||||||
|
// Run prior to npc indicators plugin so targets is populated before the isTarget predicate is checked
|
||||||
|
priority = 1
|
||||||
|
)
|
||||||
public void onNpcSpawned(NpcSpawned npcSpawned)
|
public void onNpcSpawned(NpcSpawned npcSpawned)
|
||||||
{
|
{
|
||||||
NPC npc = npcSpawned.getNpc();
|
NPC npc = npcSpawned.getNpc();
|
||||||
if (isTarget(npc))
|
if (isTarget(npc))
|
||||||
{
|
{
|
||||||
highlightedTargets.add(npc);
|
targets.add(npc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +351,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
NPC npc = npcDespawned.getNpc();
|
NPC npc = npcDespawned.getNpc();
|
||||||
taggedNpcs.remove(npc);
|
taggedNpcs.remove(npc);
|
||||||
highlightedTargets.remove(npc);
|
targets.remove(npc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -541,7 +564,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
Actor actor = hitsplatApplied.getActor();
|
Actor actor = hitsplatApplied.getActor();
|
||||||
Hitsplat hitsplat = hitsplatApplied.getHitsplat();
|
Hitsplat hitsplat = hitsplatApplied.getHitsplat();
|
||||||
if (hitsplat.getHitsplatType() == Hitsplat.HitsplatType.DAMAGE_ME && highlightedTargets.contains(actor))
|
if (hitsplat.getHitsplatType() == Hitsplat.HitsplatType.DAMAGE_ME && targets.contains(actor))
|
||||||
{
|
{
|
||||||
// If the actor is in highlightedTargets it must be an NPC and also a task assignment
|
// If the actor is in highlightedTargets it must be an NPC and also a task assignment
|
||||||
taggedNpcs.add((NPC) actor);
|
taggedNpcs.add((NPC) actor);
|
||||||
@@ -562,18 +585,25 @@ public class SlayerPlugin extends Plugin
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
private void onConfigChanged(ConfigChanged event)
|
private void onConfigChanged(ConfigChanged event)
|
||||||
{
|
{
|
||||||
if (!event.getGroup().equals(SlayerConfig.GROUP_NAME) || !event.getKey().equals("infobox"))
|
if (!event.getGroup().equals(SlayerConfig.GROUP_NAME))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.showInfobox())
|
if (event.getKey().equals("infobox"))
|
||||||
{
|
{
|
||||||
clientThread.invoke(this::addCounter);
|
if (config.showInfobox())
|
||||||
|
{
|
||||||
|
clientThread.invoke(this::addCounter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeCounter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
removeCounter();
|
npcIndicatorsService.rebuild();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,27 +649,25 @@ public class SlayerPlugin extends Plugin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = npc.getName();
|
final NPCComposition composition = npc.getTransformedComposition();
|
||||||
if (name == null)
|
if (composition == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = name.toLowerCase();
|
final String name = composition.getName()
|
||||||
|
.replace('\u00A0', ' ')
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
for (String target : targetNames)
|
for (String target : targetNames)
|
||||||
{
|
{
|
||||||
if (name.contains(target))
|
if (name.contains(target))
|
||||||
{
|
{
|
||||||
NPCComposition composition = npc.getTransformedComposition();
|
if (ArrayUtils.contains(composition.getActions(), "Attack")
|
||||||
|
// Pick action is for zygomite-fungi
|
||||||
if (composition != null)
|
|| ArrayUtils.contains(composition.getActions(), "Pick"))
|
||||||
{
|
{
|
||||||
List<String> actions = Arrays.asList(composition.getActions());
|
return true;
|
||||||
if (actions.contains("Attack") || actions.contains("Pick")) //Pick action is for zygomite-fungi
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,13 +690,13 @@ public class SlayerPlugin extends Plugin
|
|||||||
|
|
||||||
private void rebuildTargetList()
|
private void rebuildTargetList()
|
||||||
{
|
{
|
||||||
highlightedTargets.clear();
|
targets.clear();
|
||||||
|
|
||||||
for (NPC npc : client.getNpcs())
|
for (NPC npc : client.getNpcs())
|
||||||
{
|
{
|
||||||
if (isTarget(npc))
|
if (isTarget(npc))
|
||||||
{
|
{
|
||||||
highlightedTargets.add(npc);
|
targets.add(npc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -701,6 +729,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
Task task = Task.getTask(name);
|
Task task = Task.getTask(name);
|
||||||
rebuildTargetNames(task);
|
rebuildTargetNames(task);
|
||||||
rebuildTargetList();
|
rebuildTargetList();
|
||||||
|
npcIndicatorsService.rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCounter()
|
private void addCounter()
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, James Swindle <wilingua@gmail.com>
|
|
||||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
|
||||||
* Copyright (c) 2018, Shaun Dreclin <shaundreclin@gmail.com>
|
|
||||||
* 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.slayer;
|
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Shape;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
import net.runelite.client.util.ColorUtil;
|
|
||||||
|
|
||||||
public class TargetClickboxOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private final SlayerConfig config;
|
|
||||||
private final SlayerPlugin plugin;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
TargetClickboxOverlay(SlayerConfig config, SlayerPlugin plugin)
|
|
||||||
{
|
|
||||||
this.config = config;
|
|
||||||
this.plugin = plugin;
|
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
if (!config.highlightTargets())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NPC> targets = plugin.getHighlightedTargets();
|
|
||||||
for (NPC target : targets)
|
|
||||||
{
|
|
||||||
renderTargetOverlay(graphics, target, config.getTargetColor());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderTargetOverlay(Graphics2D graphics, NPC actor, Color color)
|
|
||||||
{
|
|
||||||
Shape objectClickbox = actor.getConvexHull();
|
|
||||||
if (objectClickbox != null)
|
|
||||||
{
|
|
||||||
graphics.setColor(color);
|
|
||||||
graphics.setStroke(new BasicStroke(2));
|
|
||||||
graphics.draw(objectClickbox);
|
|
||||||
graphics.setColor(ColorUtil.colorWithAlpha(color, color.getAlpha() / 12));
|
|
||||||
graphics.fill(objectClickbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, James Swindle <wilingua@gmail.com>
|
|
||||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
|
||||||
* Copyright (c) 2018, Shaun Dreclin <shaundreclin@gmail.com>
|
|
||||||
* 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.slayer;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.Point;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
|
||||||
|
|
||||||
public class TargetMinimapOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private final SlayerConfig config;
|
|
||||||
private final SlayerPlugin plugin;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
TargetMinimapOverlay(SlayerConfig config, SlayerPlugin plugin)
|
|
||||||
{
|
|
||||||
this.config = config;
|
|
||||||
this.plugin = plugin;
|
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
if (!config.highlightTargets())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NPC> targets = plugin.getHighlightedTargets();
|
|
||||||
for (NPC target : targets)
|
|
||||||
{
|
|
||||||
renderTargetOverlay(graphics, target, config.getTargetColor());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderTargetOverlay(Graphics2D graphics, NPC actor, Color color)
|
|
||||||
{
|
|
||||||
Point minimapLocation = actor.getMinimapLocation();
|
|
||||||
if (minimapLocation != null)
|
|
||||||
{
|
|
||||||
OverlayUtil.renderMinimapLocation(graphics, minimapLocation, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -64,7 +64,7 @@ class TargetWeaknessOverlay extends Overlay
|
|||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
final List<NPC> targets = plugin.getHighlightedTargets();
|
final List<NPC> targets = plugin.getTargets();
|
||||||
|
|
||||||
if (targets.isEmpty() || !config.weaknessPrompt())
|
if (targets.isEmpty() || !config.weaknessPrompt())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -128,4 +128,11 @@ public abstract class Overlay implements LayoutableRenderableEntity
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
setPreferredPosition(null);
|
||||||
|
setPreferredSize(null);
|
||||||
|
setPreferredLocation(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,9 +289,7 @@ public class OverlayManager
|
|||||||
*/
|
*/
|
||||||
public synchronized void resetOverlay(final Overlay overlay)
|
public synchronized void resetOverlay(final Overlay overlay)
|
||||||
{
|
{
|
||||||
overlay.setPreferredPosition(null);
|
overlay.reset();
|
||||||
overlay.setPreferredSize(null);
|
|
||||||
overlay.setPreferredLocation(null);
|
|
||||||
saveOverlay(overlay);
|
saveOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,20 +30,23 @@ import java.awt.Rectangle;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Varbits;
|
import net.runelite.api.Varbits;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class WidgetOverlay extends Overlay
|
public class WidgetOverlay extends Overlay
|
||||||
{
|
{
|
||||||
public static Collection<WidgetOverlay> createOverlays(final Client client)
|
public static Collection<WidgetOverlay> createOverlays(final OverlayManager overlayManager, final Client client)
|
||||||
{
|
{
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT),
|
||||||
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.RESIZABLE_MINIMAP_STONES_WIDGET, OverlayPosition.CANVAS_TOP_RIGHT),
|
||||||
new WidgetOverlay(client, WidgetInfo.FOSSIL_ISLAND_OXYGENBAR, OverlayPosition.TOP_CENTER),
|
// The client forces the oxygen bar below the xp tracker, so set its priority lower
|
||||||
new XpTrackerWidgetOverlay(client, WidgetInfo.EXPERIENCE_TRACKER_WIDGET, OverlayPosition.TOP_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.FOSSIL_ISLAND_OXYGENBAR, OverlayPosition.TOP_CENTER, OverlayPriority.HIGH),
|
||||||
|
new XpTrackerWidgetOverlay(overlayManager, client, WidgetInfo.EXPERIENCE_TRACKER_WIDGET, OverlayPosition.TOP_RIGHT),
|
||||||
new WidgetOverlay(client, WidgetInfo.RAIDS_POINTS_INFOBOX, OverlayPosition.TOP_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.RAIDS_POINTS_INFOBOX, OverlayPosition.TOP_RIGHT),
|
||||||
new WidgetOverlay(client, WidgetInfo.TOB_PARTY_INTERFACE, OverlayPosition.TOP_LEFT),
|
new WidgetOverlay(client, WidgetInfo.TOB_PARTY_INTERFACE, OverlayPosition.TOP_LEFT),
|
||||||
new WidgetOverlay(client, WidgetInfo.TOB_PARTY_STATS, OverlayPosition.TOP_LEFT),
|
new WidgetOverlay(client, WidgetInfo.TOB_PARTY_STATS, OverlayPosition.TOP_LEFT),
|
||||||
@@ -61,7 +64,8 @@ public class WidgetOverlay extends Overlay
|
|||||||
new WidgetOverlay(client, WidgetInfo.LMS_KDA, OverlayPosition.TOP_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.LMS_KDA, OverlayPosition.TOP_RIGHT),
|
||||||
new WidgetOverlay(client, WidgetInfo.GAUNTLET_TIMER_CONTAINER, OverlayPosition.TOP_LEFT),
|
new WidgetOverlay(client, WidgetInfo.GAUNTLET_TIMER_CONTAINER, OverlayPosition.TOP_LEFT),
|
||||||
new WidgetOverlay(client, WidgetInfo.HALLOWED_SEPULCHRE_TIMER_CONTAINER, OverlayPosition.TOP_LEFT),
|
new WidgetOverlay(client, WidgetInfo.HALLOWED_SEPULCHRE_TIMER_CONTAINER, OverlayPosition.TOP_LEFT),
|
||||||
new WidgetOverlay(client, WidgetInfo.HEALTH_OVERLAY_BAR, OverlayPosition.TOP_CENTER),
|
// The client forces the health overlay bar below the xp tracker, so set its priority lower
|
||||||
|
new WidgetOverlay(client, WidgetInfo.HEALTH_OVERLAY_BAR, OverlayPosition.TOP_CENTER, OverlayPriority.HIGH),
|
||||||
new WidgetOverlay(client, WidgetInfo.TOB_HEALTH_BAR, OverlayPosition.TOP_CENTER),
|
new WidgetOverlay(client, WidgetInfo.TOB_HEALTH_BAR, OverlayPosition.TOP_CENTER),
|
||||||
new WidgetOverlay(client, WidgetInfo.NIGHTMARE_PILLAR_HEALTH, OverlayPosition.TOP_LEFT),
|
new WidgetOverlay(client, WidgetInfo.NIGHTMARE_PILLAR_HEALTH, OverlayPosition.TOP_LEFT),
|
||||||
new WidgetOverlay(client, WidgetInfo.VOLCANIC_MINE_VENTS_INFOBOX_GROUP, OverlayPosition.BOTTOM_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.VOLCANIC_MINE_VENTS_INFOBOX_GROUP, OverlayPosition.BOTTOM_RIGHT),
|
||||||
@@ -71,19 +75,26 @@ public class WidgetOverlay extends Overlay
|
|||||||
new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZEABLE_CLASSIC, OverlayPosition.CANVAS_TOP_RIGHT),
|
new WidgetOverlay(client, WidgetInfo.MULTICOMBAT_RESIZEABLE_CLASSIC, OverlayPosition.CANVAS_TOP_RIGHT),
|
||||||
new WidgetOverlay(client, WidgetInfo.TEMPOROSS_STATUS_INDICATOR, OverlayPosition.TOP_LEFT),
|
new WidgetOverlay(client, WidgetInfo.TEMPOROSS_STATUS_INDICATOR, OverlayPosition.TOP_LEFT),
|
||||||
new WidgetOverlay(client, WidgetInfo.BA_HEAL_TEAMMATES, OverlayPosition.BOTTOM_LEFT),
|
new WidgetOverlay(client, WidgetInfo.BA_HEAL_TEAMMATES, OverlayPosition.BOTTOM_LEFT),
|
||||||
new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT)
|
new WidgetOverlay(client, WidgetInfo.BA_TEAM, OverlayPosition.TOP_RIGHT),
|
||||||
|
new WidgetOverlay(client, WidgetInfo.PVP_WILDERNESS_SKULL_CONTAINER, OverlayPosition.DETACHED)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Client client;
|
protected final Client client;
|
||||||
private final WidgetInfo widgetInfo;
|
private final WidgetInfo widgetInfo;
|
||||||
private final Rectangle parentBounds = new Rectangle();
|
private final Rectangle parentBounds = new Rectangle();
|
||||||
|
private boolean revalidate;
|
||||||
|
|
||||||
private WidgetOverlay(final Client client, final WidgetInfo widgetInfo, final OverlayPosition overlayPosition)
|
private WidgetOverlay(final Client client, final WidgetInfo widgetInfo, final OverlayPosition overlayPosition)
|
||||||
|
{
|
||||||
|
this(client, widgetInfo, overlayPosition, OverlayPriority.HIGHEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WidgetOverlay(final Client client, final WidgetInfo widgetInfo, final OverlayPosition overlayPosition, final OverlayPriority overlayPriority)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.widgetInfo = widgetInfo;
|
this.widgetInfo = widgetInfo;
|
||||||
setPriority(OverlayPriority.HIGHEST);
|
setPriority(overlayPriority);
|
||||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||||
setPosition(overlayPosition);
|
setPosition(overlayPosition);
|
||||||
// It's almost possible to drawAfterInterface(widgetInfo.getGroupId()) here, but that fires
|
// It's almost possible to drawAfterInterface(widgetInfo.getGroupId()) here, but that fires
|
||||||
@@ -107,10 +118,34 @@ public class WidgetOverlay extends Overlay
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert widget != null;
|
||||||
|
|
||||||
final Rectangle bounds = getBounds();
|
final Rectangle bounds = getBounds();
|
||||||
// The widget relative pos is relative to the parent
|
// OverlayRenderer sets the overlay bounds to the preferred location if one is set prior to calling render()
|
||||||
widget.setRelativeX(bounds.x - parent.x);
|
// for detached overlays.
|
||||||
widget.setRelativeY(bounds.y - parent.y);
|
if (getPosition() != OverlayPosition.DETACHED || getPreferredLocation() != null)
|
||||||
|
{
|
||||||
|
// The widget relative pos is relative to the parent
|
||||||
|
widget.setRelativeX(bounds.x - parent.x);
|
||||||
|
widget.setRelativeY(bounds.y - parent.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (revalidate)
|
||||||
|
{
|
||||||
|
revalidate = false;
|
||||||
|
log.debug("Revalidating {}", widgetInfo);
|
||||||
|
// Revalidate the widget to reposition it back to its normal location after an overlay reset
|
||||||
|
widget.revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the overlay bounds to the widget bounds so the drag overlay renders correctly.
|
||||||
|
// Note OverlayManager uses original bounds reference to render managing mode and for
|
||||||
|
// onMouseOver, so update the existing bounds vs. replacing the reference.
|
||||||
|
Rectangle widgetBounds = widget.getBounds();
|
||||||
|
bounds.setBounds(widgetBounds.x, widgetBounds.y, widgetBounds.width, widgetBounds.height);
|
||||||
|
}
|
||||||
|
|
||||||
return new Dimension(widget.getWidth(), widget.getHeight());
|
return new Dimension(widget.getWidth(), widget.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,11 +187,22 @@ public class WidgetOverlay extends Overlay
|
|||||||
return getParentBounds(widget);
|
return getParentBounds(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
super.reset();
|
||||||
|
// Revalidate must be called on the client thread, so defer til next frame
|
||||||
|
revalidate = true;
|
||||||
|
}
|
||||||
|
|
||||||
private static class XpTrackerWidgetOverlay extends WidgetOverlay
|
private static class XpTrackerWidgetOverlay extends WidgetOverlay
|
||||||
{
|
{
|
||||||
private XpTrackerWidgetOverlay(Client client, WidgetInfo widgetInfo, OverlayPosition overlayPosition)
|
private final OverlayManager overlayManager;
|
||||||
|
|
||||||
|
private XpTrackerWidgetOverlay(OverlayManager overlayManager, Client client, WidgetInfo widgetInfo, OverlayPosition overlayPosition)
|
||||||
{
|
{
|
||||||
super(client, widgetInfo, overlayPosition);
|
super(client, widgetInfo, overlayPosition);
|
||||||
|
this.overlayManager = overlayManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,7 +234,13 @@ public class WidgetOverlay extends Overlay
|
|||||||
position = OverlayPosition.TOP_LEFT;
|
position = OverlayPosition.TOP_LEFT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setPosition(position);
|
|
||||||
|
if (position != super.getPosition())
|
||||||
|
{
|
||||||
|
log.debug("Xp tracker moved position");
|
||||||
|
setPosition(position);
|
||||||
|
overlayManager.rebuildOverlayLayers();
|
||||||
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,6 +192,12 @@
|
|||||||
"name": "Super Strength (3)",
|
"name": "Super Strength (3)",
|
||||||
"xp": 125
|
"xp": 125
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"level": 57,
|
||||||
|
"icon": 9022,
|
||||||
|
"name": "Magic Essence Potion (3)",
|
||||||
|
"xp": 130
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"level": 59,
|
"level": 59,
|
||||||
"icon": 3000,
|
"icon": 3000,
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.google.common.reflect.ClassPath;
|
||||||
|
import com.google.common.reflect.ClassPath.ClassInfo;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.grapher.graphviz.GraphvizGrapher;
|
||||||
|
import com.google.inject.grapher.graphviz.GraphvizModule;
|
||||||
|
import com.google.inject.testing.fieldbinder.Bind;
|
||||||
|
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||||
|
import com.google.inject.util.Modules;
|
||||||
|
import java.applet.Applet;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.RuneLiteModule;
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
import net.runelite.client.eventbus.EventBus;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class PluginManagerTest
|
||||||
|
{
|
||||||
|
private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder folder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
public Applet applet;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
public Client client;
|
||||||
|
|
||||||
|
private Set<Class<?>> pluginClasses;
|
||||||
|
private Set<Class<?>> configClasses;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws IOException
|
||||||
|
{
|
||||||
|
OkHttpClient okHttpClient = mock(OkHttpClient.class);
|
||||||
|
when(okHttpClient.newCall(any(Request.class)))
|
||||||
|
.thenThrow(new RuntimeException("in plugin manager test"));
|
||||||
|
|
||||||
|
Injector injector = Guice.createInjector(Modules
|
||||||
|
.override(new RuneLiteModule(okHttpClient, () -> null, true, false,
|
||||||
|
RuneLite.DEFAULT_SESSION_FILE,
|
||||||
|
RuneLite.DEFAULT_CONFIG_FILE))
|
||||||
|
.with(BoundFieldModule.of(this)));
|
||||||
|
|
||||||
|
RuneLite.setInjector(injector);
|
||||||
|
|
||||||
|
// Find plugins and configs we expect to have
|
||||||
|
pluginClasses = new HashSet<>();
|
||||||
|
configClasses = new HashSet<>();
|
||||||
|
Set<ClassInfo> classes = ClassPath.from(getClass().getClassLoader()).getTopLevelClassesRecursive(PLUGIN_PACKAGE);
|
||||||
|
for (ClassInfo classInfo : classes)
|
||||||
|
{
|
||||||
|
Class<?> clazz = classInfo.load();
|
||||||
|
PluginDescriptor pluginDescriptor = clazz.getAnnotation(PluginDescriptor.class);
|
||||||
|
if (pluginDescriptor != null)
|
||||||
|
{
|
||||||
|
pluginClasses.add(clazz);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.class.isAssignableFrom(clazz))
|
||||||
|
{
|
||||||
|
configClasses.add(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadPlugins() throws Exception
|
||||||
|
{
|
||||||
|
PluginManager pluginManager = new PluginManager(false, false, null, null, null, null);
|
||||||
|
pluginManager.setOutdated(true);
|
||||||
|
pluginManager.loadCorePlugins();
|
||||||
|
Collection<Plugin> plugins = pluginManager.getPlugins();
|
||||||
|
long expected = pluginClasses.stream()
|
||||||
|
.map(cl -> cl.getAnnotation(PluginDescriptor.class))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(PluginDescriptor::loadWhenOutdated)
|
||||||
|
.count();
|
||||||
|
assertEquals(expected, plugins.size());
|
||||||
|
|
||||||
|
pluginManager = new PluginManager(false, false, null, null, null, null);
|
||||||
|
pluginManager.loadCorePlugins();
|
||||||
|
plugins = pluginManager.getPlugins();
|
||||||
|
|
||||||
|
// Check that the plugins register with the eventbus without errors
|
||||||
|
EventBus eventBus = new EventBus();
|
||||||
|
plugins.forEach(eventBus::register);
|
||||||
|
|
||||||
|
expected = pluginClasses.stream()
|
||||||
|
.map(cl -> cl.getAnnotation(PluginDescriptor.class))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(pd -> !pd.developerPlugin())
|
||||||
|
.count();
|
||||||
|
assertEquals(expected, plugins.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dumpGraph() throws Exception
|
||||||
|
{
|
||||||
|
PluginManager pluginManager = new PluginManager(true, false, null, null, null, null);
|
||||||
|
pluginManager.loadCorePlugins();
|
||||||
|
|
||||||
|
Injector graphvizInjector = Guice.createInjector(new GraphvizModule());
|
||||||
|
GraphvizGrapher graphvizGrapher = graphvizInjector.getInstance(GraphvizGrapher.class);
|
||||||
|
|
||||||
|
File dotFolder = folder.newFolder();
|
||||||
|
try (PrintWriter out = new PrintWriter(new File(dotFolder, "runelite.dot"), "UTF-8"))
|
||||||
|
{
|
||||||
|
graphvizGrapher.setOut(out);
|
||||||
|
graphvizGrapher.setRankdir("TB");
|
||||||
|
graphvizGrapher.graph(RuneLite.getInjector());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Plugin p : pluginManager.getPlugins())
|
||||||
|
{
|
||||||
|
try (PrintWriter out = new PrintWriter(new File(dotFolder, p.getName() + ".dot"), "UTF-8"))
|
||||||
|
{
|
||||||
|
graphvizGrapher.setOut(out);
|
||||||
|
graphvizGrapher.setRankdir("TB");
|
||||||
|
graphvizGrapher.graph(p.getInjector());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureNoDuplicateConfigKeyNames()
|
||||||
|
{
|
||||||
|
for (final Class<?> clazz : configClasses)
|
||||||
|
{
|
||||||
|
final Set<String> configKeyNames = new HashSet<>();
|
||||||
|
|
||||||
|
for (final Method method : clazz.getMethods())
|
||||||
|
{
|
||||||
|
if (!method.isDefault())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ConfigItem annotation = method.getAnnotation(ConfigItem.class);
|
||||||
|
|
||||||
|
if (annotation == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String configKeyName = annotation.keyName();
|
||||||
|
|
||||||
|
if (configKeyNames.contains(configKeyName))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("keyName " + configKeyName + " is duplicated in " + clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
configKeyNames.add(configKeyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Jordan <nightfirecat@protonmail.com>
|
||||||
|
* 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.itemstats;
|
||||||
|
|
||||||
|
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.awt.Color;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.util.Text;
|
||||||
|
import net.runelite.http.api.item.ItemEquipmentStats;
|
||||||
|
import net.runelite.http.api.item.ItemStats;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ItemStatOverlayTest
|
||||||
|
{
|
||||||
|
// Weapon definitions
|
||||||
|
private static final ItemStats ABYSSAL_DAGGER = new ItemStats(true, 0.453, 8,
|
||||||
|
ItemEquipmentStats.builder()
|
||||||
|
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||||
|
.isTwoHanded(false)
|
||||||
|
.astab(75)
|
||||||
|
.aslash(40)
|
||||||
|
.acrush(-4)
|
||||||
|
.amagic(1)
|
||||||
|
.dmagic(1)
|
||||||
|
.str(75)
|
||||||
|
.aspeed(4)
|
||||||
|
.build());
|
||||||
|
private static final ItemStats KATANA = new ItemStats(true, 0, 8,
|
||||||
|
ItemEquipmentStats.builder()
|
||||||
|
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||||
|
.isTwoHanded(true)
|
||||||
|
.astab(7)
|
||||||
|
.aslash(45)
|
||||||
|
.dstab(3)
|
||||||
|
.dslash(7)
|
||||||
|
.dcrush(7)
|
||||||
|
.drange(-3)
|
||||||
|
.str(40)
|
||||||
|
.aspeed(4)
|
||||||
|
.build());
|
||||||
|
private static final ItemStats BLOWPIPE = new ItemStats(true, 0, 0,
|
||||||
|
ItemEquipmentStats.builder()
|
||||||
|
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||||
|
.isTwoHanded(true)
|
||||||
|
.arange(60)
|
||||||
|
.rstr(40)
|
||||||
|
.aspeed(3)
|
||||||
|
.build());
|
||||||
|
private static final ItemStats HEAVY_BALLISTA = new ItemStats(true, 4, 8,
|
||||||
|
ItemEquipmentStats.builder()
|
||||||
|
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||||
|
.isTwoHanded(true)
|
||||||
|
.arange(110)
|
||||||
|
.aspeed(7)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ItemStatOverlay overlay;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
Client client;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
ItemStatConfig config;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
ItemManager itemManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before()
|
||||||
|
{
|
||||||
|
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||||
|
|
||||||
|
when(config.colorBetterUncapped()).thenReturn(new Color(0));
|
||||||
|
when(config.colorWorse()).thenReturn(new Color(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnarmedAttackSpeed()
|
||||||
|
{
|
||||||
|
assertEquals(ItemStatOverlay.UNARMED.getEquipment().getAspeed(), ABYSSAL_DAGGER.getEquipment().getAspeed());
|
||||||
|
assertEquals(ItemStatOverlay.UNARMED.getEquipment().getAspeed(), KATANA.getEquipment().getAspeed());
|
||||||
|
assertEquals(-1, BLOWPIPE.getEquipment().getAspeed() - ItemStatOverlay.UNARMED.getEquipment().getAspeed());
|
||||||
|
assertEquals(3, HEAVY_BALLISTA.getEquipment().getAspeed() - ItemStatOverlay.UNARMED.getEquipment().getAspeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildStatBonusString()
|
||||||
|
{
|
||||||
|
// Empty equipment (fully unarmed)
|
||||||
|
final ItemContainer equipment = mock(ItemContainer.class);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipment);
|
||||||
|
|
||||||
|
String tooltip;
|
||||||
|
String sanitizedTooltip;
|
||||||
|
|
||||||
|
tooltip = overlay.buildStatBonusString(ABYSSAL_DAGGER);
|
||||||
|
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||||
|
assertTrue(sanitizedTooltip.contains("Stab: +75"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Slash: +40"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Crush: -4"));
|
||||||
|
assertEquals(2, StringUtils.countMatches(sanitizedTooltip, "Magic: +1")); // Attack and defense
|
||||||
|
assertTrue(sanitizedTooltip.contains("Melee Str: +75"));
|
||||||
|
assertFalse(sanitizedTooltip.contains("Speed:"));
|
||||||
|
|
||||||
|
tooltip = overlay.buildStatBonusString(KATANA);
|
||||||
|
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||||
|
assertTrue(sanitizedTooltip.contains("Stab: +7"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Slash: +45"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Stab: +3")); // Defense
|
||||||
|
assertTrue(sanitizedTooltip.contains("Slash: +7")); // Defense
|
||||||
|
assertTrue(sanitizedTooltip.contains("Crush: +7")); // Defense
|
||||||
|
assertTrue(sanitizedTooltip.contains("Range: -3")); // Defense
|
||||||
|
assertTrue(sanitizedTooltip.contains("Melee Str: +40"));
|
||||||
|
assertFalse(sanitizedTooltip.contains("Speed:"));
|
||||||
|
|
||||||
|
tooltip = overlay.buildStatBonusString(BLOWPIPE);
|
||||||
|
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||||
|
assertTrue(sanitizedTooltip.contains("Range: +60"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Range Str: +40"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Speed: -1"));
|
||||||
|
assertFalse(sanitizedTooltip.contains("Stab:"));
|
||||||
|
|
||||||
|
tooltip = overlay.buildStatBonusString(HEAVY_BALLISTA);
|
||||||
|
sanitizedTooltip = Text.sanitizeMultilineText(tooltip);
|
||||||
|
assertTrue(sanitizedTooltip.contains("Range: +110"));
|
||||||
|
assertTrue(sanitizedTooltip.contains("Speed: +3"));
|
||||||
|
assertFalse(sanitizedTooltip.contains("Stab:"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -101,7 +101,7 @@ public class NpcIndicatorsPluginTest
|
|||||||
when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("goblin");
|
when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("goblin");
|
||||||
when(npcIndicatorsConfig.deadNpcMenuColor()).thenReturn(Color.RED);
|
when(npcIndicatorsConfig.deadNpcMenuColor()).thenReturn(Color.RED);
|
||||||
|
|
||||||
npcIndicatorsPlugin.rebuildAllNpcs();
|
npcIndicatorsPlugin.rebuild();
|
||||||
|
|
||||||
NPC npc = mock(NPC.class);
|
NPC npc = mock(NPC.class);
|
||||||
when(npc.getName()).thenReturn("Goblin");
|
when(npc.getName()).thenReturn("Goblin");
|
||||||
@@ -127,7 +127,7 @@ public class NpcIndicatorsPluginTest
|
|||||||
when(npcIndicatorsConfig.highlightMenuNames()).thenReturn(true);
|
when(npcIndicatorsConfig.highlightMenuNames()).thenReturn(true);
|
||||||
when(npcIndicatorsConfig.getHighlightColor()).thenReturn(Color.BLUE);
|
when(npcIndicatorsConfig.getHighlightColor()).thenReturn(Color.BLUE);
|
||||||
|
|
||||||
npcIndicatorsPlugin.rebuildAllNpcs();
|
npcIndicatorsPlugin.rebuild();
|
||||||
|
|
||||||
NPC npc = mock(NPC.class);
|
NPC npc = mock(NPC.class);
|
||||||
when(npc.getName()).thenReturn("Goblin");
|
when(npc.getName()).thenReturn("Goblin");
|
||||||
@@ -149,7 +149,7 @@ public class NpcIndicatorsPluginTest
|
|||||||
{
|
{
|
||||||
when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("Joseph");
|
when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("Joseph");
|
||||||
|
|
||||||
npcIndicatorsPlugin.rebuildAllNpcs();
|
npcIndicatorsPlugin.rebuild();
|
||||||
|
|
||||||
NPC npc = mock(NPC.class);
|
NPC npc = mock(NPC.class);
|
||||||
when(npc.getName()).thenReturn("Joseph");
|
when(npc.getName()).thenReturn("Joseph");
|
||||||
@@ -168,7 +168,7 @@ public class NpcIndicatorsPluginTest
|
|||||||
{
|
{
|
||||||
when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("Werewolf");
|
when(npcIndicatorsConfig.getNpcToHighlight()).thenReturn("Werewolf");
|
||||||
|
|
||||||
npcIndicatorsPlugin.rebuildAllNpcs();
|
npcIndicatorsPlugin.rebuild();
|
||||||
|
|
||||||
NPC npc = mock(NPC.class);
|
NPC npc = mock(NPC.class);
|
||||||
when(npc.getName()).thenReturn("Joseph");
|
when(npc.getName()).thenReturn("Joseph");
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Landy Chan <https://github.com/landychan>
|
||||||
|
* 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.prayer;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.testing.fieldbinder.Bind;
|
||||||
|
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
|
import net.runelite.api.Prayer;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.events.ItemContainerChanged;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
|
import net.runelite.http.api.item.ItemEquipmentStats;
|
||||||
|
import net.runelite.http.api.item.ItemStats;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class PrayerPluginTest
|
||||||
|
{
|
||||||
|
private static final ItemStats HIGH_PRAYER_BONUS_WEAPON = new ItemStats(false, 0, 0,
|
||||||
|
ItemEquipmentStats.builder()
|
||||||
|
.slot(EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||||
|
.prayer(50)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PrayerPlugin prayerPlugin;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private PrayerConfig config;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private InfoBoxManager infoBoxManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private ItemManager itemManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before()
|
||||||
|
{
|
||||||
|
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEstimatedTimeRemainingOverOneHour()
|
||||||
|
{
|
||||||
|
ItemContainer itemContainer = mock(ItemContainer.class);
|
||||||
|
when(itemContainer.getItems()).thenReturn(new Item[]{new Item(-1, 1)});
|
||||||
|
when(itemManager.getItemStats(anyInt(), anyBoolean())).thenReturn(HIGH_PRAYER_BONUS_WEAPON);
|
||||||
|
|
||||||
|
when(client.isPrayerActive(Prayer.PRESERVE)).thenReturn(true);
|
||||||
|
when(client.getBoostedSkillLevel(Skill.PRAYER)).thenReturn(99);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(itemContainer);
|
||||||
|
|
||||||
|
prayerPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), itemContainer));
|
||||||
|
|
||||||
|
assertEquals("1:19:12", prayerPlugin.getEstimatedTimeRemaining(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEstimatedTimeRemainingUnderOneHour()
|
||||||
|
{
|
||||||
|
ItemContainer itemContainer = mock(ItemContainer.class);
|
||||||
|
when(itemContainer.getItems()).thenReturn(new Item[]{});
|
||||||
|
|
||||||
|
when(client.isPrayerActive(Prayer.PRESERVE)).thenReturn(true);
|
||||||
|
when(client.getBoostedSkillLevel(Skill.PRAYER)).thenReturn(99);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(itemContainer);
|
||||||
|
|
||||||
|
prayerPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), itemContainer));
|
||||||
|
|
||||||
|
assertEquals("29:42", prayerPlugin.getEstimatedTimeRemaining(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEstimatedTimeRemainingFormatForOrbUnderOneHour()
|
||||||
|
{
|
||||||
|
ItemContainer itemContainer = mock(ItemContainer.class);
|
||||||
|
when(itemContainer.getItems()).thenReturn(new Item[]{});
|
||||||
|
|
||||||
|
when(client.isPrayerActive(Prayer.PRESERVE)).thenReturn(true);
|
||||||
|
when(client.getBoostedSkillLevel(Skill.PRAYER)).thenReturn(99);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(itemContainer);
|
||||||
|
|
||||||
|
prayerPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), itemContainer));
|
||||||
|
|
||||||
|
assertEquals("29m", prayerPlugin.getEstimatedTimeRemaining(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEstimatedTimeRemainingFormatForOrbOverOneHour()
|
||||||
|
{
|
||||||
|
ItemContainer itemContainer = mock(ItemContainer.class);
|
||||||
|
when(itemContainer.getItems()).thenReturn(new Item[]{new Item(-1, 1)});
|
||||||
|
when(itemManager.getItemStats(anyInt(), anyBoolean())).thenReturn(HIGH_PRAYER_BONUS_WEAPON);
|
||||||
|
|
||||||
|
when(client.isPrayerActive(Prayer.PRESERVE)).thenReturn(true);
|
||||||
|
when(client.getBoostedSkillLevel(Skill.PRAYER)).thenReturn(99);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(itemContainer);
|
||||||
|
|
||||||
|
prayerPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), itemContainer));
|
||||||
|
|
||||||
|
assertEquals("79m", prayerPlugin.getEstimatedTimeRemaining(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ import java.io.IOException;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
import static net.runelite.api.ChatMessageType.GAMEMESSAGE;
|
import static net.runelite.api.ChatMessageType.GAMEMESSAGE;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
@@ -55,6 +56,7 @@ import net.runelite.client.chat.ChatCommandManager;
|
|||||||
import net.runelite.client.chat.ChatMessageManager;
|
import net.runelite.client.chat.ChatMessageManager;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.npchighlight.NpcIndicatorsService;
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
import net.runelite.http.api.chat.ChatClient;
|
import net.runelite.http.api.chat.ChatClient;
|
||||||
@@ -168,6 +170,14 @@ public class SlayerPluginTest
|
|||||||
@Bind
|
@Bind
|
||||||
ChatClient chatClient;
|
ChatClient chatClient;
|
||||||
|
|
||||||
|
@Bind
|
||||||
|
@Named("developerMode")
|
||||||
|
boolean developerMode;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
NpcIndicatorsService npcIndicatorsService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SlayerPlugin slayerPlugin;
|
SlayerPlugin slayerPlugin;
|
||||||
|
|
||||||
@@ -871,14 +881,13 @@ public class SlayerPluginTest
|
|||||||
slayerPlugin.onStatChanged(statChanged);
|
slayerPlugin.onStatChanged(statChanged);
|
||||||
|
|
||||||
NPCComposition npcComposition = mock(NPCComposition.class);
|
NPCComposition npcComposition = mock(NPCComposition.class);
|
||||||
|
when(npcComposition.getName()).thenReturn("Suqah");
|
||||||
when(npcComposition.getActions()).thenReturn(new String[]{"Attack"});
|
when(npcComposition.getActions()).thenReturn(new String[]{"Attack"});
|
||||||
|
|
||||||
NPC npc1 = mock(NPC.class);
|
NPC npc1 = mock(NPC.class);
|
||||||
when(npc1.getName()).thenReturn("Suqah");
|
|
||||||
when(npc1.getTransformedComposition()).thenReturn(npcComposition);
|
when(npc1.getTransformedComposition()).thenReturn(npcComposition);
|
||||||
|
|
||||||
NPC npc2 = mock(NPC.class);
|
NPC npc2 = mock(NPC.class);
|
||||||
when(npc2.getName()).thenReturn("Suqah");
|
|
||||||
when(npc2.getTransformedComposition()).thenReturn(npcComposition);
|
when(npc2.getTransformedComposition()).thenReturn(npcComposition);
|
||||||
|
|
||||||
when(client.getNpcs()).thenReturn(Arrays.asList(npc1, npc2));
|
when(client.getNpcs()).thenReturn(Arrays.asList(npc1, npc2));
|
||||||
|
|||||||
Reference in New Issue
Block a user