Merge remote-tracking branch 'upstream/master' into runelite

This commit is contained in:
ThatGamerBlue
2021-02-22 00:13:07 +00:00
43 changed files with 799 additions and 289 deletions

View File

@@ -51,6 +51,7 @@ import net.runelite.api.TileObject;
import net.runelite.api.WallObject;
import net.runelite.api.coords.LocalPoint;
import net.runelite.client.task.Schedule;
import net.runelite.client.task.Scheduler;
@Singleton
public class ModelOutlineRenderer
@@ -101,9 +102,10 @@ public class ModelOutlineRenderer
private List<List<PixelDistanceAlpha>> precomputedDistancePriorities;
@Inject
private ModelOutlineRenderer(Client client)
private ModelOutlineRenderer(Client client, Scheduler scheduler)
{
this.client = client;
scheduler.registerObject(this);
reset();
}

View File

@@ -30,7 +30,6 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.openosrs.client.graphics.ModelOutlineRenderer;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
@@ -59,34 +58,21 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.client.account.SessionManager;
import net.runelite.client.callback.Hooks;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.CommandManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.discord.DiscordService;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.externalplugins.ExternalPluginManager;
import net.runelite.client.game.FriendChatManager;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.LootManager;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.OPRSExternalPluginManager;
import net.runelite.client.rs.ClientLoader;
import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.FatalErrorDialog;
import com.openosrs.client.ui.OpenOSRSSplashScreen;
import net.runelite.client.ui.SplashScreen;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.OverlayRenderer;
import net.runelite.client.ui.overlay.WidgetOverlay;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
import net.runelite.client.ws.PartyService;
import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
@@ -125,9 +111,6 @@ public class RuneLite
@Inject
private ConfigManager configManager;
@Inject
private DrawManager drawManager;
@Inject
private SessionManager sessionManager;
@@ -140,58 +123,19 @@ public class RuneLite
@Inject
private ClientUI clientUI;
@Inject
private Provider<InfoBoxManager> infoBoxManager;
@Inject
private OverlayManager overlayManager;
@Inject
private Provider<PartyService> partyService;
@Inject
private Provider<ItemManager> itemManager;
@Inject
private Provider<OverlayRenderer> overlayRenderer;
@Inject
private Provider<FriendChatManager> friendsChatManager;
@Inject
private Provider<ChatMessageManager> chatMessageManager;
@Inject
private Provider<MenuManager> menuManager;
@Inject
private Provider<CommandManager> commandManager;
@Inject
private Provider<TooltipOverlay> tooltipOverlay;
@Inject
private Provider<WorldMapOverlay> worldMapOverlay;
@Inject
private Provider<ModelOutlineRenderer> modelOutlineRenderer;
@Inject
private Provider<LootManager> lootManager;
@Inject
private Provider<ChatboxPanelManager> chatboxPanelManager;
@Inject
private Provider<Hooks> hooks;
@Inject
@Nullable
private Client client;
@Inject
private Scheduler scheduler;
public static void main(String[] args) throws Exception
{
Locale.setDefault(Locale.ENGLISH);
@@ -375,27 +319,11 @@ public class RuneLite
eventBus.register(pluginManager);
eventBus.register(externalPluginManager);
eventBus.register(overlayManager);
eventBus.register(drawManager);
eventBus.register(configManager);
eventBus.register(discordService);
if (!isOutdated)
{
// Initialize chat colors
chatMessageManager.get().loadColors();
eventBus.register(infoBoxManager.get());
eventBus.register(partyService.get());
eventBus.register(overlayRenderer.get());
eventBus.register(friendsChatManager.get());
eventBus.register(itemManager.get());
eventBus.register(menuManager.get());
eventBus.register(chatMessageManager.get());
eventBus.register(commandManager.get());
eventBus.register(lootManager.get());
eventBus.register(chatboxPanelManager.get());
eventBus.register(hooks.get());
// Add core overlays
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
overlayManager.add(worldMapOverlay.get());
@@ -405,12 +333,6 @@ public class RuneLite
// Start plugins
pluginManager.startPlugins();
// Register additional schedulers
if (this.client != null)
{
scheduler.registerObject(modelOutlineRenderer.get());
}
SplashScreen.stop();
clientUI.show();

View File

@@ -90,44 +90,19 @@ public class Hooks implements Callbacks
private static final GameTick GAME_TICK = new GameTick();
private static final BeforeRender BEFORE_RENDER = new BeforeRender();
private static final Injector injector = RuneLite.getInjector();
private static final Client client = injector.getInstance(Client.class);
public static final OverlayRenderer renderer = injector.getInstance(OverlayRenderer.class);
private static final OverlayManager overlayManager = injector.getInstance(OverlayManager.class);
@Inject
private EventBus eventBus;
@Inject
private DeferredEventBus deferredEventBus;
@Inject
private Scheduler scheduler;
@Inject
private InfoBoxManager infoBoxManager;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private MouseManager mouseManager;
@Inject
private KeyManager keyManager;
@Inject
private ClientThread clientThread;
@Inject
private DrawManager drawManager;
@Inject
private Notifier notifier;
@Inject
private ClientUI clientUi;
private final Client client;
private final OverlayRenderer renderer;
private final EventBus eventBus;
private final DeferredEventBus deferredEventBus;
private final Scheduler scheduler;
private final InfoBoxManager infoBoxManager;
private final ChatMessageManager chatMessageManager;
private final MouseManager mouseManager;
private final KeyManager keyManager;
private final ClientThread clientThread;
private final DrawManager drawManager;
private final Notifier notifier;
private final ClientUI clientUi;
private Dimension lastStretchedDimensions;
private VolatileImage stretchedImage;
@@ -162,6 +137,39 @@ public class Hooks implements Callbacks
return lastGraphics;
}
@Inject
private Hooks(
Client client,
OverlayRenderer renderer,
EventBus eventBus,
DeferredEventBus deferredEventBus,
Scheduler scheduler,
InfoBoxManager infoBoxManager,
ChatMessageManager chatMessageManager,
MouseManager mouseManager,
KeyManager keyManager,
ClientThread clientThread,
DrawManager drawManager,
Notifier notifier,
ClientUI clientUi
)
{
this.client = client;
this.renderer = renderer;
this.eventBus = eventBus;
this.deferredEventBus = deferredEventBus;
this.scheduler = scheduler;
this.infoBoxManager = infoBoxManager;
this.chatMessageManager = chatMessageManager;
this.mouseManager = mouseManager;
this.keyManager = keyManager;
this.clientThread = clientThread;
this.drawManager = drawManager;
this.notifier = notifier;
this.clientUi = clientUi;
eventBus.register(this);
}
@Override
public void post(Object event)
{

View File

@@ -50,6 +50,7 @@ import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.ui.JagexColors;
@@ -72,11 +73,14 @@ public class ChatMessageManager
private ChatMessageManager(
Client client,
ChatColorConfig chatColorConfig,
ClientThread clientThread)
ClientThread clientThread,
EventBus eventBus)
{
this.client = client;
this.chatColorConfig = chatColorConfig;
this.clientThread = clientThread;
eventBus.register(this);
loadColors();
}
@Subscribe
@@ -254,7 +258,7 @@ public class ChatMessageManager
/**
* Load all configured colors
*/
public void loadColors()
private void loadColors()
{
colorCache.clear();

View File

@@ -63,6 +63,7 @@ public class CommandManager
this.client = client;
this.eventBus = eventBus;
this.clientThread = clientThread;
eventBus.register(this);
}
public void register(ChatboxInputListener chatboxInputListener)

View File

@@ -27,7 +27,6 @@ package net.runelite.client.config;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
@@ -128,9 +127,10 @@ public class ConfigManager
private final Client client;
private final ConfigInvocationHandler handler = new ConfigInvocationHandler(this);
private final Properties properties = new Properties();
private final Map<String, String> pendingChanges = new HashMap<>();
private Properties properties = new Properties();
// null => we need to make a new profile
@Nullable
private String rsProfileKey;
@@ -225,35 +225,14 @@ public class ConfigManager
return;
}
handler.invalidate();
properties.clear();
Properties newProperties = new Properties();
for (ConfigEntry entry : configuration.getConfig())
{
log.debug("Loading configuration value from client {}: {}", entry.getKey(), entry.getValue());
String[] split = splitKey(entry.getKey());
if (split == null)
{
continue;
}
final String groupName = split[KEY_SPLITTER_GROUP];
final String profile = split[KEY_SPLITTER_PROFILE];
final String key = split[KEY_SPLITTER_KEY];
final String value = entry.getValue();
final String oldValue = (String) properties.setProperty(entry.getKey(), value);
ConfigChanged configChanged = new ConfigChanged();
configChanged.setGroup(groupName);
configChanged.setProfile(profile);
configChanged.setKey(key);
configChanged.setOldValue(oldValue);
configChanged.setNewValue(value);
eventBus.post(configChanged);
newProperties.setProperty(entry.getKey(), entry.getValue());
}
migrateConfig();
log.debug("Loading in config from server");
swapProperties(newProperties, false);
try
{
@@ -267,7 +246,64 @@ public class ConfigManager
}
}
private synchronized void syncPropertiesFromFile(File propertiesFile)
private void swapProperties(Properties newProperties, boolean saveToServer)
{
Set<Object> allKeys = new HashSet<>(newProperties.keySet());
Properties oldProperties;
synchronized (this)
{
handler.invalidate();
oldProperties = properties;
this.properties = newProperties;
}
updateRSProfile();
allKeys.addAll(oldProperties.keySet());
for (Object wholeKey : allKeys)
{
String[] split = splitKey((String) wholeKey);
if (split == null)
{
continue;
}
String groupName = split[KEY_SPLITTER_GROUP];
String profile = split[KEY_SPLITTER_PROFILE];
String key = split[KEY_SPLITTER_KEY];
String oldValue = (String) oldProperties.get(wholeKey);
String newValue = (String) newProperties.get(wholeKey);
if (Objects.equals(oldValue, newValue))
{
continue;
}
log.debug("Loading configuration value {}: {}", wholeKey, newValue);
ConfigChanged configChanged = new ConfigChanged();
configChanged.setGroup(groupName);
configChanged.setProfile(profile);
configChanged.setKey(key);
configChanged.setOldValue(oldValue);
configChanged.setNewValue(newValue);
eventBus.post(configChanged);
if (saveToServer)
{
synchronized (pendingChanges)
{
pendingChanges.put((String) wholeKey, newValue);
}
}
}
migrateConfig();
}
private void syncPropertiesFromFile(File propertiesFile)
{
final Properties properties = new Properties();
try (FileInputStream in = new FileInputStream(propertiesFile))
@@ -276,44 +312,12 @@ public class ConfigManager
}
catch (Exception e)
{
log.debug("Malformed properties, skipping update");
log.warn("Malformed properties, skipping update");
return;
}
final Map<String, String> copy = (Map) ImmutableMap.copyOf(this.properties);
copy.forEach((wholeKey, value) ->
{
if (!properties.containsKey(wholeKey))
{
String[] split = splitKey(wholeKey);
if (split == null)
{
return;
}
String groupName = split[KEY_SPLITTER_GROUP];
String profile = split[KEY_SPLITTER_PROFILE];
String key = split[KEY_SPLITTER_KEY];
unsetConfiguration(groupName, profile, key);
}
});
properties.forEach((wholeKey, objValue) ->
{
String[] split = splitKey((String) wholeKey);
if (split == null)
{
return;
}
String groupName = split[KEY_SPLITTER_GROUP];
String profile = split[KEY_SPLITTER_PROFILE];
String key = split[KEY_SPLITTER_KEY];
String value = String.valueOf(objValue);
setConfiguration(groupName, profile, key, value);
});
migrateConfig();
log.debug("Loading in config from disk for upload");
swapProperties(properties, true);
}
public Future<Void> importLocal()
@@ -343,12 +347,10 @@ public class ConfigManager
private synchronized void loadFromFile()
{
handler.invalidate();
properties.clear();
Properties newProperties = new Properties();
try (FileInputStream in = new FileInputStream(propertiesFile))
{
properties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
newProperties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
catch (FileNotFoundException ex)
{
@@ -359,38 +361,8 @@ public class ConfigManager
log.warn("Unable to load settings", ex);
}
try
{
Map<String, String> copy = (Map) ImmutableMap.copyOf(properties);
copy.forEach((wholeKey, value) ->
{
String[] split = splitKey(wholeKey);
if (split == null)
{
log.debug("Properties key malformed!: {}", wholeKey);
properties.remove(wholeKey);
return;
}
String groupName = split[KEY_SPLITTER_GROUP];
String profile = split[KEY_SPLITTER_PROFILE];
String key = split[KEY_SPLITTER_KEY];
ConfigChanged configChanged = new ConfigChanged();
configChanged.setGroup(groupName);
configChanged.setProfile(profile);
configChanged.setKey(key);
configChanged.setOldValue(null);
configChanged.setNewValue(value);
eventBus.post(configChanged);
});
}
catch (Exception ex)
{
log.warn("Error posting config events", ex);
}
migrateConfig();
log.debug("Loading in config from disk");
swapProperties(newProperties, false);
}
private void saveToFile(final File propertiesFile) throws IOException
@@ -519,7 +491,11 @@ public class ConfigManager
assert !key.startsWith(RSPROFILE_GROUP + ".");
String wholeKey = getWholeKey(groupName, profile, key);
String oldValue = (String) properties.setProperty(wholeKey, value);
String oldValue;
synchronized (this)
{
oldValue = (String) properties.setProperty(wholeKey, value);
}
if (Objects.equals(oldValue, value))
{
@@ -599,7 +575,11 @@ public class ConfigManager
{
assert !key.startsWith(RSPROFILE_GROUP + ".");
String wholeKey = getWholeKey(groupName, profile, key);
String oldValue = (String) properties.remove(wholeKey);
String oldValue;
synchronized (this)
{
oldValue = (String) properties.remove(wholeKey);
}
if (oldValue == null)
{
@@ -768,7 +748,7 @@ public class ConfigManager
{
return Boolean.parseBoolean(str);
}
if (type == int.class)
if (type == int.class || type == Integer.class)
{
return Integer.parseInt(str);
}
@@ -977,6 +957,7 @@ public class ConfigManager
salt = new byte[15];
new SecureRandom()
.nextBytes(salt);
log.info("creating new salt as there is no existing one {}", Base64.getUrlEncoder().encodeToString(salt));
setConfiguration(RSPROFILE_GROUP, RSPROFILE_LOGIN_SALT, salt);
}
@@ -1013,7 +994,7 @@ public class ConfigManager
String keyStr = RSPROFILE_GROUP + "." + Base64.getUrlEncoder().encodeToString(key);
if (!keys.contains(keyStr))
{
log.info("creating new profile {} for user {}", key, username);
log.info("creating new profile {} for user {} ({}) salt {}", keyStr, username, type, Base64.getUrlEncoder().encodeToString(salt));
setConfiguration(RSPROFILE_GROUP, keyStr, RSPROFILE_LOGIN_HASH, loginHash);
setConfiguration(RSPROFILE_GROUP, keyStr, RSPROFILE_TYPE, type);
@@ -1071,6 +1052,7 @@ public class ConfigManager
/**
* Split a config key into (group, profile, key)
*
* @param key in form group.(rsprofile.profile.)?key
* @return an array of {group, profile, key}
*/

View File

@@ -117,7 +117,7 @@ public enum AgilityShortcut
BRIMHAVEN_DUNGEON_MEDIUM_PIPE(34, "Pipe Squeeze", null, new WorldPoint(2698, 9501, 0), PIPE_21727),
KOUREND_CATACOMBS_NORTH_EAST_CREVICE_NORTH(34, "Crevice", new WorldPoint(1715, 10057, 0), CRACK_28892),
KOUREND_CATACOMBS_NORTH_EAST_CREVICE_SOUTH(34, "Crevice", new WorldPoint(1705, 10077, 0), CRACK_28892),
CATHERBY_OBELISK_GRAPPLE(36, "Grapple Rock", new WorldPoint(2841, 3434, 0), CROSSBOW_TREE_17062),
CATHERBY_OBELISK_GRAPPLE(36, "Grapple Rock", null, CROSSBOW_TREE_17062),
GNOME_STRONGHOLD_ROCKS(37, "Rocks", new WorldPoint(2485, 3515, 0), ROCKS_16534, ROCKS_16535),
AL_KHARID_MINING_PITCLIFF_SCRAMBLE(38, "Rocks", new WorldPoint(3305, 3315, 0), ROCKS_16549, ROCKS_16550),
YANILLE_WALL_GRAPPLE(39, "Grapple Wall", new WorldPoint(2552, 3072, 0), WALL_17047),

View File

@@ -45,6 +45,7 @@ import net.runelite.api.IndexedSprite;
import net.runelite.api.SpriteID;
import net.runelite.api.events.FriendsChatChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text;
@@ -93,10 +94,11 @@ public class FriendChatManager
private int offset;
@Inject
private FriendChatManager(Client client, SpriteManager spriteManager)
private FriendChatManager(Client client, SpriteManager spriteManager, EventBus eventBus)
{
this.client = client;
this.spriteManager = spriteManager;
eventBus.register(this);
}
public boolean isMember(String name)

View File

@@ -55,6 +55,7 @@ import net.runelite.api.SpritePixels;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.PostItemComposition;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.util.AsyncBufferedImage;
import net.runelite.http.api.item.ItemClient;
@@ -169,7 +170,7 @@ public class ItemManager
@Inject
public ItemManager(Client client, ScheduledExecutorService scheduledExecutorService, ClientThread clientThread,
OkHttpClient okHttpClient)
OkHttpClient okHttpClient, EventBus eventBus)
{
this.client = client;
this.clientThread = clientThread;
@@ -213,6 +214,8 @@ public class ItemManager
return loadItemOutline(key.itemId, key.itemQuantity, key.outlineColor);
}
});
eventBus.register(this);
}
private void loadPrices()

