Merge remote-tracking branch 'upstream/master' into master
This commit is contained in:
@@ -185,7 +185,7 @@ public interface ChatColorConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "opaqueClanChatMessageHighlight",
|
||||
keyName = "opaqueClanMessageHighlight",
|
||||
name = "Clan chat message highlight",
|
||||
description = "Color of highlights in Clan Chat messages",
|
||||
section = opaqueSection
|
||||
@@ -582,7 +582,7 @@ public interface ChatColorConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 64,
|
||||
keyName = "transparentClanChatMessageHighlight",
|
||||
keyName = "transparentClanMessageHighlight",
|
||||
name = "Clan chat message highlight (transparent)",
|
||||
description = "Color of highlights in Clan Chat messages (transparent)",
|
||||
section = transparentSection
|
||||
|
||||
@@ -448,7 +448,7 @@ public class ConfigManager
|
||||
|
||||
public void setConfiguration(String groupName, String profile, String key, @NonNull String value)
|
||||
{
|
||||
if (Strings.isNullOrEmpty(groupName) || Strings.isNullOrEmpty(key))
|
||||
if (Strings.isNullOrEmpty(groupName) || Strings.isNullOrEmpty(key) || key.indexOf(':') != -1)
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@@ -191,4 +191,15 @@ public interface CameraConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "preserveYaw",
|
||||
name = "Preserve yaw on world hop",
|
||||
description = "Preserves the camera yaw (left/right) when world hopping.",
|
||||
position = 14
|
||||
)
|
||||
default boolean preserveYaw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.events.BeforeRender;
|
||||
import net.runelite.api.events.ClientTick;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.events.ScriptPreFired;
|
||||
@@ -89,7 +90,8 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
|
||||
* Whether or not the current menu has any non-ignored menu entries
|
||||
*/
|
||||
private boolean menuHasEntries;
|
||||
|
||||
private int savedCameraYaw;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@@ -418,6 +420,24 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
switch (gameStateChanged.getGameState())
|
||||
{
|
||||
case HOPPING:
|
||||
savedCameraYaw = client.getMapAngle();
|
||||
break;
|
||||
case LOGGED_IN:
|
||||
if (savedCameraYaw != 0 && config.preserveYaw())
|
||||
{
|
||||
client.setCameraYawTarget(savedCameraYaw);
|
||||
}
|
||||
savedCameraYaw = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The event that is triggered when a mouse button is pressed
|
||||
* In this method the right click is changed to a middle-click to enable rotating the camera
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ChatCommandsPlugin extends Plugin
|
||||
private static final String COX_TEAM_SIZES = "(?:\\d+(?:\\+|-\\d+)? players|Solo)";
|
||||
private static final Pattern RAIDS_PB_PATTERN = Pattern.compile("<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>" + COX_TEAM_SIZES + "</col> Duration:</col> <col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(new personal best\\)</col>");
|
||||
private static final Pattern RAIDS_DURATION_PATTERN = Pattern.compile("<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>" + COX_TEAM_SIZES + "</col> Duration:</col> <col=ff0000>[0-9:.]+</col> Personal best: </col><col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col>");
|
||||
private static final Pattern TOB_WAVE_PB_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: <col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(Personal best!\\)");
|
||||
private static final Pattern TOB_WAVE_PB_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: <col=ff0000>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(new personal best\\)");
|
||||
private static final Pattern TOB_WAVE_DURATION_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: <col=ff0000>[0-9:.]+</col><br></col>Personal best: (?<pb>[0-9:]+(?:\\.[0-9]+)?)");
|
||||
private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) <col=[0-9a-f]{6}>[0-9:.]+</col>\\. Personal best: (?:<col=ff0000>)?(?<pb>[0-9:]+(?:\\.[0-9]+)?)");
|
||||
private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) <col=[0-9a-f]{6}>(?<pb>[0-9:]+(?:\\.[0-9]+)?)</col> \\(new personal best\\)");
|
||||
@@ -245,6 +245,11 @@ public class ChatCommandsPlugin extends Plugin
|
||||
configManager.setRSProfileConfiguration("killcount", boss.toLowerCase(), killcount);
|
||||
}
|
||||
|
||||
private void unsetKc(String boss)
|
||||
{
|
||||
configManager.unsetRSProfileConfiguration("killcount", boss.toLowerCase());
|
||||
}
|
||||
|
||||
private int getKc(String boss)
|
||||
{
|
||||
Integer killCount = configManager.getRSProfileConfiguration("killcount", boss.toLowerCase(), int.class);
|
||||
@@ -256,6 +261,11 @@ public class ChatCommandsPlugin extends Plugin
|
||||
configManager.setRSProfileConfiguration("personalbest", boss.toLowerCase(), seconds);
|
||||
}
|
||||
|
||||
private void unsetPb(String boss)
|
||||
{
|
||||
configManager.unsetRSProfileConfiguration("personalbest", boss.toLowerCase());
|
||||
}
|
||||
|
||||
private double getPb(String boss)
|
||||
{
|
||||
Double personalBest = configManager.getRSProfileConfiguration("personalbest", boss.toLowerCase(), double.class);
|
||||
@@ -280,19 +290,30 @@ public class ChatCommandsPlugin extends Plugin
|
||||
String boss = matcher.group(1);
|
||||
int kc = Integer.parseInt(matcher.group(2));
|
||||
|
||||
boss = KILLCOUNT_RENAMES.getOrDefault(boss, boss);
|
||||
String renamedBoss = KILLCOUNT_RENAMES
|
||||
.getOrDefault(boss, boss)
|
||||
// The config service doesn't support keys with colons in them
|
||||
.replace(":", "");
|
||||
if (boss != renamedBoss)
|
||||
{
|
||||
// Unset old TOB kc
|
||||
unsetKc(boss);
|
||||
unsetPb(boss);
|
||||
unsetKc(boss.replace(":", "."));
|
||||
unsetPb(boss.replace(":", "."));
|
||||
}
|
||||
|
||||
setKc(boss, kc);
|
||||
setKc(renamedBoss, kc);
|
||||
// We either already have the pb, or need to remember the boss for the upcoming pb
|
||||
if (lastPb > -1)
|
||||
{
|
||||
log.debug("Got out-of-order personal best for {}: {}", boss, lastPb);
|
||||
setPb(boss, lastPb);
|
||||
log.debug("Got out-of-order personal best for {}: {}", renamedBoss, lastPb);
|
||||
setPb(renamedBoss, lastPb);
|
||||
lastPb = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastBossKill = boss;
|
||||
lastBossKill = renamedBoss;
|
||||
lastBossTime = client.getTickCount();
|
||||
}
|
||||
return;
|
||||
@@ -1687,6 +1708,19 @@ public class ChatCommandsPlugin extends Plugin
|
||||
case "raids 2":
|
||||
return "Theatre of Blood";
|
||||
|
||||
case "Theatre of Blood: Story Mode":
|
||||
case "tob sm":
|
||||
case "tob story mode":
|
||||
case "tob story":
|
||||
return "Theatre of Blood Story Mode";
|
||||
|
||||
case "Theatre of Blood: Hard Mode":
|
||||
case "tob cm":
|
||||
case "tob hm":
|
||||
case "tob hard mode":
|
||||
case "tob hard":
|
||||
return "Theatre of Blood Hard Mode";
|
||||
|
||||
// agility course
|
||||
case "prif":
|
||||
case "prifddinas":
|
||||
|
||||
@@ -330,6 +330,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
private final String text;
|
||||
private final String npc;
|
||||
private final int objectId;
|
||||
@Nullable
|
||||
private final WorldPoint location;
|
||||
private final String solution;
|
||||
@Nullable
|
||||
@@ -371,7 +372,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
this(text, npc, objectId, location, solution, null);
|
||||
}
|
||||
|
||||
private CrypticClue(String text, String npc, int objectId, WorldPoint location, String solution, @Nullable String questionText)
|
||||
private CrypticClue(String text, String npc, int objectId, @Nullable WorldPoint location, String solution, @Nullable String questionText)
|
||||
{
|
||||
this.text = text;
|
||||
this.npc = npc;
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.InventoryID;
|
||||
@@ -167,6 +168,7 @@ public class ThreeStepCrypticClue extends ClueScroll implements TextClueScroll,
|
||||
return clueSteps.stream()
|
||||
.filter(s -> !s.getValue())
|
||||
.map(s -> s.getKey().getLocation())
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(WorldPoint[]::new);
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,6 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
private int vboUiHandle;
|
||||
|
||||
private int fboSceneHandle;
|
||||
private int texSceneHandle;
|
||||
private int rboSceneHandle;
|
||||
|
||||
// scene vertex buffer
|
||||
@@ -297,7 +296,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
{
|
||||
try
|
||||
{
|
||||
texSceneHandle = fboSceneHandle = rboSceneHandle = -1; // AA FBO
|
||||
fboSceneHandle = rboSceneHandle = -1; // AA FBO
|
||||
unorderedModels = smallModels = largeModels = 0;
|
||||
drawingModel = false;
|
||||
|
||||
@@ -737,28 +736,13 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
gl.glRenderbufferStorageMultisample(gl.GL_RENDERBUFFER, aaSamples, gl.GL_RGBA, width, height);
|
||||
gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_RENDERBUFFER, rboSceneHandle);
|
||||
|
||||
// Create texture
|
||||
texSceneHandle = glGenTexture(gl);
|
||||
gl.glBindTexture(gl.GL_TEXTURE_2D_MULTISAMPLE, texSceneHandle);
|
||||
gl.glTexImage2DMultisample(gl.GL_TEXTURE_2D_MULTISAMPLE, aaSamples, gl.GL_RGBA, width, height, true);
|
||||
|
||||
// Bind texture
|
||||
gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D_MULTISAMPLE, texSceneHandle, 0);
|
||||
|
||||
// Reset
|
||||
gl.glBindTexture(gl.GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0);
|
||||
gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
private void shutdownAAFbo()
|
||||
{
|
||||
if (texSceneHandle != -1)
|
||||
{
|
||||
glDeleteTexture(gl, texSceneHandle);
|
||||
texSceneHandle = -1;
|
||||
}
|
||||
|
||||
if (fboSceneHandle != -1)
|
||||
{
|
||||
glDeleteFrameBuffer(gl, fboSceneHandle);
|
||||
|
||||
@@ -110,6 +110,13 @@ public class IdleNotifierPlugin extends Plugin
|
||||
return configManager.getConfig(IdleNotifierConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
// can't tell when 6hr will be if enabled while already logged in
|
||||
sixHourWarningTime = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged event)
|
||||
{
|
||||
|
||||
@@ -419,6 +419,17 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapTeleToPoh",
|
||||
name = "Tele to POH",
|
||||
description = "Swap Wear with Tele to POH on the construction cape",
|
||||
section = itemSection
|
||||
)
|
||||
default boolean swapTeleToPoh()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapAbyssTeleport",
|
||||
name = "Teleport to Abyss",
|
||||
|
||||
@@ -348,6 +348,8 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
swap("value", "sell 10", () -> shiftModifier() && config.shopSell() == SellMode.SELL_10);
|
||||
swap("value", "sell 50", () -> shiftModifier() && config.shopSell() == SellMode.SELL_50);
|
||||
|
||||
swap("wear", "tele to poh", config::swapTeleToPoh);
|
||||
|
||||
swap("wear", "rub", config::swapTeleportItem);
|
||||
swap("wear", "teleport", config::swapTeleportItem);
|
||||
swap("wield", "teleport", config::swapTeleportItem);
|
||||
|
||||
@@ -96,6 +96,7 @@ public class AlchemyRoom extends MTARoom
|
||||
|
||||
private AlchemyItem best;
|
||||
private Cupboard suggestion;
|
||||
private boolean hintSet;
|
||||
|
||||
@Inject
|
||||
private AlchemyRoom(Client client, MTAConfig config, MTAPlugin plugin, ItemManager itemManager, InfoBoxManager infoBoxManager)
|
||||
@@ -221,6 +222,11 @@ public class AlchemyRoom extends MTARoom
|
||||
if (!inside())
|
||||
{
|
||||
reset();
|
||||
if (hintSet)
|
||||
{
|
||||
client.clearHintArrow();
|
||||
hintSet = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,6 +387,7 @@ public class AlchemyRoom extends MTARoom
|
||||
{
|
||||
client.setHintArrow(object.getWorldLocation());
|
||||
found = true;
|
||||
hintSet = true;
|
||||
}
|
||||
|
||||
BufferedImage image = itemManager.getImage(alchemyItem.getId());
|
||||
@@ -395,6 +402,7 @@ public class AlchemyRoom extends MTARoom
|
||||
if (!found && suggestion != null)
|
||||
{
|
||||
client.setHintArrow(suggestion.gameObject.getWorldLocation());
|
||||
hintSet = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public class EnchantmentRoom extends MTARoom
|
||||
|
||||
private final Client client;
|
||||
private final List<WorldPoint> dragonstones = new ArrayList<>();
|
||||
private boolean hintSet;
|
||||
|
||||
@Inject
|
||||
private EnchantmentRoom(MTAConfig config, Client client)
|
||||
@@ -64,6 +65,11 @@ public class EnchantmentRoom extends MTARoom
|
||||
if (gameStateChanged.getGameState() == GameState.LOADING)
|
||||
{
|
||||
dragonstones.clear();
|
||||
if (hintSet)
|
||||
{
|
||||
client.clearHintArrow();
|
||||
hintSet = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,10 +85,12 @@ public class EnchantmentRoom extends MTARoom
|
||||
if (nearest != null)
|
||||
{
|
||||
client.setHintArrow(nearest);
|
||||
hintSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
client.clearHintArrow();
|
||||
hintSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -253,11 +253,23 @@ public interface ScreenshotConfig extends Config
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "collectionLogEntries",
|
||||
name = "Screenshot collection log entries",
|
||||
description = "Take a screenshot when completing an entry in the collection log",
|
||||
position = 18,
|
||||
section = whatSection
|
||||
)
|
||||
default boolean screenshotCollectionLogEntries()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hotkey",
|
||||
name = "Screenshot hotkey",
|
||||
description = "When you press this key a screenshot will be taken",
|
||||
position = 18
|
||||
position = 19
|
||||
)
|
||||
default Keybind hotkey()
|
||||
{
|
||||
|
||||
@@ -95,6 +95,7 @@ import net.runelite.client.util.Text;
|
||||
@Slf4j
|
||||
public class ScreenshotPlugin extends Plugin
|
||||
{
|
||||
private static final String COLLECTION_LOG_TEXT = "New item added to your collection log: ";
|
||||
private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!";
|
||||
private static final Map<Integer, String> CHEST_LOOT_EVENTS = ImmutableMap.of(12127, "The Gauntlet");
|
||||
private static final int GAUNTLET_REGION = 7512;
|
||||
@@ -456,6 +457,13 @@ public class ScreenshotPlugin extends Plugin
|
||||
takeScreenshot(fileName, "Duels");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.screenshotCollectionLogEntries() && chatMessage.startsWith(COLLECTION_LOG_TEXT))
|
||||
{
|
||||
String entry = Text.removeTags(chatMessage).substring(COLLECTION_LOG_TEXT.length());
|
||||
String fileName = "Collection log (" + entry + ")";
|
||||
takeScreenshot(fileName, "Collection Log");
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -45,7 +45,8 @@ enum Boss
|
||||
KING_BLACK_DRAGON(NpcID.KING_BLACK_DRAGON, NpcID.KING_BLACK_DRAGON_2642, NpcID.KING_BLACK_DRAGON_6502),
|
||||
KRIL_TSUROTH(NpcID.KRIL_TSUTSAROTH, NpcID.KRIL_TSUTSAROTH_6495),
|
||||
VENETENATIS(NpcID.VENENATIS, NpcID.VENENATIS_6610),
|
||||
VETION(NpcID.VETION, NpcID.VETION_REBORN);
|
||||
VETION(NpcID.VETION, NpcID.VETION_REBORN),
|
||||
ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA, NpcID.ALCHEMICAL_HYDRA_8616, NpcID.ALCHEMICAL_HYDRA_8617, NpcID.ALCHEMICAL_HYDRA_8618, NpcID.ALCHEMICAL_HYDRA_8619, NpcID.ALCHEMICAL_HYDRA_8620, NpcID.ALCHEMICAL_HYDRA_8621, NpcID.ALCHEMICAL_HYDRA_8622, NpcID.ALCHEMICAL_HYDRA_8634);
|
||||
|
||||
private final Set<Integer> ids;
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.statusbars;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.util.function.Supplier;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.components.TextComponent;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
class BarRenderer
|
||||
@@ -100,28 +102,26 @@ class BarRenderer
|
||||
|
||||
private void renderIconsAndCounters(StatusBarsConfig config, Graphics2D graphics, int x, int y)
|
||||
{
|
||||
graphics.setFont(FontManager.getRunescapeSmallFont());
|
||||
graphics.setColor(Color.WHITE);
|
||||
String counterText = Integer.toString(currentValue);
|
||||
final int widthOfCounter = graphics.getFontMetrics().stringWidth(counterText);
|
||||
int centerText = (WIDTH - PADDING) / 2 - (widthOfCounter / 2);
|
||||
final Image icon = iconSupplier.get();
|
||||
final boolean skillIconEnabled = config.enableSkillIcon();
|
||||
|
||||
if (skillIconEnabled)
|
||||
{
|
||||
final Image icon = iconSupplier.get();
|
||||
graphics.drawImage(icon, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - icon.getWidth(null), null);
|
||||
}
|
||||
|
||||
if (config.enableCounter())
|
||||
{
|
||||
if (config.enableSkillIcon())
|
||||
{
|
||||
graphics.drawImage(icon, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - icon.getWidth(null), null);
|
||||
graphics.drawString(counterText, x + centerText + PADDING, y + SKILL_ICON_HEIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.drawString(counterText, x + centerText + PADDING, y + COUNTER_ICON_HEIGHT);
|
||||
}
|
||||
}
|
||||
else if (config.enableSkillIcon())
|
||||
{
|
||||
graphics.drawImage(icon, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - icon.getWidth(null), null);
|
||||
graphics.setFont(FontManager.getRunescapeSmallFont());
|
||||
final String counterText = Integer.toString(currentValue);
|
||||
final int widthOfCounter = graphics.getFontMetrics().stringWidth(counterText);
|
||||
final int centerText = (WIDTH - PADDING) / 2 - (widthOfCounter / 2);
|
||||
final int yOffset = skillIconEnabled ? SKILL_ICON_HEIGHT : COUNTER_ICON_HEIGHT;
|
||||
|
||||
final TextComponent textComponent = new TextComponent();
|
||||
textComponent.setText(counterText);
|
||||
textComponent.setPosition(new Point(x + centerText + PADDING, y + yOffset));
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,24 @@ public class WorldMapOverlay extends Overlay
|
||||
|
||||
if (worldPoint.isSnapToEdge())
|
||||
{
|
||||
if (worldMapRectangle.contains(drawPoint.getX(), drawPoint.getY()))
|
||||
// Get a smaller rect for edge-snapped icons so they display correctly at the edge
|
||||
final Rectangle snappedRect = widget.getBounds();
|
||||
snappedRect.grow(-image.getWidth() / 2, -image.getHeight() / 2);
|
||||
|
||||
final Rectangle unsnappedRect = new Rectangle(snappedRect);
|
||||
if (worldPoint.getImagePoint() != null)
|
||||
{
|
||||
int dx = worldPoint.getImagePoint().getX() - (image.getWidth() / 2);
|
||||
int dy = worldPoint.getImagePoint().getY() - (image.getHeight() / 2);
|
||||
unsnappedRect.translate(dx, dy);
|
||||
}
|
||||
// Make the unsnap rect slightly smaller so a smaller snapped image doesn't cause a freak out
|
||||
if (worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
unsnappedRect.grow(-image.getWidth(), -image.getHeight());
|
||||
}
|
||||
|
||||
if (unsnappedRect.contains(drawPoint.getX(), drawPoint.getY()))
|
||||
{
|
||||
if (worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
@@ -141,7 +158,7 @@ public class WorldMapOverlay extends Overlay
|
||||
}
|
||||
else
|
||||
{
|
||||
drawPoint = clipToRectangle(drawPoint, worldMapRectangle);
|
||||
drawPoint = clipToRectangle(drawPoint, snappedRect);
|
||||
if (!worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
worldPoint.setCurrentlyEdgeSnapped(true);
|
||||
|
||||
@@ -60,6 +60,12 @@ public class WorldMapOverlayMouseListener extends MouseAdapter
|
||||
if (SwingUtilities.isLeftMouseButton(e) && !worldMapPoints.isEmpty())
|
||||
{
|
||||
Point mousePos = client.getMouseCanvasPosition();
|
||||
final Widget view = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
|
||||
if (view == null)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
for (WorldMapPoint worldMapPoint : worldMapPoints)
|
||||
{
|
||||
@@ -77,6 +83,7 @@ public class WorldMapOverlayMouseListener extends MouseAdapter
|
||||
RenderOverview renderOverview = client.getRenderOverview();
|
||||
renderOverview.setWorldMapPositionTarget(target);
|
||||
}
|
||||
e.consume();
|
||||
return worldMapPoint.onClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ChatColorConfigTest
|
||||
{
|
||||
@Test
|
||||
public void testUniqueKeys()
|
||||
{
|
||||
final Set<String> configKeyNames = new HashSet<>();
|
||||
|
||||
for (Method method : ChatColorConfig.class.getMethods())
|
||||
{
|
||||
final ConfigItem annotation = method.getAnnotation(ConfigItem.class);
|
||||
if (annotation == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final String configKeyName = annotation.keyName();
|
||||
if (configKeyNames.contains(configKeyName))
|
||||
{
|
||||
fail("keyName " + configKeyName + " is duplicated in " + ChatColorConfig.class);
|
||||
}
|
||||
|
||||
configKeyNames.add(configKeyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ public class ChatCommandsPluginTest
|
||||
@Test
|
||||
public void testTheatreOfBlood()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>37:04</col> (Personal best!)", null, 0);
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>37:04</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: <col=ff0000>73</col>.", null, 0);
|
||||
@@ -167,7 +167,7 @@ public class ChatCommandsPluginTest
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4.0);
|
||||
|
||||
// Precise times
|
||||
ChatMessage chatMessagePrecise = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>37:04.20</col> (Personal best!)", null, 0);
|
||||
ChatMessage chatMessagePrecise = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>37:04.20</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessagePrecise);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
@@ -194,6 +194,21 @@ public class ChatCommandsPluginTest
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4.4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTheatreOfBloodStoryMode()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "",
|
||||
"Theatre of Blood wave completion time: <col=ff0000>5:04</col> (new personal best)<br>" +
|
||||
"Theatre of Blood total completion time: <col=ff0000>24:39</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood: Story Mode count is: <col=ff0000>73</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood story mode", 73);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood story mode", 5 * 60 + 4.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWintertodt()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Jordan Atwood <jordan.atwood423@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.cluescrolls.clues;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.util.Text;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ThreeStepCrypticClueTest
|
||||
{
|
||||
@Test
|
||||
public void forTextEmptyString()
|
||||
{
|
||||
assertNull(ThreeStepCrypticClue.forText("", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonNullLocations()
|
||||
{
|
||||
final String clueText = Joiner.on("<br><br>").join(CrypticClue.CLUES.stream().map(CrypticClue::getText).toArray());
|
||||
final ThreeStepCrypticClue clue = ThreeStepCrypticClue.forText(Text.sanitizeMultilineText(clueText).toLowerCase(), clueText);
|
||||
|
||||
assertNotNull(clue);
|
||||
for (final WorldPoint location : clue.getLocations())
|
||||
{
|
||||
assertNotNull(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user