diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index e81fa36fb9..224412bd53 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -32,6 +32,7 @@ import javax.annotation.Nullable; import net.runelite.api.annotations.VisibleForDevtools; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.vars.AccountType; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; @@ -57,6 +58,11 @@ public interface Client extends GameEngine void setUsername(String name); + /** + * Gets the account type for the logged in player. + */ + AccountType getAccountType(); + Canvas getCanvas(); int getFPS(); diff --git a/runelite-api/src/main/java/net/runelite/api/HeadIcon.java b/runelite-api/src/main/java/net/runelite/api/HeadIcon.java index 6391a00b3a..826c104671 100644 --- a/runelite-api/src/main/java/net/runelite/api/HeadIcon.java +++ b/runelite-api/src/main/java/net/runelite/api/HeadIcon.java @@ -28,5 +28,9 @@ public enum HeadIcon { MELEE, RANGED, - MAGIC; + MAGIC, + RETRIBUTION, + SMITE, + REDEMPTION, + RANGE_MAGE; //used by Kalphite Queen } diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index b425d99314..d54df17d33 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -339,7 +339,12 @@ public enum Varbits /** * Automatically weed farming patches */ - AUTOWEED(5557); + AUTOWEED(5557), + + /** + * The varbit that stores the players {@code AccountType}. + */ + ACCOUNT_TYPE(1777); /** * varbit id diff --git a/runelite-api/src/main/java/net/runelite/api/vars/AccountType.java b/runelite-api/src/main/java/net/runelite/api/vars/AccountType.java new file mode 100644 index 0000000000..3e7a712886 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/vars/AccountType.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Joshua Filby + * 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.api.vars; + +/** + * An enumeration of possible account types. + */ +public enum AccountType +{ + NORMAL, + IRONMAN, + ULTIMATE_IRONMAN, + HARDCORE_IRONMAN; + + /** + * Check if the {@code AccountType} is any of the possible ironman types. + * + * @return {@code true} if the type is any of the ironman types. + */ + public boolean isIronman() + { + return this.ordinal() >= IRONMAN.ordinal() && this.ordinal() <= HARDCORE_IRONMAN.ordinal(); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/ClientLoader.java index 9978fa8eb5..ef657e5bdf 100644 --- a/runelite-client/src/main/java/net/runelite/client/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/ClientLoader.java @@ -28,33 +28,34 @@ import java.applet.Applet; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; -import java.util.Optional; import lombok.extern.slf4j.Slf4j; import net.runelite.http.api.updatecheck.UpdateCheckClient; @Slf4j public class ClientLoader { - public Optional loadRs(boolean disableUpdateCheck) + public Applet loadRs(UpdateCheckMode updateMode) { - boolean isOutdated = false; - - if (!disableUpdateCheck) + if (updateMode == UpdateCheckMode.AUTO) { final UpdateCheckClient updateCheck = new UpdateCheckClient(); - isOutdated = updateCheck.isOutdated(); + updateMode = updateCheck.isOutdated() ? + UpdateCheckMode.VANILLA : + UpdateCheckMode.RUNELITE; } try { - if (isOutdated) + switch (updateMode) { - log.info("RuneLite is outdated - fetching vanilla client"); - return Optional.of(loadVanilla()); + case RUNELITE: + return loadRuneLite(); + default: + case VANILLA: + return loadVanilla(); + case NONE: + return null; } - - log.debug("RuneLite is up to date"); - return Optional.of(loadRuneLite()); } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { @@ -66,7 +67,8 @@ public class ClientLoader } log.error("Error loading RS!", e); - return Optional.empty(); + System.exit(-1); + return null; } } @@ -102,9 +104,9 @@ public class ClientLoader // Must set parent classloader to null, or it will pull from // this class's classloader first URLClassLoader classloader = new URLClassLoader(new URL[] - { - url - }, null); + { + url + }, null); Class clientClass = classloader.loadClass(initialClass); Applet rs = (Applet) clientClass.newInstance(); diff --git a/runelite-client/src/main/java/net/runelite/client/Notifier.java b/runelite-client/src/main/java/net/runelite/client/Notifier.java index 5fa9ca3516..bd2ed482a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/Notifier.java +++ b/runelite-client/src/main/java/net/runelite/client/Notifier.java @@ -27,19 +27,28 @@ package net.runelite.client; import com.google.common.escape.Escaper; import com.google.common.escape.Escapers; import com.google.inject.Inject; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.TrayIcon; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import javax.inject.Provider; import javax.inject.Singleton; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GameState; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.ui.ClientUI; import net.runelite.client.util.OSType; @@ -48,6 +57,25 @@ import net.runelite.client.util.OSType; @Slf4j public class Notifier { + @Getter + @RequiredArgsConstructor + public enum NotificationMode + { + TRAY("System tray"), + BEEP("System beep"), + MESSAGE("Game message"), + FLASH("Screen flash"), + OFF("Off"); + + private final String name; + + @Override + public String toString() + { + return name; + } + } + // Default timeout of notification in milliseconds private static final int DEFAULT_TIMEOUT = 10000; private static final String DOUBLE_QUOTE = "\""; @@ -55,24 +83,32 @@ public class Notifier .addEscape('"', "'") .build(); + // Notifier properties + private static final Color FLASH_COLOR = new Color(255, 0, 0, 70); + private static final int FLASH_DURATION = 2000; + private static final String MESSAGE_COLOR = "FF0000"; + + private final Provider client; private final String appName; private final RuneLiteConfig runeLiteConfig; private final Provider clientUI; private final ScheduledExecutorService executorService; private final Path notifyIconPath; + private Instant flashStart; @Inject private Notifier( final Provider clientUI, + final Provider client, final RuneLiteConfig runeliteConfig, final RuneLiteProperties runeLiteProperties, final ScheduledExecutorService executorService) { + this.client = client; this.appName = runeLiteProperties.getTitle(); this.clientUI = clientUI; this.runeLiteConfig = runeliteConfig; this.executorService = executorService; - this.notifyIconPath = RuneLite.RUNELITE_DIR.toPath().resolve("icon.png"); storeIcon(); } @@ -101,26 +137,63 @@ public class Notifier clientUI.requestFocus(); } - if (runeLiteConfig.enableTrayNotifications()) + switch (runeLiteConfig.notificationMode()) { - sendNotification(appName, message, type, null); + case TRAY: + sendNotification(appName, message, type); + break; + case BEEP: + Toolkit.getDefaultToolkit().beep(); + break; + case MESSAGE: + final Client client = this.client.get(); + + if (client != null && client.getGameState() == GameState.LOGGED_IN) + { + client.addChatMessage(ChatMessageType.GAME, appName, + "" + message + "", ""); + } + + break; + case FLASH: + flashStart = Instant.now(); + break; + } + } + + public void processFlash(final Graphics2D graphics) + { + if (flashStart == null) + { + return; } - if (runeLiteConfig.enableNotificationSound()) + final Client client = this.client.get(); + + if (client == null || client.getGameCycle() % 40 >= 20) { - Toolkit.getDefaultToolkit().beep(); + return; + } + + final Color color = graphics.getColor(); + graphics.setColor(FLASH_COLOR); + graphics.fill(new Rectangle(client.getCanvas().getSize())); + graphics.setColor(color); + + if (Instant.now().minusMillis(FLASH_DURATION).isAfter(flashStart)) + { + flashStart = null; } } private void sendNotification( final String title, final String message, - final TrayIcon.MessageType type, - final String subtitle) + final TrayIcon.MessageType type) { final String escapedTitle = SHELL_ESCAPE.escape(title); final String escapedMessage = SHELL_ESCAPE.escape(message); - final String escapedSubtitle = subtitle != null ? SHELL_ESCAPE.escape(subtitle) : null; + final String escapedSubtitle = null; switch (OSType.getOSType()) { diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 94a0322be5..5c65ebfa96 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -34,10 +34,11 @@ import com.google.inject.Injector; import com.google.inject.Provider; import java.applet.Applet; import java.io.File; -import java.util.Optional; import javax.inject.Singleton; +import joptsimple.ArgumentAcceptingOptionSpec; import joptsimple.OptionParser; import joptsimple.OptionSet; +import joptsimple.util.EnumConverter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.client.account.SessionManager; @@ -119,12 +120,29 @@ public class RuneLite public static void main(String[] args) throws Exception { OptionParser parser = new OptionParser(); - parser.accepts("developer-mode"); - parser.accepts("no-rs"); - parser.accepts("debug"); - parser.accepts("disable-update-check"); + parser.accepts("developer-mode", "Enable developer tools"); + parser.accepts("debug", "Show extra debugging output"); + ArgumentAcceptingOptionSpec updateMode = parser.accepts("rs", "Select client type") + .withRequiredArg() + .ofType(UpdateCheckMode.class) + .defaultsTo(UpdateCheckMode.AUTO) + .withValuesConvertedBy(new EnumConverter(UpdateCheckMode.class) + { + @Override + public UpdateCheckMode convert(String v) + { + return super.convert(v.toUpperCase()); + } + }); + parser.accepts("help", "Show this text").forHelp(); setOptions(parser.parse(args)); + if (getOptions().has("help")) + { + parser.printHelpOn(System.out); + System.exit(0); + } + PROFILES_DIR.mkdirs(); // Setup logger @@ -137,26 +155,15 @@ public class RuneLite } setInjector(Guice.createInjector(new RuneLiteModule())); - injector.getInstance(RuneLite.class).start(); + injector.getInstance(RuneLite.class).start(getOptions().valueOf(updateMode)); } - public void start() throws Exception + public void start(UpdateCheckMode updateMode) throws Exception { // Load RuneLite or Vanilla client - final boolean hasRs = !getOptions().has("no-rs"); - final boolean disableUpdateCheck = getOptions().has("disable-update-check"); - final Optional optionalClient = hasRs - ? new ClientLoader().loadRs(disableUpdateCheck) - : Optional.empty(); + final Applet client = new ClientLoader().loadRs(updateMode); - if (!optionalClient.isPresent() && hasRs) - { - System.exit(-1); - return; - } - - final Applet client = optionalClient.orElse(null); - final boolean isOutdated = client == null || !(client instanceof Client); + final boolean isOutdated = !(client instanceof Client); if (!isOutdated) { diff --git a/runelite-client/src/main/java/net/runelite/client/UpdateCheckMode.java b/runelite-client/src/main/java/net/runelite/client/UpdateCheckMode.java new file mode 100644 index 0000000000..06abaaa07d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/UpdateCheckMode.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 Abex + * 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; + +public enum UpdateCheckMode +{ + AUTO, + NONE, + VANILLA, + RUNELITE +} diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 292cbc2826..18952cde20 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -64,6 +64,7 @@ import net.runelite.api.events.ProjectileMoved; import net.runelite.api.events.SetMessage; import net.runelite.api.widgets.Widget; import static net.runelite.api.widgets.WidgetID.WORLD_MAP; +import net.runelite.client.Notifier; import net.runelite.client.RuneLite; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.input.KeyManager; @@ -98,6 +99,7 @@ public class Hooks private static final ClientThread clientThread = injector.getInstance(ClientThread.class); private static final GameTick tick = new GameTick(); private static final DrawManager renderHooks = injector.getInstance(DrawManager.class); + private static final Notifier notifier = injector.getInstance(Notifier.class); private static Dimension lastStretchedDimensions; private static BufferedImage stretchedImage; @@ -267,6 +269,8 @@ public class Hooks log.warn("Error during overlay rendering", ex); } + notifier.processFlash(graphics2d); + // Stretch the game image if the user has that enabled if (!client.isResized() && client.isStretchedEnabled()) { diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index 97b2964f24..52c66f295d 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -26,6 +26,7 @@ package net.runelite.client.config; import java.awt.Dimension; import net.runelite.api.Constants; +import net.runelite.client.Notifier; @ConfigGroup( keyName = "runelite", @@ -80,32 +81,21 @@ public interface RuneLiteConfig extends Config } @ConfigItem( - keyName = "notificationTray", - name = "Enable tray notifications", - description = "Enables tray notifications", + keyName = "notificationMode", + name = "Notification mode", + description = "Determines mode of notifications", position = 5 ) - default boolean enableTrayNotifications() + default Notifier.NotificationMode notificationMode() { - return true; - } - - @ConfigItem( - keyName = "notificationSound", - name = "Enable sound on notifications", - description = "Enables the playing of a beep sound when notifications are displayed", - position = 6 - ) - default boolean enableNotificationSound() - { - return true; + return Notifier.NotificationMode.TRAY; } @ConfigItem( keyName = "notificationFocused", name = "Send notifications when focused", description = "Toggles idle notifications for when the client is focused", - position = 7 + position = 6 ) default boolean sendNotificationsWhenFocused() { @@ -116,7 +106,7 @@ public interface RuneLiteConfig extends Config keyName = "notificationRequestFocus", name = "Request focus on notification", description = "Toggles window focus request", - position = 8 + position = 7 ) default boolean requestFocusOnNotification() { @@ -127,7 +117,7 @@ public interface RuneLiteConfig extends Config keyName = "fontType", name = "Dynamic Overlay Font", description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.", - position = 9 + position = 8 ) default FontType fontType() { @@ -138,7 +128,7 @@ public interface RuneLiteConfig extends Config keyName = "infoBoxVertical", name = "Display infoboxes vertically", description = "Toggles the infoboxes to display vertically", - position = 10 + position = 9 ) default boolean infoBoxVertical() { @@ -149,7 +139,7 @@ public interface RuneLiteConfig extends Config keyName = "infoBoxWrap", name = "Infobox wrap count", description = "Configures the amount of infoboxes shown before wrapping", - position = 11 + position = 10 ) default int infoBoxWrap() { @@ -160,7 +150,7 @@ public interface RuneLiteConfig extends Config keyName = "containInScreen", name = "Contain in screen", description = "Makes the client stay contained in the screen when attempted to move out of it.
Note: Only works if custom chrome is enabled.", - position = 12 + position = 11 ) default boolean containInScreen() { @@ -171,7 +161,7 @@ public interface RuneLiteConfig extends Config keyName = "rememberScreenBounds", name = "Remember client position", description = "Save the position and size of the client after exiting", - position = 13 + position = 12 ) default boolean rememberScreenBounds() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java index 5e548a0456..f4c153a011 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java @@ -30,6 +30,8 @@ import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; import java.awt.Color; +import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; +import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; @ConfigGroup( keyName = "grounditems", @@ -83,25 +85,25 @@ public interface GroundItemsConfig extends Config } @ConfigItem( - keyName = "highlightMenuOption", - name = "Highlight Menu Option", - description = "Configures whether or not to highlight the menu option", + keyName = "itemHighlightMode", + name = "Item Highlight Mode", + description = "Configures how ground items will be highlighted", position = 5 ) - default boolean highlightMenuOption() + default ItemHighlightMode itemHighlightMode() { - return true; + return ItemHighlightMode.BOTH; } @ConfigItem( - keyName = "highlightMenuItemName", - name = "Highlight Menu Item Name", - description = "Configures whether or not to highlight the menu item name", + keyName = "menuHighlightMode", + name = "Menu Highlight Mode", + description = "Configures what to highlight in right-click menu", position = 6 ) - default boolean highlightMenuItemName() + default MenuHighlightMode menuHighlightMode() { - return false; + return MenuHighlightMode.NAME; } @ConfigItem( diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 19e897201e..3d53678700 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -40,6 +40,7 @@ import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.client.game.ItemManager; +import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; @@ -83,6 +84,11 @@ public class GroundItemsOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { + if (!plugin.isHotKeyPressed() && config.itemHighlightMode() == MENU) + { + return null; + } + final FontMetrics fm = graphics.getFontMetrics(); final Player player = client.getLocalPlayer(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 5f344ab1b9..b6be656bad 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -75,6 +75,11 @@ import net.runelite.client.input.KeyManager; import net.runelite.client.input.MouseManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.OVERLAY; +import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; +import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.BOTH; +import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.NAME; +import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.OPTION; import net.runelite.client.ui.overlay.Overlay; import net.runelite.http.api.item.ItemPrice; @@ -338,7 +343,8 @@ public class GroundItemsPlugin extends Plugin @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - if ((config.highlightMenuOption() || config.highlightMenuItemName()) && event.getOption().equals("Take") + if (config.itemHighlightMode() != OVERLAY + && event.getOption().equals("Take") && event.getType() == MenuAction.GROUND_ITEM_THIRD_OPTION.getId()) { int itemId = event.getIdentifier(); @@ -382,11 +388,14 @@ public class GroundItemsPlugin extends Plugin { String hexColor = Integer.toHexString(color.getRGB() & 0xFFFFFF); String colTag = ""; - if (config.highlightMenuOption()) + final MenuHighlightMode mode = config.menuHighlightMode(); + + if (mode == BOTH || mode == OPTION) { lastEntry.setOption(colTag + "Take"); } - if (config.highlightMenuItemName()) + + if (mode == BOTH || mode == NAME) { String target = lastEntry.getTarget().substring(lastEntry.getTarget().indexOf(">") + 1); lastEntry.setTarget(colTag + target); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/config/ItemHighlightMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/config/ItemHighlightMode.java new file mode 100644 index 0000000000..9b873a639e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/config/ItemHighlightMode.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.grounditems.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum ItemHighlightMode +{ + OVERLAY("Overlay"), + MENU("Right-click menu"), + BOTH("Both"); + + private final String name; + + @Override + public String toString() + { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/config/MenuHighlightMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/config/MenuHighlightMode.java new file mode 100644 index 0000000000..705f322cc0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/config/MenuHighlightMode.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.grounditems.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum MenuHighlightMode +{ + OPTION("Menu option"), + NAME("Menu item name"), + BOTH("Both"); + + private final String name; + + @Override + public String toString() + { + return name; + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 25302619f3..9f224efc95 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -27,6 +27,7 @@ package net.runelite.mixins; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; +import net.runelite.api.vars.AccountType; import net.runelite.api.ChatMessageType; import net.runelite.api.ClanMember; import net.runelite.api.GameState; @@ -160,6 +161,25 @@ public abstract class RSClientMixin implements RSClient interpolateObjectAnimations = interpolate; } + @Inject + @Override + public AccountType getAccountType() + { + int varbit = getVar(Varbits.ACCOUNT_TYPE); + + switch (varbit) + { + case 1: + return AccountType.IRONMAN; + case 2: + return AccountType.ULTIMATE_IRONMAN; + case 3: + return AccountType.HARDCORE_IRONMAN; + } + + return AccountType.NORMAL; + } + @Inject @Override public Tile getSelectedRegionTile() diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNpcCompositionMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNpcCompositionMixin.java index 061d6d890e..b359786653 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSNpcCompositionMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNpcCompositionMixin.java @@ -28,6 +28,7 @@ import net.runelite.api.HeadIcon; import static net.runelite.api.HeadIcon.MAGIC; import static net.runelite.api.HeadIcon.MELEE; import static net.runelite.api.HeadIcon.RANGED; +import static net.runelite.api.HeadIcon.RANGE_MAGE; import net.runelite.api.events.NpcActionChanged; import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; @@ -50,6 +51,8 @@ public abstract class RSNpcCompositionMixin implements RSNPCComposition return RANGED; case 2: return MAGIC; + case 6: + return RANGE_MAGE; default: return null; } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java index bc75866702..1dd3a66a3a 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSPlayerMixin.java @@ -31,6 +31,9 @@ import net.runelite.api.HeadIcon; import static net.runelite.api.HeadIcon.MAGIC; import static net.runelite.api.HeadIcon.MELEE; import static net.runelite.api.HeadIcon.RANGED; +import static net.runelite.api.HeadIcon.REDEMPTION; +import static net.runelite.api.HeadIcon.RETRIBUTION; +import static net.runelite.api.HeadIcon.SMITE; import net.runelite.api.Model; import net.runelite.api.Perspective; import net.runelite.api.Point; @@ -88,6 +91,12 @@ public abstract class RSPlayerMixin implements RSPlayer return RANGED; case 2: return MAGIC; + case 3: + return RETRIBUTION; + case 4: + return SMITE; + case 5: + return REDEMPTION; default: return null; }