View File

@@ -281,6 +281,14 @@ public enum ItemMapping
ITEM_GRACEFUL_BOOTS(MARK_OF_GRACE, true, 32L, GRACEFUL_BOOTS),
ITEM_GRACEFUL_CAPE(MARK_OF_GRACE, true, 32L, GRACEFUL_CAPE),
// Trailblazer Graceful Ornament Kit
ITEM_TRAILBLAZER_GRACEFUL_HOOD(TRAILBLAZER_GRACEFUL_ORNAMENT_KIT, GRACEFUL_HOOD_25069),
ITEM_TRAILBLAZER_GRACEFUL_TOP(TRAILBLAZER_GRACEFUL_ORNAMENT_KIT, GRACEFUL_TOP_25075),
ITEM_TRAILBLAZER_GRACEFUL_LEGS(TRAILBLAZER_GRACEFUL_ORNAMENT_KIT, GRACEFUL_LEGS_25078),
ITEM_TRAILBLAZER_GRACEFUL_GLOVES(TRAILBLAZER_GRACEFUL_ORNAMENT_KIT, GRACEFUL_GLOVES_25081),
ITEM_TRAILBLAZER_GRACEFUL_BOOTS(TRAILBLAZER_GRACEFUL_ORNAMENT_KIT, GRACEFUL_BOOTS_25084),
ITEM_TRAILBLAZER_GRACEFUL_CAPE(TRAILBLAZER_GRACEFUL_ORNAMENT_KIT, GRACEFUL_CAPE_25072),
// 10 golden nuggets = 100 soft clay
ITEM_GOLDEN_NUGGET(SOFT_CLAY, true, 10L, GOLDEN_NUGGET),
ITEM_PROSPECTOR_HELMET(GOLDEN_NUGGET, true, 32L, PROSPECTOR_HELMET),

View File

@@ -84,6 +84,7 @@ public class LootManager
{
this.eventBus = eventBus;
this.client = client;
eventBus.register(this);
}
@Subscribe

View File

@@ -79,6 +79,8 @@ public class ChatboxPanelManager
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
this.chatboxTextInputProvider = chatboxTextInputProvider;
eventBus.register(this);
}
public void close()

View File

@@ -24,7 +24,6 @@
*/
package net.runelite.client.menus;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
@@ -65,11 +64,11 @@ public class MenuManager
private final Multimap<Integer, WidgetMenuOption> managedMenuOptions = LinkedHashMultimap.create();
@Inject
@VisibleForTesting
MenuManager(Client client, EventBus eventBus)
private MenuManager(Client client, EventBus eventBus)
{
this.client = client;
this.eventBus = eventBus;
eventBus.register(this);
}
/**

View File

@@ -37,8 +37,8 @@ import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
import net.runelite.api.Player;
import net.runelite.api.SpriteID;
import net.runelite.client.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.WidgetClosed;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
@@ -49,6 +49,7 @@ import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.plugins.Plugin;
@@ -159,8 +160,6 @@ public class BarrowsPlugin extends Plugin
if (event.getGameState() == GameState.LOADING)
{
wasInCrypt = isInCrypt();
// on region changes the tiles get set to null
puzzleAnswer = null;
}
else if (event.getGameState() == GameState.LOGGED_IN)
{
@@ -221,6 +220,15 @@ public class BarrowsPlugin extends Plugin
}
}
@Subscribe
public void onWidgetClosed(WidgetClosed widgetClosed)
{
if (widgetClosed.getGroupId() == WidgetID.BARROWS_PUZZLE_GROUP_ID)
{
puzzleAnswer = null;
}
}
private void startPrayerDrainTimer()
{
if (config.showPrayerDrainTimer())

View File

@@ -146,7 +146,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
new SkillChallengeClue("Steal from a chest in Ardougne Castle."),
new SkillChallengeClue("Craft a green dragonhide body.", xOfItem(ItemID.GREEN_DRAGON_LEATHER, 3), item(ItemID.NEEDLE), item(ItemID.THREAD)),
new SkillChallengeClue("String a yew longbow.", item(ItemID.YEW_LONGBOW_U), item(ItemID.BOW_STRING)),
new SkillChallengeClue("Kill a Dust Devil.", "slay a dust devil.", true, any("Facemask or Slayer Helmet", item(ItemID.FACEMASK), item(ItemID.SLAYER_HELMET), item(ItemID. SLAYER_HELMET_I), item(ItemID. BLACK_SLAYER_HELMET), item(ItemID. BLACK_SLAYER_HELMET_I), item(ItemID. PURPLE_SLAYER_HELMET), item(ItemID. PURPLE_SLAYER_HELMET_I), item(ItemID. RED_SLAYER_HELMET), item(ItemID. RED_SLAYER_HELMET_I), item(ItemID.GREEN_SLAYER_HELMET), item(ItemID. GREEN_SLAYER_HELMET_I), item(ItemID. TURQUOISE_SLAYER_HELMET), item(ItemID. TURQUOISE_SLAYER_HELMET_I), item(ItemID. HYDRA_SLAYER_HELMET), item(ItemID. HYDRA_SLAYER_HELMET_I))),
new SkillChallengeClue("Kill a Dust Devil.", "slay a dust devil.", true, any("Facemask or Slayer Helmet", item(ItemID.FACEMASK), item(ItemID.SLAYER_HELMET), item(ItemID. SLAYER_HELMET_I), item(ItemID. BLACK_SLAYER_HELMET), item(ItemID. BLACK_SLAYER_HELMET_I), item(ItemID. PURPLE_SLAYER_HELMET), item(ItemID. PURPLE_SLAYER_HELMET_I), item(ItemID. RED_SLAYER_HELMET), item(ItemID. RED_SLAYER_HELMET_I), item(ItemID.GREEN_SLAYER_HELMET), item(ItemID. GREEN_SLAYER_HELMET_I), item(ItemID. TURQUOISE_SLAYER_HELMET), item(ItemID. TURQUOISE_SLAYER_HELMET_I), item(ItemID. HYDRA_SLAYER_HELMET), item(ItemID. HYDRA_SLAYER_HELMET_I), item(ItemID.TWISTED_SLAYER_HELMET), item(ItemID.TWISTED_SLAYER_HELMET_I))),
new SkillChallengeClue("Catch a black warlock.", item(ItemID.BUTTERFLY_JAR), any("Butterfly Net", item(ItemID.BUTTERFLY_NET), item(ItemID.MAGIC_BUTTERFLY_NET))),
new SkillChallengeClue("Catch a red chinchompa.", item(ItemID.BOX_TRAP)),
new SkillChallengeClue("Mine a mithril ore.", ANY_PICKAXE),

View File

@@ -96,7 +96,7 @@ public enum HotColdLocation
FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2084, 3916, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village.", ANCIENT_WIZARDS),
FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village.", ANCIENT_WIZARDS),
ICE_MOUNTAIN(new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"),
ISLE_OF_SOULS_MINE(new WorldPoint(2189, 2794, 0), KANDARIN, "Isle of Souls Mine, south of the Soul Wars lobby"),
ISLE_OF_SOULS_MINE(new WorldPoint(2189, 2794, 0), KANDARIN, "Isle of Souls Mine, south of the Soul Wars lobby", BRASSICAN_MAGE),
KANDARIN_SINCLAR_MANSION(new WorldPoint(2730, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut.", BRASSICAN_MAGE),
KANDARIN_CATHERBY(new WorldPoint(2774, 3436, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation.", BRASSICAN_MAGE),
KANDARIN_GRAND_TREE(new WorldPoint(2448, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure.", BRASSICAN_MAGE),

View File

@@ -174,9 +174,16 @@ public class CookingPlugin extends Plugin
if (message.startsWith("You successfully cook")
|| message.startsWith("You successfully bake")
|| message.startsWith("You successfully fry")
|| message.startsWith("You manage to cook")
|| message.startsWith("You roast a")
|| message.startsWith("You spit-roast")
|| message.startsWith("You cook")
|| message.startsWith("Eventually the Jubbly")
|| message.startsWith("You half-cook")
|| message.startsWith("The undead meat is now cooked")
|| message.startsWith("The undead chicken is now cooked")
|| message.startsWith("You successfully scramble")
|| message.startsWith("You dry a piece of meat"))
{
if (session == null)
@@ -189,6 +196,8 @@ public class CookingPlugin extends Plugin
}
else if (message.startsWith("You accidentally burn")
|| message.startsWith("You burn")
|| message.startsWith("Unfortunately the Jubbly")
|| message.startsWith("You accidentally spoil"))
{
if (session == null)

View File

@@ -43,6 +43,7 @@ import net.runelite.api.events.HitsplatApplied;
import net.runelite.api.events.InteractingChanged;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
@@ -191,12 +192,6 @@ public class CorpPlugin extends Plugin
return;
}
int myDamage = client.getVar(Varbits.CORP_DAMAGE);
// sometimes hitsplats are applied after the damage counter has been reset
if (myDamage > 0)
{
yourDamage = myDamage;
}
totalDamage += hitsplatApplied.getHitsplat().getAmount();
}
@@ -213,4 +208,18 @@ public class CorpPlugin extends Plugin
players.add(source);
}
@Subscribe
public void onVarbitChanged(VarbitChanged varbitChanged)
{
if (corp != null)
{
int myDamage = client.getVar(Varbits.CORP_DAMAGE);
// avoid resetting our counter when the client's is reset
if (myDamage > 0)
{
yourDamage = myDamage;
}
}
}
}

View File

@@ -75,10 +75,19 @@ public class CrowdsourcingCooking
// Message prefixes taken from CookingPlugin
if (message.startsWith("You successfully cook")
|| message.startsWith("You successfully bake")
|| message.startsWith("You successfully fry")
|| message.startsWith("You manage to cook")
|| message.startsWith("You roast a")
|| message.startsWith("You spit-roast")
|| message.startsWith("You cook")
|| message.startsWith("You burn")
|| message.startsWith("Eventually the Jubbly")
|| message.startsWith("Unfortunately the Jubbly")
|| message.startsWith("You accidentally burn")
|| message.startsWith("You half-cook")
|| message.startsWith("The undead meat is now cooked")
|| message.startsWith("The undead chicken is now cooked")
|| message.startsWith("You successfully scramble")
|| message.startsWith("You accidentally spoil"))
{
boolean inHosidiusKitchen = false;

View File

@@ -55,25 +55,85 @@ public class CrowdsourcingWoodcutting
private static final String INVENTORY_FULL_MESSAGE = "Your inventory is too full to hold any more logs.";
private static final String NEST_MESSAGE = "A bird's nest falls out of the tree";
private static final Set<Integer> TREE_OBJECTS = new ImmutableSet.Builder<Integer>().
add(ObjectID.OAK).
add(ObjectID.OAK_10820).
add(ObjectID.OAK_8467).
add(ObjectID.OAK_9734).
add(ObjectID.YEW).
add(ObjectID.YEW_TREE_8513).
add(ObjectID.TREE).
add(ObjectID.TREE_1277).
add(ObjectID.TREE_1278).
add(ObjectID.TREE_1279).
add(ObjectID.TREE_1280).
add(ObjectID.DEAD_TREE).
add(ObjectID.DEAD_TREE_1283).
add(ObjectID.DEAD_TREE_1284).
add(ObjectID.DEAD_TREE_1285).
add(ObjectID.DEAD_TREE_1286).
add(ObjectID.DEAD_TREE_1289).
add(ObjectID.DEAD_TREE_1290).
add(ObjectID.DEAD_TREE_1291).
add(ObjectID.EVERGREEN).
add(ObjectID.EVERGREEN_1319).
add(ObjectID.TREE_1330).
add(ObjectID.TREE_1331).
add(ObjectID.TREE_1332).
add(ObjectID.DEAD_TREE_1365).
add(ObjectID.DEAD_TREE_1383).
add(ObjectID.DEAD_TREE_1384).
add(ObjectID.EVERGREEN_2091).
add(ObjectID.EVERGREEN_2092).
add(ObjectID.TREE_2409).
add(ObjectID.TREE_3879).
add(ObjectID.TREE_3881).
add(ObjectID.TREE_3882).
add(ObjectID.TREE_3883).
add(ObjectID.DEAD_TREE_5902).
add(ObjectID.DEAD_TREE_5903).
add(ObjectID.DEAD_TREE_5904).
add(ObjectID.TREE_9730).
add(ObjectID.TREE_9731).
add(ObjectID.TREE_9732).
add(ObjectID.TREE_9733).
add(ObjectID.TREE_10041).
add(ObjectID.TREE_14308).
add(ObjectID.TREE_14309).
add(ObjectID.TREE_16264).
add(ObjectID.TREE_16265).
add(ObjectID.EVERGREEN_27060).
add(ObjectID.BURNT_TREE).
add(ObjectID.BURNT_TREE_30854).
add(ObjectID.MATURE_JUNIPER_TREE).
add(ObjectID.WILLOW).
add(ObjectID.WILLOW_10829).
add(ObjectID.WILLOW_10831).
add(ObjectID.WILLOW_10833).
add(ObjectID.WILLOW_TREE_8488).
add(ObjectID.SCRAPEY_TREE).
add(ObjectID.JUNGLE_TREE_15951).
add(ObjectID.JUNGLE_TREE_15954).
add(ObjectID.JUNGLE_TREE_15948).
add(ObjectID.MAPLE_TREE_10832).
add(ObjectID.MAPLE_TREE_4674).
add(ObjectID.MAPLE_TREE_8444).
add(ObjectID.MAHOGANY).
add(ObjectID.TEAK).
add(ObjectID.TEAK_15062).
add(ObjectID.MAGIC_TREE_10834).
add(ObjectID.MAGIC_TREE_8409).
add(ObjectID.HOLLOW_TREE_10821).
add(ObjectID.HOLLOW_TREE_10830).
add(ObjectID.ACHEY_TREE).
add(ObjectID.REDWOOD).
add(ObjectID.REDWOOD_29670).
add(ObjectID.BRUMA_ROOTS).
add(ObjectID.ARCTIC_PINE).
add(ObjectID.SULLIUSCEP).
build();
private static final Map<Integer, Integer> AXE_ANIMS = new ImmutableMap.Builder<Integer, Integer>().
@@ -103,8 +163,13 @@ public class CrowdsourcingWoodcutting
add("You get some mahogany logs and give them to Carpenter Kjallak.").
add("You get some yew logs.").
add("You get some magic logs.").
add("You get some redwood logs.").
add("You get some scrapey tree logs.").
add("You get some bark.").
add("You get a bruma root.").
add("You get an arctic pine log").
add("You get some juniper logs.").
add("You get some mushrooms.").
build();
@Inject

View File

@@ -33,8 +33,10 @@ import javax.inject.Inject;
import javax.swing.JButton;
import javax.swing.JPanel;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.MenuAction;
import net.runelite.client.Notifier;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.overlay.OverlayMenuEntry;
@@ -45,6 +47,7 @@ import net.runelite.client.util.ImageUtil;
class DevToolsPanel extends PluginPanel
{
private final Client client;
private final ClientThread clientThread;
private final Notifier notifier;
private final DevToolsPlugin plugin;
@@ -58,6 +61,7 @@ class DevToolsPanel extends PluginPanel
@Inject
private DevToolsPanel(
Client client,
ClientThread clientThread,
DevToolsPlugin plugin,
WidgetInspector widgetInspector,
VarInspector varInspector,
@@ -69,6 +73,7 @@ class DevToolsPanel extends PluginPanel
{
super();
this.client = client;
this.clientThread = clientThread;
this.plugin = plugin;
this.widgetInspector = widgetInspector;
this.varInspector = varInspector;
@@ -205,6 +210,10 @@ class DevToolsPanel extends PluginPanel
}
});
final JButton disconnectBtn = new JButton("Disconnect");
disconnectBtn.addActionListener(e -> clientThread.invoke(() -> client.setGameState(GameState.CONNECTION_LOST)));
container.add(disconnectBtn);
return container;
}
}

View File

@@ -287,7 +287,8 @@ enum DiscordGameEventType
MG_HALLOWED_SEPULCHRE("Hallowed Sepulchre", DiscordAreaType.MINIGAMES, 8797, 9051, 9052, 9053, 9054, 9309, 9563, 9565, 9821, 10074, 10075, 10077),
MG_INFERNO("The Inferno", DiscordAreaType.MINIGAMES, 9043),
MG_KELDAGRIM_RAT_PITS("Keldagrim Rat Pits", DiscordAreaType.MINIGAMES, 7753),
MG_LAST_MAN_STANDING("Last Man Standing", DiscordAreaType.MINIGAMES, 13660, 13659, 13658, 13916, 13915, 13914),
MG_LAST_MAN_STANDING_DESERTED_ISLAND("LMS - Deserted Island", DiscordAreaType.MINIGAMES, 13658, 13659, 13660, 13914, 13915, 13916),
MG_LAST_MAN_STANDING_WILD_VARROCK("LMS - Wild Varrock", DiscordAreaType.MINIGAMES, 13918, 13919, 13920, 14174, 14175, 14176, 14430, 14431, 14432),
MG_MAGE_TRAINING_ARENA("Mage Training Arena", DiscordAreaType.MINIGAMES, 13462, 13463),
MG_NIGHTMARE_ZONE("Nightmare Zone", DiscordAreaType.MINIGAMES, 9033),
MG_PEST_CONTROL("Pest Control", DiscordAreaType.MINIGAMES, 10536),
@@ -385,7 +386,7 @@ enum DiscordGameEventType
REGION_MCGRUBORS_WOOD("McGrubor's Wood", DiscordAreaType.REGIONS, 10550),
REGION_MIME_STAGE("Mime's Stage", DiscordAreaType.REGIONS, 8010),
REGION_MIND_ALTAR("Mind Altar", DiscordAreaType.REGIONS, 11083),
REGION_MISTHALIN("Misthalin", DiscordAreaType.REGIONS, 12594, 12595),
REGION_MISTHALIN("Misthalin", DiscordAreaType.REGIONS, 12594, 12595, 12851),
REGION_MOLCH("Molch", DiscordAreaType.REGIONS, 5177),
REGION_MOLCH_ISLAND("Molch Island", DiscordAreaType.REGIONS, 5432),
REGION_MORYTANIA("Morytania", DiscordAreaType.REGIONS, 13619, 13620, 13621, 13622, 13876, 13877, 13879, 14133, 14134, 14389, 14390, 14391, 14645, 14647),

View File

@@ -172,10 +172,9 @@ public class DiscordPlugin extends Plugin
resetState();
checkForGameStateUpdate();
}
checkForAreaUpdate();
break;
}
checkForAreaUpdate();
}
@Subscribe

View File

@@ -45,8 +45,34 @@ enum ItemIdentification
LANTADYME_SEED(Type.SEED, "Lanta", "L", ItemID.LANTADYME_SEED),
DWARF_WEED_SEED(Type.SEED, "Dwarf", "D", ItemID.DWARF_WEED_SEED),
TORSTOL_SEED(Type.SEED, "Torstol", "TOR", ItemID.TORSTOL_SEED),
POISON_IVY_SEED(Type.SEED, "Ivy", "I", ItemID.POISON_IVY_SEED),
WHITEBERRY_SEED(Type.SEED, "White", "W", ItemID.WHITEBERRY_SEED),
SEAWEED_SPORE(Type.SEED, "Seaweed", "SW", ItemID.SEAWEED_SPORE),
HESPORI_SEED(Type.SEED, "Hespori", "HES", ItemID.HESPORI_SEED),
KRONOS_SEED(Type.SEED, "Kronos", "KRO", ItemID.KRONOS_SEED),
IASOR_SEED(Type.SEED, "Iasor", "IA", ItemID.IASOR_SEED),
ATTAS_SEED(Type.SEED, "Attas", "AT", ItemID.ATTAS_SEED),
CELASTRUS_SEED(Type.SEED, "Celas", "CEL", ItemID.CELASTRUS_SEED),
SPIRIT_SEED(Type.SEED, "Spirit", "SPI", ItemID.SPIRIT_SEED),
CALQUAT_SEED(Type.SEED, "Calquat", "CAL", ItemID.CALQUAT_TREE_SEED),
ACORN(Type.SEED, "Oak", "OAK", ItemID.ACORN),
WILLOW_SEED(Type.SEED, "Willow", "WIL", ItemID.WILLOW_SEED),
MAPLE_SEED(Type.SEED, "Maple", "MAP", ItemID.MAPLE_SEED),
YEW_SEED(Type.SEED, "Yew", "YEW", ItemID.YEW_SEED),
MAGIC_SEED(Type.SEED, "Magic", "MAG", ItemID.MAGIC_SEED),
REDWOOD_SEED(Type.SEED, "Red", "RED", ItemID.REDWOOD_TREE_SEED),
TEAK_SEED(Type.SEED, "Teak", "TEAK", ItemID.TEAK_SEED),
MAHOGANY_SEED(Type.SEED, "Mahog", "MAH", ItemID.MAHOGANY_SEED),
CRYSTAL_ACORN(Type.SEED, "Crystal", "CRY", ItemID.CRYSTAL_ACORN),
//Sacks
SACK(Type.SACK, "Empty", "EMP", ItemID.EMPTY_SACK),
CABBAGE_SACK(Type.SACK, "Cabbage", "CAB", ItemID.CABBAGES1, ItemID.CABBAGES2, ItemID.CABBAGES3, ItemID.CABBAGES4, ItemID.CABBAGES5, ItemID.CABBAGES6, ItemID.CABBAGES7, ItemID.CABBAGES8, ItemID.CABBAGES9, ItemID.CABBAGES10),
ONION_SACK(Type.SACK, "Onion", "ONI", ItemID.ONIONS1, ItemID.ONIONS2, ItemID.ONIONS3, ItemID.ONIONS4, ItemID.ONIONS5, ItemID.ONIONS6, ItemID.ONIONS7, ItemID.ONIONS8, ItemID.ONIONS9, ItemID.ONIONS10),
POTATO_SACK(Type.SACK, "Potato", "POT", ItemID.POTATOES1, ItemID.POTATOES2, ItemID.POTATOES3, ItemID.POTATOES4, ItemID.POTATOES5, ItemID.POTATOES6, ItemID.POTATOES7, ItemID.POTATOES8, ItemID.POTATOES9, ItemID.POTATOES10),
//Herbs
GUAM(Type.HERB, "Guam", "G", ItemID.GUAM_LEAF, ItemID.GRIMY_GUAM_LEAF),
@@ -69,6 +95,48 @@ enum ItemIdentification
SITO_FOIL(Type.HERB, "Sito", "SF", ItemID.SITO_FOIL, ItemID.GRIMY_SITO_FOIL),
SNAKE_WEED(Type.HERB, "Snake", "SW", ItemID.SNAKE_WEED, ItemID.GRIMY_SNAKE_WEED),
VOLENCIA_MOSS(Type.HERB, "Volenc", "V", ItemID.VOLENCIA_MOSS, ItemID.GRIMY_VOLENCIA_MOSS),
//Logs
RED_LOGS(Type.LOGS, "Red", "RED", ItemID.RED_LOGS),
GREEN_LOGS(Type.LOGS, "Green", "GRE", ItemID.GREEN_LOGS),
BLUE_LOGS(Type.LOGS, "Blue", "BLU", ItemID.BLUE_LOGS),
WHITE_LOGS(Type.LOGS, "White", "WHI", ItemID.WHITE_LOGS),
PURPLE_LOGS(Type.LOGS, "Purple", "PUR", ItemID.PURPLE_LOGS),
SCRAPEY_TREE_LOGS(Type.LOGS, "Scrapey", "SCRAP", ItemID.SCRAPEY_TREE_LOGS),
LOG(Type.LOGS, "Log", "LOG", ItemID.LOGS),
ACHEY_TREE_LOG(Type.LOGS, "Achey", "ACH", ItemID.ACHEY_TREE_LOGS),
OAK_LOG(Type.LOGS, "Oak", "OAK", ItemID.OAK_LOGS),
WILLOW_LOG(Type.LOGS, "Willow", "WIL", ItemID.WILLOW_LOGS),
TEAK_LOG(Type.LOGS, "Teak", "TEAK", ItemID.TEAK_LOGS),
JUNIPER_LOG(Type.LOGS, "Juniper", "JUN", ItemID.JUNIPER_LOGS),
MAPLE_LOG(Type.LOGS, "Maple", "MAP", ItemID.MAPLE_LOGS),
MAHOGANY_LOG(Type.LOGS, "Mahog", "MAH", ItemID.MAHOGANY_LOGS),
ARCTIC_PINE_LOG(Type.LOGS, "Arctic", "ARC", ItemID.ARCTIC_PINE_LOGS),
YEW_LOG(Type.LOGS, "Yew", "YEW", ItemID.YEW_LOGS),
BLISTERWOOD_LOG(Type.LOGS, "Blister", "BLI", ItemID.BLISTERWOOD_LOGS),
MAGIC_LOG(Type.LOGS, "Magic", "MAG", ItemID.MAGIC_LOGS),
REDWOOD_LOG(Type.LOGS, "Red", "RED", ItemID.REDWOOD_LOGS),
PYRE_LOGS(Type.LOGS, "Pyre", "P", ItemID.PYRE_LOGS),
ARCTIC_PYRE_LOGS(Type.LOGS, "Art P", "AP", ItemID.ARCTIC_PYRE_LOGS),
OAK_PYRE_LOGS(Type.LOGS, "Oak P", "OAKP", ItemID.OAK_PYRE_LOGS),
WILLOW_PYRE_LOGS(Type.LOGS, "Wil P", "WILP", ItemID.WILLOW_PYRE_LOGS),
TEAK_PYRE_LOGS(Type.LOGS, "Teak P", "TEAKP", ItemID.TEAK_PYRE_LOGS),
MAPLE_PYRE_LOGS(Type.LOGS, "Map P", "MAPP", ItemID.MAPLE_PYRE_LOGS),
MAHOGANY_PYRE_LOGS(Type.LOGS, "Mah P", "MAHP", ItemID.MAHOGANY_PYRE_LOGS),
YEW_PYRE_LOGS(Type.LOGS, "Yew P", "YEWP", ItemID.YEW_PYRE_LOGS),
MAGIC_PYRE_LOGS(Type.LOGS, "Mag P", "MAGP", ItemID.MAGIC_PYRE_LOGS),
REDWOOD_PYRE_LOGS(Type.LOGS, "Red P", "REDP", ItemID.REDWOOD_PYRE_LOGS),
//Planks
PLANK(Type.PLANK, "Plank", "PLANK", ItemID.PLANK),
OAK_PLANK(Type.PLANK, "Oak", "OAK", ItemID.OAK_PLANK),
TEAK_PLANK(Type.PLANK, "Teak", "TEAK", ItemID.TEAK_PLANK),
MAHOGANY_PLANK(Type.PLANK, "Mahog", "MAH", ItemID.MAHOGANY_PLANK),
WAXWOOD_PLANK(Type.PLANK, "Wax", "WAX", ItemID.WAXWOOD_PLANK),
MALLIGNUM_ROOT_PLANK(Type.PLANK, "Mallig", "MALL", ItemID.MALLIGNUM_ROOT_PLANK),
//Saplings
OAK_SAPLING(Type.SAPLING, "Oak", "OAK", ItemID.OAK_SAPLING, ItemID.OAK_SEEDLING, ItemID.OAK_SEEDLING_W),
@@ -94,6 +162,11 @@ enum ItemIdentification
CALQUAT_SAPLING(Type.SAPLING, "Calquat", "CALQ", ItemID.CALQUAT_SAPLING, ItemID.CALQUAT_SEEDLING, ItemID.CALQUAT_SEEDLING_W),
CELASTRUS_SAPLING(Type.SAPLING, "Celas", "CEL", ItemID.CELASTRUS_SAPLING, ItemID.CELASTRUS_SEEDLING, ItemID.CELASTRUS_SEEDLING_W),
//Compost
COMPOST(Type.COMPOST, "Compost", "COM", ItemID.COMPOST),
SUPERCOMPOST(Type.COMPOST, "Sup Com", "SCOM", ItemID.SUPERCOMPOST),
ULTRACOMPOST(Type.COMPOST, "Ult Com", "UCOM", ItemID.ULTRACOMPOST),
//Ores
COPPER_ORE(Type.ORE, "Copper", "COP", ItemID.COPPER_ORE),
TIN_ORE(Type.ORE, "Tin", "TIN", ItemID.TIN_ORE),
@@ -116,6 +189,16 @@ enum ItemIdentification
DAEYALT_ORE(Type.ORE, "Daeyalt", "DAE", ItemID.DAEYALT_ORE),
LUNAR_ORE(Type.ORE, "Lunar", "LUN", ItemID.LUNAR_ORE),
//Bars
BRONZE_BAR(Type.BAR, "Bronze", "BRO", ItemID.BRONZE_BAR),
IRON_BAR(Type.BAR, "Iron", "IRO", ItemID.IRON_BAR),
SILVER_BAR(Type.BAR, "Silver", "SIL", ItemID.SILVER_BAR),
STEEL_BAR(Type.BAR, "Steel", "STE", ItemID.STEEL_BAR),
GOLD_BAR(Type.BAR, "Gold", "GOL", ItemID.GOLD_BAR),
MITHRIL_BAR(Type.BAR, "Mithril", "MIT", ItemID.MITHRIL_BAR),
ADAMANTITE_BAR(Type.BAR, "Adaman", "ADA", ItemID.ADAMANTITE_BAR),
RUNITE_BAR(Type.BAR, "Runite", "RUN", ItemID.RUNITE_BAR),
//Gems
SAPPHIRE(Type.GEM, "Sapphir", "S", ItemID.UNCUT_SAPPHIRE, ItemID.SAPPHIRE),
EMERALD(Type.GEM, "Emerald", "E", ItemID.UNCUT_EMERALD, ItemID.EMERALD),
@@ -183,7 +266,7 @@ enum ItemIdentification
SERUM_207(Type.POTION, "Ser207", "S7", ItemID.SERUM_207_4, ItemID.SERUM_207_3, ItemID.SERUM_207_2, ItemID.SERUM_207_1),
SERUM_208(Type.POTION, "Ser208", "S8", ItemID.SERUM_208_4, ItemID.SERUM_208_3, ItemID.SERUM_208_2, ItemID.SERUM_208_1),
COMPOST(Type.POTION, "Compost", "Cp", ItemID.COMPOST_POTION4, ItemID.COMPOST_POTION3, ItemID.COMPOST_POTION2, ItemID.COMPOST_POTION1),
COMPOST_POTION(Type.POTION, "Compost", "COM", ItemID.COMPOST_POTION4, ItemID.COMPOST_POTION3, ItemID.COMPOST_POTION2, ItemID.COMPOST_POTION1),
AGILITY(Type.POTION, "Agility", "Ag", ItemID.AGILITY_POTION4, ItemID.AGILITY_POTION3, ItemID.AGILITY_POTION2, ItemID.AGILITY_POTION1),
FISHING(Type.POTION, "Fishing", "Fi", ItemID.FISHING_POTION4, ItemID.FISHING_POTION3, ItemID.FISHING_POTION2, ItemID.FISHING_POTION1),
@@ -227,15 +310,18 @@ enum ItemIdentification
ARDOUGNE_TELEPORT(Type.TABLET, "Ardoug", "ARD", ItemID.ARDOUGNE_TELEPORT),
WATCHTOWER_TELEPORT(Type.TABLET, "W.tow", "WT", ItemID.WATCHTOWER_TELEPORT),
TELEPORT_TO_HOUSE(Type.TABLET, "House", "POH", ItemID.TELEPORT_TO_HOUSE),
ENCHANT_SAPPHIRE_OR_OPAL(Type.TABLET, "E.Saph", "E SO", ItemID.ENCHANT_SAPPHIRE_OR_OPAL),
ENCHANT_EMERALD_OR_JADE(Type.TABLET, "E.Emer", "E EJ", ItemID.ENCHANT_EMERALD_OR_JADE),
ENCHANT_RUBY_OR_TOPAZ(Type.TABLET, "E.Ruby", "E RT", ItemID.ENCHANT_RUBY_OR_TOPAZ),
ENCHANT_DIAMOND(Type.TABLET, "E.Diam", "E DIA", ItemID.ENCHANT_DIAMOND),
ENCHANT_DRAGONSTONE(Type.TABLET, "E.Dstn", "E DS", ItemID.ENCHANT_DRAGONSTONE),
ENCHANT_ONYX(Type.TABLET, "E.Onyx", "E ONX", ItemID.ENCHANT_ONYX),
TELEKINETIC_GRAB(Type.TABLET, "T.grab", "T.GRB", ItemID.TELEKINETIC_GRAB),
BONES_TO_PEACHES(Type.TABLET, "Peach", "BtP", ItemID.BONES_TO_PEACHES_8015),
BONES_TO_BANANAS(Type.TABLET, "Banana", "BtB", ItemID.BONES_TO_BANANAS),
RIMMINGTON_TELEPORT(Type.TABLET, "Rimmi", "RIM", ItemID.RIMMINGTON_TELEPORT),
TAVERLEY_TELEPORT(Type.TABLET, "Taver", "TAV", ItemID.TAVERLEY_TELEPORT),
POLLNIVNEACH_TELEPORT(Type.TABLET, "Pollnv", "POL", ItemID.POLLNIVNEACH_TELEPORT),
@@ -245,6 +331,7 @@ enum ItemIdentification
TROLLHEIM_TELEPORT(Type.TABLET, "Trollh", "T.HM", ItemID.TROLLHEIM_TELEPORT),
PRIFDDINAS_TELEPORT(Type.TABLET, "Prifd", "PRIF", ItemID.PRIFDDINAS_TELEPORT),
HOSIDIUS_TELEPORT(Type.TABLET, "Hosid", "HOS", ItemID.HOSIDIUS_TELEPORT),
ANNAKARL_TELEPORT(Type.TABLET, "Annak", "GDZ", ItemID.ANNAKARL_TELEPORT),
CARRALLANGAR_TELEPORT(Type.TABLET, "Carra", "CAR", ItemID.CARRALLANGAR_TELEPORT),
DAREEYAK_TELEPORT(Type.TABLET, "Dareey", "DAR", ItemID.DAREEYAK_TELEPORT),
@@ -252,6 +339,7 @@ enum ItemIdentification
LASSAR_TELEPORT(Type.TABLET, "Lass", "LSR", ItemID.LASSAR_TELEPORT),
PADDEWWA_TELEPORT(Type.TABLET, "Paddew", "PDW", ItemID.PADDEWWA_TELEPORT),
SENNTISTEN_TELEPORT(Type.TABLET, "Sennt", "SNT", ItemID.SENNTISTEN_TELEPORT),
LUMBRIDGE_GRAVEYARD_TELEPORT(Type.TABLET, "L.Grave", "L.GRV", ItemID.LUMBRIDGE_GRAVEYARD_TELEPORT),
DRAYNOR_MANOR_TELEPORT(Type.TABLET, "D.Manor", "D.MNR", ItemID.DRAYNOR_MANOR_TELEPORT),
MIND_ALTAR_TELEPORT(Type.TABLET, "M.Altar", "M.ALT", ItemID.MIND_ALTAR_TELEPORT),
@@ -263,6 +351,16 @@ enum ItemIdentification
BARROWS_TELEPORT(Type.TABLET, "Barrow", "BAR", ItemID.BARROWS_TELEPORT),
APE_ATOLL_TELEPORT(Type.TABLET, "Atoll", "APE", ItemID.APE_ATOLL_TELEPORT),
BATTLEFRONT_TELEPORT(Type.TABLET, "B.Front", "BF", ItemID.BATTLEFRONT_TELEPORT),
MOONCLAN_TELEPORT(Type.TABLET, "Moon", "MOON", ItemID.MOONCLAN_TELEPORT),
OURANIA_TELEPORT(Type.TABLET, "Ourania", "ZMI", ItemID.OURANIA_TELEPORT),
WATERBIRTH_TELEPORT(Type.TABLET, "W.Birth", "WAT", ItemID.WATERBIRTH_TELEPORT),
BARBARIAN_TELEPORT(Type.TABLET, "Barb", "BARB", ItemID.BARBARIAN_TELEPORT),
KHAZARD_TELEPORT(Type.TABLET, "Khaz", "KHA", ItemID.KHAZARD_TELEPORT),
FISHING_GUILD_TELEPORT(Type.TABLET, "Fish G.", "FIS", ItemID.FISHING_GUILD_TELEPORT),
CATHERBY_TELEPORT(Type.TABLET, "Cathy", "CATH", ItemID.CATHERBY_TELEPORT),
ICE_PLATEAU(Type.TABLET, "Ice Pl.", "ICE", ItemID.ICE_PLATEAU_TELEPORT),
TARGET_TELEPORT(Type.TABLET, "Target", "TRG", ItemID.TARGET_TELEPORT),
VOLCANIC_MINE_TELEPORT(Type.TABLET, "V.Mine", "VM", ItemID.VOLCANIC_MINE_TELEPORT),
WILDERNESS_CRABS_TELEPORT(Type.TABLET, "W.Crab", "CRAB", ItemID.WILDERNESS_CRABS_TELEPORT);
@@ -305,9 +403,14 @@ enum ItemIdentification
enum Type
{
SEED,
SACK,
HERB,
LOGS,
PLANK,
SAPLING,
COMPOST,
ORE,
BAR,
GEM,
POTION,
IMPLING_JAR,

View File

@@ -73,6 +73,16 @@ public interface ItemIdentificationConfig extends Config
return true;
}
@ConfigItem(
keyName = "showSacks",
name = "Sacks",
description = "Show identification on Sacks"
)
default boolean showSacks()
{
return false;
}
@ConfigItem(
keyName = "showHerbs",
name = "Herbs",
@@ -84,6 +94,28 @@ public interface ItemIdentificationConfig extends Config
return false;
}
@ConfigItem(
keyName = "showLogs",
name = "Logs",
description = "Show identification on Logs",
section = identificationSection
)
default boolean showLogs()
{
return false;
}
@ConfigItem(
keyName = "showPlanks",
name = "Planks",
description = "Show identification on Planks",
section = identificationSection
)
default boolean showPlanks()
{
return false;
}
@ConfigItem(
keyName = "showSaplings",
name = "Saplings",
@@ -95,6 +127,17 @@ public interface ItemIdentificationConfig extends Config
return true;
}
@ConfigItem(
keyName = "showComposts",
name = "Composts",
description = "Show identification on Composts",
section = identificationSection
)
default boolean showComposts()
{
return false;
}
@ConfigItem(
keyName = "showOres",
name = "Ores",
@@ -106,6 +149,17 @@ public interface ItemIdentificationConfig extends Config
return false;
}
@ConfigItem(
keyName = "showBars",
name = "Bars",
description = "Show identification on Bars",
section = identificationSection
)
default boolean showBars()
{
return false;
}
@ConfigItem(
keyName = "showGems",
name = "Gems",

View File

@@ -71,24 +71,54 @@ class ItemIdentificationOverlay extends WidgetItemOverlay
return;
}
break;
case SACK:
if (!config.showSacks())
{
return;
}
break;
case HERB:
if (!config.showHerbs())
{
return;
}
break;
case LOGS:
if (!config.showLogs())
{
return;
}
break;
case PLANK:
if (!config.showPlanks())
{
return;
}
break;
case SAPLING:
if (!config.showSaplings())
{
return;
}
break;
case COMPOST:
if (!config.showComposts())
{
return;
}
break;
case ORE:
if (!config.showOres())
{
return;
}
break;
case BAR:
if (!config.showBars())
{
return;
}
break;
case GEM:
if (!config.showGems())
{

View File

@@ -162,12 +162,9 @@ public class KeyRemappingPlugin extends Plugin
{
case SCRIPT_EVENT_SET_CHATBOX_INPUT:
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
if (chatboxInput != null)
if (chatboxInput != null && !typing)
{
if (chatboxFocused() && !typing)
{
setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT);
}
setChatboxWidgetInput(chatboxInput, PRESS_ENTER_TO_CHAT);
}
break;
case SCRIPT_EVENT_BLOCK_CHAT_INPUT:

View File

@@ -202,7 +202,7 @@ public class LootTrackerPlugin extends Plugin
private static final Set<Integer> HALLOWED_SEPULCHRE_MAP_REGIONS = ImmutableSet.of(8797, 10077, 9308, 10074, 9050); // one map region per floor
// Last man standing map regions
private static final Set<Integer> LAST_MAN_STANDING_REGIONS = ImmutableSet.of(13658, 13659, 13914, 13915, 13916);
private static final Set<Integer> LAST_MAN_STANDING_REGIONS = ImmutableSet.of(13658, 13659, 13660, 13914, 13915, 13916, 13918, 13919, 13920, 14174, 14175, 14176, 14430, 14431, 14432);
private static final Pattern PICKPOCKET_REGEX = Pattern.compile("You pick (the )?(?<target>.+)'s? pocket.*");

View File

@@ -287,6 +287,17 @@ public interface MenuEntrySwapperConfig extends Config
return false;
}
@ConfigItem(
keyName = "swapBait",
name = "Bait",
description = "Swap Lure, Small Net with Bait on Fishing spot",
section = objectSection
)
default boolean swapBait()
{
return false;
}
@ConfigItem(
keyName = "swapHelp",
name = "Help",
@@ -342,6 +353,17 @@ public interface MenuEntrySwapperConfig extends Config
return false;
}
@ConfigItem(
keyName = "swapPortalNexus",
name = "Portal Nexus",
description = "Swap Teleport options with Teleport Menu on the Portal Nexus",
section = objectSection
)
default boolean swapPortalNexus()
{
return false;
}
@ConfigItem(
keyName = "swapPrivate",
name = "Private",
@@ -628,4 +650,15 @@ public interface MenuEntrySwapperConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "swapRowboatDive",
name = "Fossil Island Rowboat Dive",
description = "Swap Travel with Dive on the rowboat found on the small island north-east of Fossil Island",
section = objectSection
)
default boolean swapRowboatDive()
{
return false;
}
}

View File

@@ -238,6 +238,10 @@ public class MenuEntrySwapperPlugin extends Plugin
swap("big net", "harpoon", config::swapHarpoon);
swap("net", "harpoon", config::swapHarpoon);
swap("lure", "bait", config::swapBait);
swap("net", "bait", config::swapBait);
swap("small net", "bait", config::swapBait);
swap("enter", "portal", "home", () -> config.swapHomePortal() == HouseMode.HOME);
swap("enter", "portal", "build mode", () -> config.swapHomePortal() == HouseMode.BUILD_MODE);
swap("enter", "portal", "friend's house", () -> config.swapHomePortal() == HouseMode.FRIENDS_HOUSE);
@@ -304,6 +308,14 @@ public class MenuEntrySwapperPlugin extends Plugin
swap("teleport menu", "draynor village", config::swapJewelleryBox);
swap("teleport menu", "al kharid", config::swapJewelleryBox);
Arrays.asList(
"annakarl", "ape atoll dungeon", "ardougne", "barrows", "battlefront", "camelot", "carrallangar",
"catherby", "cemetery", "draynor manor", "falador", "fenkenstrain's castle", "fishing guild", "ghorrock",
"grand exchange", "great kourend", "harmony island", "kharyrll", "lumbridge", "lumbridge graveyard",
"lunar isle", "marim", "mind altar", "salve graveyard", "seers' village", "senntisten", "troll stronghold",
"varrock", "watchtower", "waterbirth island", "weiss", "west ardougne", "yanille"
).forEach(location -> swap(location, "portal nexus", "teleport menu", config::swapPortalNexus));
swap("shared", "private", config::swapPrivate);
swap("pick", "pick-lots", config::swapPick);
@@ -361,6 +373,8 @@ public class MenuEntrySwapperPlugin extends Plugin
swapTeleport("teleport to house", "outside");
swap("eat", "guzzle", config::swapRockCake);
swap("travel", "dive", config::swapRowboatDive);
}
public void swap(String option, String swappedOption, Supplier<Boolean> enabled)

View File

@@ -39,6 +39,7 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.GameState;
import static net.runelite.api.HintArrowType.WORLD_POSITION;
import net.runelite.api.MenuAction;
import static net.runelite.api.ObjectID.DEPLETED_VEIN_26665;
import static net.runelite.api.ObjectID.DEPLETED_VEIN_26666;
@@ -133,6 +134,7 @@ public class MiningPlugin extends Plugin
pickaxe = null;
overlayManager.remove(overlay);
overlayManager.remove(rocksOverlay);
respawns.forEach(respawn -> clearHintArrowAt(respawn.getWorldPoint()));
respawns.clear();
}
@@ -200,7 +202,7 @@ public class MiningPlugin extends Plugin
@Subscribe
public void onGameTick(GameTick gameTick)
{
respawns.removeIf(RockRespawn::isExpired);
clearExpiredRespawns();
recentlyLoggedIn = false;
if (session == null || session.getLastMined() == null)
@@ -223,6 +225,24 @@ public class MiningPlugin extends Plugin
}
}
/**
* Clears expired respawns and removes the hint arrow from expired Daeyalt essence rocks.
*/
private void clearExpiredRespawns()
{
respawns.removeIf(rockRespawn ->
{
final boolean expired = rockRespawn.isExpired();
if (expired && rockRespawn.getRock() == Rock.DAEYALT_ESSENCE)
{
clearHintArrowAt(rockRespawn.getWorldPoint());
}
return expired;
});
}
public void resetSession()
{
session = null;
@@ -243,19 +263,29 @@ public class MiningPlugin extends Plugin
Rock rock = Rock.getRock(object.getId());
if (rock != null)
{
final WorldPoint point = object.getWorldLocation();
if (rock == Rock.DAEYALT_ESSENCE)
{
final WorldPoint point = object.getWorldLocation();
respawns.removeIf(rockRespawn -> rockRespawn.getWorldPoint().equals(point));
clearHintArrowAt(point);
}
else
{
RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(region).toMillis(), rock.getZOffset());
RockRespawn rockRespawn = new RockRespawn(rock, point, Instant.now(), (int) rock.getRespawnTime(region).toMillis(), rock.getZOffset());
respawns.add(rockRespawn);
}
}
}
private void clearHintArrowAt(WorldPoint worldPoint)
{
if (client.getHintArrowType() == WORLD_POSITION && client.getHintArrowPoint().equals(worldPoint))
{
client.clearHintArrow();
}
}
@Subscribe
public void onGameObjectSpawned(GameObjectSpawned event)
{
@@ -273,6 +303,7 @@ public class MiningPlugin extends Plugin
final int region = client.getLocalPlayer().getWorldLocation().getRegionID();
RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(region).toMillis(), rock.getZOffset());
respawns.add(rockRespawn);
client.setHintArrow(object.getWorldLocation());
}
// If the Lovakite ore respawns before the timer is up, remove it
else if (rock == Rock.LOVAKITE)

View File

@@ -27,6 +27,7 @@ package net.runelite.client.plugins.objectindicators;
import java.awt.Color;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import net.runelite.api.ObjectComposition;
import net.runelite.api.TileObject;
/**
@@ -38,5 +39,13 @@ import net.runelite.api.TileObject;
class ColorTileObject
{
private final TileObject tileObject;
/**
* Non-transformed object composition for the object
*/
private final ObjectComposition composition;
/**
* Name to highlight for multilocs
*/
private final String name;
private final Color color;
}

View File

@@ -33,6 +33,7 @@ import net.runelite.api.Client;
import net.runelite.api.DecorativeObject;
import net.runelite.api.GameObject;
import net.runelite.api.GroundObject;
import net.runelite.api.ObjectComposition;
import net.runelite.api.TileObject;
import net.runelite.api.WallObject;
import net.runelite.client.ui.overlay.Overlay;
@@ -71,6 +72,18 @@ class ObjectIndicatorsOverlay extends Overlay
continue;
}
ObjectComposition composition = colorTileObject.getComposition();
if (composition.getImpostorIds() != null)
{
// This is a multiloc
composition = composition.getImpostor();
// Only mark the object if the name still matches
if (composition == null || !composition.getName().equals(colorTileObject.getName()))
{
continue;
}
}
if (color == null || !config.rememberObjectColors())
{
// Fallback to the current config if the object is marked before the addition of multiple colors

View File

@@ -292,16 +292,15 @@ public class ObjectIndicatorsPlugin extends Plugin
{
if (worldPoint.getRegionX() == objectPoint.getRegionX()
&& worldPoint.getRegionY() == objectPoint.getRegionY()
&& worldPoint.getPlane() == objectPoint.getZ())
&& worldPoint.getPlane() == objectPoint.getZ()
&& objectPoint.getId() == object.getId())
{
// Transform object to get the name which matches against what we've stored
ObjectComposition composition = getObjectComposition(object.getId());
if (composition != null && objectPoint.getName().equals(composition.getName()))
{
log.debug("Marking object {} due to matching {}", object, objectPoint);
objects.add(new ColorTileObject(object, objectPoint.getColor()));
break;
}
log.debug("Marking object {} due to matching {}", object, objectPoint);
objects.add(new ColorTileObject(object,
client.getObjectDefinition(object.getId()),
objectPoint.getName(),
objectPoint.getColor()));
break;
}
}
}
@@ -415,7 +414,10 @@ public class ObjectIndicatorsPlugin extends Plugin
else
{
objectPoints.add(point);
objects.add(new ColorTileObject(object, color));
objects.add(new ColorTileObject(object,
client.getObjectDefinition(object.getId()),
name,
color));
log.debug("Marking object: {}", point);
}

View File

@@ -54,7 +54,7 @@ enum GameTimer
ICEBURST(SpriteID.SPELL_ICE_BURST, GameTimerImageType.SPRITE, "Ice burst", GraphicID.ICE_BURST, 16, GAME_TICKS, true),
ICEBLITZ(SpriteID.SPELL_ICE_BLITZ, GameTimerImageType.SPRITE, "Ice blitz", GraphicID.ICE_BLITZ, 24, GAME_TICKS, true),
ICEBARRAGE(SpriteID.SPELL_ICE_BARRAGE, GameTimerImageType.SPRITE, "Ice barrage", GraphicID.ICE_BARRAGE, 32, GAME_TICKS, true),
IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, ChronoUnit.SECONDS, true),
IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", 420, ChronoUnit.SECONDS, true),
VENGEANCE(SpriteID.SPELL_VENGEANCE, GameTimerImageType.SPRITE, "Vengeance", 30, ChronoUnit.SECONDS),
EXSUPERANTIFIRE(ItemID.EXTENDED_SUPER_ANTIFIRE4, GameTimerImageType.ITEM, "Extended Super AntiFire", 6, ChronoUnit.MINUTES),
OVERLOAD_RAID(ItemID.OVERLOAD_4_20996, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true),

View File

@@ -39,6 +39,7 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.EquipmentInventorySlot;
import net.runelite.api.GameState;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
@@ -48,11 +49,13 @@ import static net.runelite.api.ItemID.INFERNAL_CAPE;
import net.runelite.api.NPC;
import net.runelite.api.NpcID;
import net.runelite.api.Player;
import net.runelite.api.Skill;
import net.runelite.api.VarPlayer;
import net.runelite.api.Varbits;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ActorDeath;
import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.StatChanged;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
@@ -141,6 +144,8 @@ public class TimersPlugin extends Plugin
private int lastAnimation;
private boolean widgetHiddenChangedOnPvpWorld;
private ElapsedTimer tzhaarTimer;
private int imbuedHeartClickTick = -1;
private int lastBoostedMagicLevel = -1;
@Inject
private ItemManager itemManager;
@@ -163,6 +168,15 @@ public class TimersPlugin extends Plugin
return configManager.getConfig(TimersConfig.class);
}
@Override
public void startUp()
{
if (client.getGameState() == GameState.LOGGED_IN)
{
lastBoostedMagicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
}
}
@Override
protected void shutDown() throws Exception
{
@@ -176,6 +190,8 @@ public class TimersPlugin extends Plugin
nextPoisonTick = 0;
removeTzhaarTimer();
staminaTimer = null;
imbuedHeartClickTick = -1;
lastBoostedMagicLevel = -1;
}
@Subscribe
@@ -435,6 +451,12 @@ public class TimersPlugin extends Plugin
return;
}
if (event.getMenuOption().contains("Invigorate")
&& event.getId() == ItemID.IMBUED_HEART)
{
imbuedHeartClickTick = client.getTickCount();
}
TeleportWidget teleportWidget = TeleportWidget.of(event.getWidgetId());
if (teleportWidget != null)
{
@@ -796,8 +818,10 @@ public class TimersPlugin extends Plugin
config.tzhaarLastTime(null);
}
break;
case HOPPING:
case LOGIN_SCREEN:
lastBoostedMagicLevel = -1;
// fall through
case HOPPING:
// pause tzhaar timer if logged out without pausing
if (config.tzhaarStartTime() != null && config.tzhaarLastTime() == null)
{
@@ -856,11 +880,6 @@ public class TimersPlugin extends Plugin
return;
}
if (config.showImbuedHeart() && actor.getGraphic() == IMBUEDHEART.getGraphicId())
{
createGameTimer(IMBUEDHEART);
}
if (config.showFreezes())
{
if (actor.getGraphic() == BIND.getGraphicId())
@@ -978,6 +997,37 @@ public class TimersPlugin extends Plugin
}
}
@Subscribe
public void onStatChanged(StatChanged statChanged)
{
if (statChanged.getSkill() != Skill.MAGIC)
{
return;
}
final int boostedMagicLevel = statChanged.getBoostedLevel();
if (imbuedHeartClickTick < 0
|| client.getTickCount() > imbuedHeartClickTick + 3 // allow for 2 ticks of lag
|| !config.showImbuedHeart())
{
lastBoostedMagicLevel = boostedMagicLevel;
return;
}
final int boostAmount = boostedMagicLevel - statChanged.getLevel();
final int boostChange = boostedMagicLevel - lastBoostedMagicLevel;
final int heartBoost = 1 + (statChanged.getLevel() / 10);
if ((boostAmount == heartBoost || (lastBoostedMagicLevel != -1 && boostChange == heartBoost))
&& boostChange > 0)
{
createGameTimer(IMBUEDHEART);
}
lastBoostedMagicLevel = boostedMagicLevel;
}
private void createStaminaTimer()
{
Duration duration = Duration.ofMinutes(wasWearingEndurance ? 4 : 2);

View File

@@ -122,17 +122,18 @@ enum TransportationPointLocation
CHARTER_PRIFDDINAS_INSTANCE("Charter Ship", new WorldPoint(3180, 6083, 0)),
//Minecarts/Carts
MINE_CART_ARCEUUS("Minecart", new WorldPoint(1673, 3832, 0)),
MINE_CART_ARCEUUS("Lovakengj Minecart Network", new WorldPoint(1673, 3832, 0)),
MINE_CART_GRANDEXCHANGE("Minecart to Keldagrim", new WorldPoint(3139, 3504, 0)),
MINE_CART_HOSIDIUS("Minecart", new WorldPoint(1656, 3542, 0)),
MINE_CART_KELDAGRIM("Minecart", new WorldPoint(2908, 10170, 0)),
MINE_CART_LOVAKENGJ("Minecart", new WorldPoint(1524, 3721, 0)),
MINE_CART_PORT_PISCARILIUS("Minecart", new WorldPoint(1760, 3708, 0)),
MINE_CART_QUIDAMORTEM("Minecart", new WorldPoint(1253, 3550, 0)),
MINE_CART_SHAYZIEN("Minecart", new WorldPoint(1586, 3622, 0)),
MINE_CART_TAVERLEY_UNDERGROUND("Minecart", new WorldPoint(2874, 9870, 0)),
MINE_CART_HOSIDIUS("Lovakengj Minecart Network", new WorldPoint(1656, 3542, 0)),
MINE_CART_ICE_MOUNTAIN("Minecart to Keldagrim", new WorldPoint(2995, 9836, 0)),
MINE_CART_KELDAGRIM("Keldagrim Minecart System", new WorldPoint(2908, 10170, 0)),
MINE_CART_LOVAKENGJ("Lovakengj Minecart Network", new WorldPoint(1524, 3721, 0)),
MINE_CART_PORT_PISCARILIUS("Lovakengj Minecart Network", new WorldPoint(1760, 3708, 0)),
MINE_CART_QUIDAMORTEM("Lovakengj Minecart Network", new WorldPoint(1253, 3550, 0)),
MINE_CART_SHAYZIEN("Lovakengj Minecart Network", new WorldPoint(1586, 3622, 0)),
MINE_CART_WHITE_WOLF_MOUNTAIN("Minecart to Keldagrim", new WorldPoint(2874, 9870, 0)),
CART_TO_BRIMHAVEN("Cart to Brimhaven", new WorldPoint(2833, 2958, 0), new WorldPoint(2780, 3214, 0)),
CART_TO_SHILO("Cart to Shilo", new WorldPoint(2780, 3214, 0), new WorldPoint(2833, 2958, 0)),
CART_TO_SHILO("Cart to Shilo Village", new WorldPoint(2780, 3214, 0), new WorldPoint(2833, 2958, 0)),
//Canoes
CANOE_BARBVILLAGE("Canoe", new WorldPoint(3111, 3409, 0)),

View File

@@ -58,6 +58,7 @@ import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetItem;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
@@ -113,7 +114,8 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
final RuneLiteConfig runeLiteConfig,
final MouseManager mouseManager,
final KeyManager keyManager,
final ClientUI clientUI)
final ClientUI clientUI,
final EventBus eventBus)
{
this.client = client;
this.overlayManager = overlayManager;
@@ -121,6 +123,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
this.clientUI = clientUI;
keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this);
eventBus.register(this);
}
@Subscribe

View File

@@ -95,6 +95,7 @@ public class InfoBoxManager
this.eventBus = eventBus;
this.overlayManager = overlayManager;
this.configManager = configManager;
eventBus.register(this);
}
@Subscribe

View File

@@ -78,6 +78,7 @@ public class PartyService
this.sessionManager = sessionManager;
this.eventBus = eventBus;
this.chat = chat;
eventBus.register(this);
}
public void changeParty(UUID newParty)

View File

@@ -35,6 +35,7 @@ import net.runelite.api.MessageNode;
import net.runelite.api.Player;
import net.runelite.api.events.ChatMessage;
import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.events.ConfigChanged;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -62,8 +63,6 @@ public class ChatMessageManagerTest
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
chatMessageManager.loadColors();
}
@Test
@@ -71,7 +70,10 @@ public class ChatMessageManagerTest
{
when(chatColorConfig.opaqueServerMessage()).thenReturn(Color.decode("#b20000"));
chatMessageManager.loadColors();
// rebuild color cache
ConfigChanged configChanged = new ConfigChanged();
configChanged.setGroup("textrecolor");
chatMessageManager.onConfigChanged(configChanged);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.GAMEMESSAGE);
@@ -93,8 +95,6 @@ public class ChatMessageManagerTest
when(chatColorConfig.opaquePublicFriendUsernames()).thenReturn(Color.decode("#b20000"));
chatMessageManager.loadColors();
// Setup message
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
@@ -125,8 +125,6 @@ public class ChatMessageManagerTest
when(chatColorConfig.opaquePublicFriendUsernames()).thenReturn(Color.decode("#b20000"));
chatMessageManager.loadColors();
// Setup message
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);

View File

@@ -32,10 +32,15 @@ import java.time.Duration;
import java.time.Instant;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.InventoryID;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
import net.runelite.api.Skill;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.StatChanged;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.ui.overlay.infobox.InfoBox;
@@ -53,9 +58,11 @@ import static org.mockito.ArgumentMatchers.nullable;
import org.mockito.Mock;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
@@ -369,4 +376,125 @@ public class TimersPluginTest
ElapsedTimer timer = (ElapsedTimer) captor.getValue();
assertEquals("00:06", timer.getText());
}
}
@Test
public void testImbuedHeartBoost()
{
when(timersConfig.showImbuedHeart()).thenReturn(true);
when(client.getTickCount()).thenReturn(100);
StatChanged event;
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
for (int level = 1, i = 0; level <= Experience.MAX_REAL_LEVEL; level++, i++)
{
event = new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level));
timersPlugin.onStatChanged(event);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(i + 1)).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.IMBUEDHEART, infoBox.getTimer());
}
}
@Test
public void testImbuedHeartBoostFromDrained()
{
when(timersConfig.showImbuedHeart()).thenReturn(true);
when(client.getTickCount()).thenReturn(100);
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
for (int level = 1, i = 0; level <= Experience.MAX_REAL_LEVEL; level++, i++)
{
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, level - 1));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level) - 1));
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(i + 1)).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.IMBUEDHEART, infoBox.getTimer());
}
}
@Test
public void testImbuedHeartBoostFromPartialBoost()
{
when(timersConfig.showImbuedHeart()).thenReturn(true);
when(client.getTickCount()).thenReturn(100);
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
for (int level = 10, i = 0; level <= Experience.MAX_REAL_LEVEL; level++, i++)
{
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, level + 1));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level)));
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(i + 1)).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.IMBUEDHEART, infoBox.getTimer());
}
}
@Test
public void testNonImbuedHeartBoost()
{
lenient().when(timersConfig.showImbuedHeart()).thenReturn(true);
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 1, 1));
// Simulate stat changes of imbued heart boost amount without having clicked the imbued heart
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 29, 34)); // equal to magic essence
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 39, 43)); // equal to magic potion
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 49, 54)); // equal to spicy stew
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 99, 109));
verifyNoInteractions(infoBoxManager);
}
@Test
public void testMagicLevelDrain()
{
lenient().when(timersConfig.showImbuedHeart()).thenReturn(true);
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, 1, 1));
when(client.getTickCount()).thenReturn(100);
final MenuOptionClicked imbuedHeartClick = new MenuOptionClicked();
imbuedHeartClick.setMenuOption("Invigorate");
imbuedHeartClick.setId(ItemID.IMBUED_HEART);
timersPlugin.onMenuOptionClicked(imbuedHeartClick);
when(client.getTickCount()).thenReturn(101);
// Simulate stat changes draining to the imbued heart boost amount
for (int level = 1; level <= Experience.MAX_REAL_LEVEL; level++)
{
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, level));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level) + 1));
timersPlugin.onStatChanged(new StatChanged(Skill.MAGIC, 0, level, heartBoostedLevel(level)));
}
verifyNoInteractions(infoBoxManager);
}
private static int heartBoostedLevel(final int level)
{
return level + 1 + (level / 10);
}
}