plugins checkstyle
This commit is contained in:
@@ -1,57 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public abstract class Plugin implements Module
|
||||
{
|
||||
protected Injector injector;
|
||||
|
||||
public File file;
|
||||
public PluginClassLoader loader;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
}
|
||||
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public final Injector getInjector()
|
||||
{
|
||||
return injector;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import java.io.File;
|
||||
|
||||
public abstract class Plugin implements Module
|
||||
{
|
||||
protected Injector injector;
|
||||
|
||||
public File file;
|
||||
public PluginClassLoader loader;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
}
|
||||
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public final Injector getInjector()
|
||||
{
|
||||
return injector;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
public @interface PluginDescriptor
|
||||
{
|
||||
String name();
|
||||
|
||||
/**
|
||||
* A short, one-line summary of the plugin.
|
||||
*/
|
||||
String description() default "";
|
||||
|
||||
/**
|
||||
* A list of plugin keywords, used (together with the name) when searching for plugins.
|
||||
* Each tag should not contain any spaces, and should be fully lowercase.
|
||||
*/
|
||||
String[] tags() default {};
|
||||
|
||||
boolean enabledByDefault() default true;
|
||||
|
||||
/**
|
||||
* Whether or not plugin is hidden from configuration panel
|
||||
*/
|
||||
boolean hidden() default false;
|
||||
|
||||
boolean developerPlugin() default false;
|
||||
|
||||
boolean loadWhenOutdated() default false;
|
||||
|
||||
PluginType type() default PluginType.GENERAL_USE;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
public @interface PluginDescriptor
|
||||
{
|
||||
String name();
|
||||
|
||||
/**
|
||||
* A short, one-line summary of the plugin.
|
||||
*/
|
||||
String description() default "";
|
||||
|
||||
/**
|
||||
* A list of plugin keywords, used (together with the name) when searching for plugins.
|
||||
* Each tag should not contain any spaces, and should be fully lowercase.
|
||||
*/
|
||||
String[] tags() default {};
|
||||
|
||||
boolean enabledByDefault() default true;
|
||||
|
||||
/**
|
||||
* Whether or not plugin is hidden from configuration panel
|
||||
*/
|
||||
boolean hidden() default false;
|
||||
|
||||
boolean developerPlugin() default false;
|
||||
|
||||
boolean loadWhenOutdated() default false;
|
||||
|
||||
PluginType type() default PluginType.GENERAL_USE;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,16 @@
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
public enum PluginType {
|
||||
|
||||
PVM,
|
||||
PVP,
|
||||
|
||||
UTILITY,
|
||||
GENERAL_USE,
|
||||
|
||||
EXTERNAL,
|
||||
|
||||
PLUGIN_ORGANIZER
|
||||
|
||||
}
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
public enum PluginType
|
||||
{
|
||||
|
||||
PVM,
|
||||
PVP,
|
||||
|
||||
UTILITY,
|
||||
GENERAL_USE,
|
||||
|
||||
EXTERNAL,
|
||||
|
||||
PLUGIN_ORGANIZER
|
||||
|
||||
}
|
||||
|
||||
@@ -1,273 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchEvent.Kind;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class PluginWatcher extends Thread
|
||||
{
|
||||
private static final File BASE = RuneLite.PLUGIN_DIR;
|
||||
|
||||
private final RuneLiteConfig runeliteConfig;
|
||||
private final PluginManager pluginManager;
|
||||
private final WatchService watchService;
|
||||
private final WatchKey watchKey;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
public PluginWatcher(RuneLiteConfig runeliteConfig, PluginManager pluginManager) throws IOException
|
||||
{
|
||||
this.runeliteConfig = runeliteConfig;
|
||||
this.pluginManager = pluginManager;
|
||||
|
||||
setName("Plugin Watcher");
|
||||
setDaemon(true);
|
||||
|
||||
watchService = FileSystems.getDefault().newWatchService();
|
||||
BASE.mkdirs();
|
||||
Path dir = BASE.toPath();
|
||||
watchKey = dir.register(watchService, ENTRY_MODIFY, ENTRY_DELETE);
|
||||
}
|
||||
|
||||
public void cancel()
|
||||
{
|
||||
watchKey.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (runeliteConfig.enablePlugins())
|
||||
{
|
||||
scan();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
WatchKey key = watchService.take();
|
||||
Thread.sleep(50);
|
||||
|
||||
if (!runeliteConfig.enablePlugins())
|
||||
{
|
||||
key.reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WatchEvent<?> event : key.pollEvents())
|
||||
{
|
||||
Kind<?> kind = event.kind();
|
||||
Path path = (Path) event.context();
|
||||
File file = new File(BASE, path.toFile().getName());
|
||||
|
||||
log.debug("Event {} file {}", kind, file);
|
||||
|
||||
if (kind == ENTRY_MODIFY)
|
||||
{
|
||||
Plugin existing = findPluginForFile(file);
|
||||
if (existing != null)
|
||||
{
|
||||
log.info("Reloading plugin {}", file);
|
||||
unload(existing);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info("Loading plugin {}", file);
|
||||
}
|
||||
|
||||
load(file);
|
||||
}
|
||||
else if (kind == ENTRY_DELETE)
|
||||
{
|
||||
Plugin existing = findPluginForFile(file);
|
||||
if (existing != null)
|
||||
{
|
||||
log.info("Unloading plugin {}", file);
|
||||
|
||||
unload(existing);
|
||||
}
|
||||
}
|
||||
}
|
||||
key.reset();
|
||||
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
log.warn("error polling for plugins", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scan()
|
||||
{
|
||||
for (File file : BASE.listFiles())
|
||||
{
|
||||
if (!file.getName().endsWith(".jar"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("Loading plugin from {}", file);
|
||||
load(file);
|
||||
}
|
||||
}
|
||||
|
||||
private Plugin findPluginForFile(File file)
|
||||
{
|
||||
for (Plugin plugin : pluginManager.getPlugins())
|
||||
{
|
||||
if (plugin.file != null && plugin.file.equals(file))
|
||||
{
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void load(File pluginFile)
|
||||
{
|
||||
PluginClassLoader loader;
|
||||
try
|
||||
{
|
||||
loader = new PluginClassLoader(pluginFile, getClass().getClassLoader());
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
log.warn("Error loading plugin", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
List<Plugin> loadedPlugins;
|
||||
try
|
||||
{
|
||||
loadedPlugins = pluginManager.scanAndInstantiate(loader, null);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
close(loader);
|
||||
log.warn("Error loading plugin", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadedPlugins.isEmpty())
|
||||
{
|
||||
close(loader);
|
||||
log.warn("No plugin found in plugin {}", pluginFile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadedPlugins.size() != 1)
|
||||
{
|
||||
close(loader);
|
||||
log.warn("You can not have more than one plugin per jar");
|
||||
return;
|
||||
}
|
||||
|
||||
Plugin plugin = loadedPlugins.get(0);
|
||||
plugin.file = pluginFile;
|
||||
plugin.loader = loader;
|
||||
|
||||
// Initialize default configuration
|
||||
Injector injector = plugin.getInjector();
|
||||
for (Key<?> key : injector.getAllBindings().keySet())
|
||||
{
|
||||
Class<?> type = key.getTypeLiteral().getRawType();
|
||||
if (Config.class.isAssignableFrom(type))
|
||||
{
|
||||
Config config = (Config) injector.getInstance(key);
|
||||
configManager.setDefaultConfiguration(config, false);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
pluginManager.startPlugin(plugin);
|
||||
}
|
||||
catch (PluginInstantiationException ex)
|
||||
{
|
||||
close(loader);
|
||||
log.warn("unable to start plugin", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Plugin is now running
|
||||
pluginManager.add(plugin);
|
||||
}
|
||||
|
||||
private void unload(Plugin plugin)
|
||||
{
|
||||
try
|
||||
{
|
||||
pluginManager.stopPlugin(plugin);
|
||||
}
|
||||
catch (PluginInstantiationException ex)
|
||||
{
|
||||
log.warn("unable to stop plugin", ex);
|
||||
}
|
||||
|
||||
pluginManager.remove(plugin); // remove it regardless
|
||||
|
||||
close(plugin.loader);
|
||||
}
|
||||
|
||||
private void close(URLClassLoader classLoader)
|
||||
{
|
||||
try
|
||||
{
|
||||
classLoader.close();
|
||||
}
|
||||
catch (IOException ex1)
|
||||
{
|
||||
log.warn(null, ex1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
|
||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchEvent.Kind;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class PluginWatcher extends Thread
|
||||
{
|
||||
private static final File BASE = RuneLite.PLUGIN_DIR;
|
||||
|
||||
private final RuneLiteConfig runeliteConfig;
|
||||
private final PluginManager pluginManager;
|
||||
private final WatchService watchService;
|
||||
private final WatchKey watchKey;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
public PluginWatcher(RuneLiteConfig runeliteConfig, PluginManager pluginManager) throws IOException
|
||||
{
|
||||
this.runeliteConfig = runeliteConfig;
|
||||
this.pluginManager = pluginManager;
|
||||
|
||||
setName("Plugin Watcher");
|
||||
setDaemon(true);
|
||||
|
||||
watchService = FileSystems.getDefault().newWatchService();
|
||||
BASE.mkdirs();
|
||||
Path dir = BASE.toPath();
|
||||
watchKey = dir.register(watchService, ENTRY_MODIFY, ENTRY_DELETE);
|
||||
}
|
||||
|
||||
public void cancel()
|
||||
{
|
||||
watchKey.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (runeliteConfig.enablePlugins())
|
||||
{
|
||||
scan();
|
||||
}
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
try
|
||||
{
|
||||
WatchKey key = watchService.take();
|
||||
Thread.sleep(50);
|
||||
|
||||
if (!runeliteConfig.enablePlugins())
|
||||
{
|
||||
key.reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WatchEvent<?> event : key.pollEvents())
|
||||
{
|
||||
Kind<?> kind = event.kind();
|
||||
Path path = (Path) event.context();
|
||||
File file = new File(BASE, path.toFile().getName());
|
||||
|
||||
log.debug("Event {} file {}", kind, file);
|
||||
|
||||
if (kind == ENTRY_MODIFY)
|
||||
{
|
||||
Plugin existing = findPluginForFile(file);
|
||||
if (existing != null)
|
||||
{
|
||||
log.info("Reloading plugin {}", file);
|
||||
unload(existing);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info("Loading plugin {}", file);
|
||||
}
|
||||
|
||||
load(file);
|
||||
}
|
||||
else if (kind == ENTRY_DELETE)
|
||||
{
|
||||
Plugin existing = findPluginForFile(file);
|
||||
if (existing != null)
|
||||
{
|
||||
log.info("Unloading plugin {}", file);
|
||||
|
||||
unload(existing);
|
||||
}
|
||||
}
|
||||
}
|
||||
key.reset();
|
||||
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
log.warn("error polling for plugins", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scan()
|
||||
{
|
||||
for (File file : BASE.listFiles())
|
||||
{
|
||||
if (!file.getName().endsWith(".jar"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("Loading plugin from {}", file);
|
||||
load(file);
|
||||
}
|
||||
}
|
||||
|
||||
private Plugin findPluginForFile(File file)
|
||||
{
|
||||
for (Plugin plugin : pluginManager.getPlugins())
|
||||
{
|
||||
if (plugin.file != null && plugin.file.equals(file))
|
||||
{
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void load(File pluginFile)
|
||||
{
|
||||
PluginClassLoader loader;
|
||||
try
|
||||
{
|
||||
loader = new PluginClassLoader(pluginFile, getClass().getClassLoader());
|
||||
}
|
||||
catch (MalformedURLException ex)
|
||||
{
|
||||
log.warn("Error loading plugin", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
List<Plugin> loadedPlugins;
|
||||
try
|
||||
{
|
||||
loadedPlugins = pluginManager.scanAndInstantiate(loader, null);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
close(loader);
|
||||
log.warn("Error loading plugin", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadedPlugins.isEmpty())
|
||||
{
|
||||
close(loader);
|
||||
log.warn("No plugin found in plugin {}", pluginFile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadedPlugins.size() != 1)
|
||||
{
|
||||
close(loader);
|
||||
log.warn("You can not have more than one plugin per jar");
|
||||
return;
|
||||
}
|
||||
|
||||
Plugin plugin = loadedPlugins.get(0);
|
||||
plugin.file = pluginFile;
|
||||
plugin.loader = loader;
|
||||
|
||||
// Initialize default configuration
|
||||
Injector injector = plugin.getInjector();
|
||||
for (Key<?> key : injector.getAllBindings().keySet())
|
||||
{
|
||||
Class<?> type = key.getTypeLiteral().getRawType();
|
||||
if (Config.class.isAssignableFrom(type))
|
||||
{
|
||||
Config config = (Config) injector.getInstance(key);
|
||||
configManager.setDefaultConfiguration(config, false);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
pluginManager.startPlugin(plugin);
|
||||
}
|
||||
catch (PluginInstantiationException ex)
|
||||
{
|
||||
close(loader);
|
||||
log.warn("unable to start plugin", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Plugin is now running
|
||||
pluginManager.add(plugin);
|
||||
}
|
||||
|
||||
private void unload(Plugin plugin)
|
||||
{
|
||||
try
|
||||
{
|
||||
pluginManager.stopPlugin(plugin);
|
||||
}
|
||||
catch (PluginInstantiationException ex)
|
||||
{
|
||||
log.warn("unable to stop plugin", ex);
|
||||
}
|
||||
|
||||
pluginManager.remove(plugin); // remove it regardless
|
||||
|
||||
close(plugin.loader);
|
||||
}
|
||||
|
||||
private void close(URLClassLoader classLoader)
|
||||
{
|
||||
try
|
||||
{
|
||||
classLoader.close();
|
||||
}
|
||||
catch (IOException ex1)
|
||||
{
|
||||
log.warn(null, ex1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.plugins.achievementdiary;
|
||||
|
||||
public interface Requirement
|
||||
{
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019 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.plugins.achievementdiary;
|
||||
|
||||
public interface Requirement
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,136 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2019 William <https://github.com/monsterxsync>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Favour;
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.FavourRequirement;
|
||||
|
||||
public class KourendDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public KourendDiaryRequirement()
|
||||
{
|
||||
//EASY
|
||||
add("Mine some Iron at the Mount Karuulm mine.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
add("Steal from a Hosidius Food Stall.",
|
||||
new SkillRequirement(Skill.THIEVING, 25),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 15));
|
||||
add("Browse the Warrens General Store.",
|
||||
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES, true));
|
||||
add("Enter your Player Owned House from Hosidius.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 25));
|
||||
add("Create a Strength potion in the Lovakengj Pub.",
|
||||
new SkillRequirement(Skill.HERBLORE, 12));
|
||||
add("Fish a Trout from the River Molch.",
|
||||
new SkillRequirement(Skill.FISHING, 20));
|
||||
|
||||
//MEDIUM
|
||||
add("Travel to the Fairy Ring south of Mount Karuulm.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Use Kharedst's memoirs to teleport to all five cities in Great Kourend.",
|
||||
new QuestRequirement(Quest.THE_DEPTHS_OF_DESPAIR),
|
||||
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES),
|
||||
new QuestRequirement(Quest.TALE_OF_THE_RIGHTEOUS),
|
||||
new QuestRequirement(Quest.THE_FORSAKEN_TOWER),
|
||||
new QuestRequirement(Quest.THE_ASCENT_OF_ARCEUUS));
|
||||
add("Mine some Volcanic sulphur.",
|
||||
new SkillRequirement(Skill.MINING, 42));
|
||||
add("Enter the Farming Guild.",
|
||||
new SkillRequirement(Skill.FARMING, 45));
|
||||
add("Switch to the Necromancy Spellbook at Tyss.",
|
||||
new FavourRequirement(Favour.ARCEUUS, 60));
|
||||
add("Repair a Piscarilius crane.",
|
||||
new SkillRequirement(Skill.CRAFTING, 30));
|
||||
add("Deliver some intelligence to Captain Ginea.",
|
||||
new FavourRequirement(Favour.SHAYZIEN, 40));
|
||||
add("Catch a Bluegill on Molch Island.",
|
||||
new SkillRequirement(Skill.FISHING, 43),
|
||||
new SkillRequirement(Skill.HUNTER, 35));
|
||||
add("Use the boulder leap in the Arceuus essence mine.",
|
||||
new SkillRequirement(Skill.AGILITY, 49));
|
||||
add("Subdue the Wintertodt.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 50));
|
||||
add("Catch a Chinchompa in the Kourend Woodland.",
|
||||
new SkillRequirement(Skill.HUNTER, 53),
|
||||
new QuestRequirement(Quest.EAGLES_PEAK));
|
||||
add("Chop some Mahogany logs north of the Farming Guild.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 50));
|
||||
|
||||
//HARD
|
||||
add("Enter the Woodcutting Guild.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 60),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 75));
|
||||
add("Smelt an Adamantite bar in The Forsaken Tower.",
|
||||
new SkillRequirement(Skill.SMITHING, 70),
|
||||
new QuestRequirement(Quest.THE_FORSAKEN_TOWER, true));
|
||||
add("Kill a Lizardman Shaman in Molch.",
|
||||
new FavourRequirement(Favour.SHAYZIEN, 100));
|
||||
add("Mine some Lovakite.",
|
||||
new SkillRequirement(Skill.MINING, 65),
|
||||
new FavourRequirement(Favour.LOVAKENGJ, 30));
|
||||
add("Plant some Logavano seeds at the Tithe Farm.",
|
||||
new SkillRequirement(Skill.FARMING, 74),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 100));
|
||||
add("Teleport to Xeric's Heart using Xeric's Talisman.",
|
||||
new QuestRequirement(Quest.ARCHITECTURAL_ALLIANCE));
|
||||
add("Deliver an artefact to Captain Khaled.",
|
||||
new SkillRequirement(Skill.THIEVING, 49),
|
||||
new FavourRequirement(Favour.PISCARILIUS, 75));
|
||||
add("Kill a Wyrm in the Karuulm Slayer Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 62));
|
||||
add("Cast Monster Examine on a Troll south of Mount Quidamortem.",
|
||||
new SkillRequirement(Skill.MAGIC, 66),
|
||||
new QuestRequirement(Quest.DREAM_MENTOR));
|
||||
|
||||
//ELITE
|
||||
add("Craft one or more Blood runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 77),
|
||||
new SkillRequirement(Skill.MINING, 38),
|
||||
new SkillRequirement(Skill.CRAFTING, 38),
|
||||
new FavourRequirement(Favour.ARCEUUS, 100));
|
||||
add("Chop some Redwood logs.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 90),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 75));
|
||||
add("Catch an Anglerfish and cook it whilst in Great Kourend.",
|
||||
new SkillRequirement(Skill.FISHING, 82),
|
||||
new SkillRequirement(Skill.COOKING, 84),
|
||||
new FavourRequirement(Favour.PISCARILIUS, 100));
|
||||
add("Kill a Hydra in the Karuulm Slayer Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 95));
|
||||
add("Create an Ape Atoll teleport tablet.",
|
||||
new SkillRequirement(Skill.MAGIC, 90),
|
||||
new SkillRequirement(Skill.MINING, 38),
|
||||
new SkillRequirement(Skill.CRAFTING, 38),
|
||||
new FavourRequirement(Favour.ARCEUUS, 100));
|
||||
add("Create your own Battlestaff from scratch within the Farming Guild.",
|
||||
new SkillRequirement(Skill.FARMING, 85),
|
||||
new SkillRequirement(Skill.FLETCHING, 40));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019 William <https://github.com/monsterxsync>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Favour;
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.FavourRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class KourendDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public KourendDiaryRequirement()
|
||||
{
|
||||
//EASY
|
||||
add("Mine some Iron at the Mount Karuulm mine.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
add("Steal from a Hosidius Food Stall.",
|
||||
new SkillRequirement(Skill.THIEVING, 25),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 15));
|
||||
add("Browse the Warrens General Store.",
|
||||
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES, true));
|
||||
add("Enter your Player Owned House from Hosidius.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 25));
|
||||
add("Create a Strength potion in the Lovakengj Pub.",
|
||||
new SkillRequirement(Skill.HERBLORE, 12));
|
||||
add("Fish a Trout from the River Molch.",
|
||||
new SkillRequirement(Skill.FISHING, 20));
|
||||
|
||||
//MEDIUM
|
||||
add("Travel to the Fairy Ring south of Mount Karuulm.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Use Kharedst's memoirs to teleport to all five cities in Great Kourend.",
|
||||
new QuestRequirement(Quest.THE_DEPTHS_OF_DESPAIR),
|
||||
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES),
|
||||
new QuestRequirement(Quest.TALE_OF_THE_RIGHTEOUS),
|
||||
new QuestRequirement(Quest.THE_FORSAKEN_TOWER),
|
||||
new QuestRequirement(Quest.THE_ASCENT_OF_ARCEUUS));
|
||||
add("Mine some Volcanic sulphur.",
|
||||
new SkillRequirement(Skill.MINING, 42));
|
||||
add("Enter the Farming Guild.",
|
||||
new SkillRequirement(Skill.FARMING, 45));
|
||||
add("Switch to the Necromancy Spellbook at Tyss.",
|
||||
new FavourRequirement(Favour.ARCEUUS, 60));
|
||||
add("Repair a Piscarilius crane.",
|
||||
new SkillRequirement(Skill.CRAFTING, 30));
|
||||
add("Deliver some intelligence to Captain Ginea.",
|
||||
new FavourRequirement(Favour.SHAYZIEN, 40));
|
||||
add("Catch a Bluegill on Molch Island.",
|
||||
new SkillRequirement(Skill.FISHING, 43),
|
||||
new SkillRequirement(Skill.HUNTER, 35));
|
||||
add("Use the boulder leap in the Arceuus essence mine.",
|
||||
new SkillRequirement(Skill.AGILITY, 49));
|
||||
add("Subdue the Wintertodt.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 50));
|
||||
add("Catch a Chinchompa in the Kourend Woodland.",
|
||||
new SkillRequirement(Skill.HUNTER, 53),
|
||||
new QuestRequirement(Quest.EAGLES_PEAK));
|
||||
add("Chop some Mahogany logs north of the Farming Guild.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 50));
|
||||
|
||||
//HARD
|
||||
add("Enter the Woodcutting Guild.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 60),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 75));
|
||||
add("Smelt an Adamantite bar in The Forsaken Tower.",
|
||||
new SkillRequirement(Skill.SMITHING, 70),
|
||||
new QuestRequirement(Quest.THE_FORSAKEN_TOWER, true));
|
||||
add("Kill a Lizardman Shaman in Molch.",
|
||||
new FavourRequirement(Favour.SHAYZIEN, 100));
|
||||
add("Mine some Lovakite.",
|
||||
new SkillRequirement(Skill.MINING, 65),
|
||||
new FavourRequirement(Favour.LOVAKENGJ, 30));
|
||||
add("Plant some Logavano seeds at the Tithe Farm.",
|
||||
new SkillRequirement(Skill.FARMING, 74),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 100));
|
||||
add("Teleport to Xeric's Heart using Xeric's Talisman.",
|
||||
new QuestRequirement(Quest.ARCHITECTURAL_ALLIANCE));
|
||||
add("Deliver an artefact to Captain Khaled.",
|
||||
new SkillRequirement(Skill.THIEVING, 49),
|
||||
new FavourRequirement(Favour.PISCARILIUS, 75));
|
||||
add("Kill a Wyrm in the Karuulm Slayer Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 62));
|
||||
add("Cast Monster Examine on a Troll south of Mount Quidamortem.",
|
||||
new SkillRequirement(Skill.MAGIC, 66),
|
||||
new QuestRequirement(Quest.DREAM_MENTOR));
|
||||
|
||||
//ELITE
|
||||
add("Craft one or more Blood runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 77),
|
||||
new SkillRequirement(Skill.MINING, 38),
|
||||
new SkillRequirement(Skill.CRAFTING, 38),
|
||||
new FavourRequirement(Favour.ARCEUUS, 100));
|
||||
add("Chop some Redwood logs.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 90),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 75));
|
||||
add("Catch an Anglerfish and cook it whilst in Great Kourend.",
|
||||
new SkillRequirement(Skill.FISHING, 82),
|
||||
new SkillRequirement(Skill.COOKING, 84),
|
||||
new FavourRequirement(Favour.PISCARILIUS, 100));
|
||||
add("Kill a Hydra in the Karuulm Slayer Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 95));
|
||||
add("Create an Ape Atoll teleport tablet.",
|
||||
new SkillRequirement(Skill.MAGIC, 90),
|
||||
new SkillRequirement(Skill.MINING, 38),
|
||||
new SkillRequirement(Skill.CRAFTING, 38),
|
||||
new FavourRequirement(Favour.ARCEUUS, 100));
|
||||
add("Create your own Battlestaff from scratch within the Farming Guild.",
|
||||
new SkillRequirement(Skill.FARMING, 85),
|
||||
new SkillRequirement(Skill.FLETCHING, 40));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,141 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Cas <https://github.com/casvandongen>
|
||||
* 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.agility;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class AgilityOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE;
|
||||
|
||||
private final Client client;
|
||||
private final AgilityPlugin plugin;
|
||||
private final AgilityConfig config;
|
||||
|
||||
@Inject
|
||||
private AgilityOverlay(Client client, AgilityPlugin plugin, AgilityConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
|
||||
Point mousePosition = client.getMouseCanvasPosition();
|
||||
final List<Tile> marksOfGrace = plugin.getMarksOfGrace();
|
||||
plugin.getObstacles().forEach((object, obstacle) ->
|
||||
{
|
||||
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() ||
|
||||
Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = obstacle.getTile();
|
||||
if (tile.getPlane() == client.getPlane()
|
||||
&& object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
{
|
||||
// This assumes that the obstacle is not clickable.
|
||||
if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()))
|
||||
{
|
||||
Polygon polygon = object.getCanvasTilePoly();
|
||||
if (polygon != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, polygon, config.getTrapColor());
|
||||
}
|
||||
return;
|
||||
}
|
||||
Area objectClickbox = object.getClickbox();
|
||||
if (objectClickbox != null)
|
||||
{
|
||||
AgilityShortcut agilityShortcut = obstacle.getShortcut();
|
||||
Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? config.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR;
|
||||
if (config.highlightMarks() && !marksOfGrace.isEmpty())
|
||||
{
|
||||
configColor = config.getMarkColor();
|
||||
}
|
||||
|
||||
if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY()))
|
||||
{
|
||||
graphics.setColor(configColor.darker());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(configColor);
|
||||
}
|
||||
|
||||
graphics.draw(objectClickbox);
|
||||
graphics.setColor(new Color(configColor.getRed(), configColor.getGreen(), configColor.getBlue(), 50));
|
||||
graphics.fill(objectClickbox);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (config.highlightMarks() && !marksOfGrace.isEmpty())
|
||||
{
|
||||
for (Tile markOfGraceTile : marksOfGrace)
|
||||
{
|
||||
if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null
|
||||
&& markOfGraceTile.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
{
|
||||
final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly();
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OverlayUtil.renderPolygon(graphics, poly, config.getMarkColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Cas <https://github.com/casvandongen>
|
||||
* 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.agility;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class AgilityOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE;
|
||||
|
||||
private final Client client;
|
||||
private final AgilityPlugin plugin;
|
||||
private final AgilityConfig config;
|
||||
|
||||
@Inject
|
||||
private AgilityOverlay(Client client, AgilityPlugin plugin, AgilityConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
|
||||
Point mousePosition = client.getMouseCanvasPosition();
|
||||
final List<Tile> marksOfGrace = plugin.getMarksOfGrace();
|
||||
plugin.getObstacles().forEach((object, obstacle) ->
|
||||
{
|
||||
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() ||
|
||||
Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = obstacle.getTile();
|
||||
if (tile.getPlane() == client.getPlane()
|
||||
&& object.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
{
|
||||
// This assumes that the obstacle is not clickable.
|
||||
if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()))
|
||||
{
|
||||
Polygon polygon = object.getCanvasTilePoly();
|
||||
if (polygon != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, polygon, config.getTrapColor());
|
||||
}
|
||||
return;
|
||||
}
|
||||
Area objectClickbox = object.getClickbox();
|
||||
if (objectClickbox != null)
|
||||
{
|
||||
AgilityShortcut agilityShortcut = obstacle.getShortcut();
|
||||
Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? config.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR;
|
||||
if (config.highlightMarks() && !marksOfGrace.isEmpty())
|
||||
{
|
||||
configColor = config.getMarkColor();
|
||||
}
|
||||
|
||||
if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY()))
|
||||
{
|
||||
graphics.setColor(configColor.darker());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(configColor);
|
||||
}
|
||||
|
||||
graphics.draw(objectClickbox);
|
||||
graphics.setColor(new Color(configColor.getRed(), configColor.getGreen(), configColor.getBlue(), 50));
|
||||
graphics.fill(objectClickbox);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (config.highlightMarks() && !marksOfGrace.isEmpty())
|
||||
{
|
||||
for (Tile markOfGraceTile : marksOfGrace)
|
||||
{
|
||||
if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null
|
||||
&& markOfGraceTile.getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
{
|
||||
final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly();
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OverlayUtil.renderPolygon(graphics, poly, config.getMarkColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,462 +1,463 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.agility;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemID;
|
||||
import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Skill;
|
||||
import static net.runelite.api.Skill.AGILITY;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.BoostedLevelChanged;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.DecorativeObjectChanged;
|
||||
import net.runelite.api.events.DecorativeObjectDespawned;
|
||||
import net.runelite.api.events.DecorativeObjectSpawned;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameObjectChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GroundObjectChanged;
|
||||
import net.runelite.api.events.GroundObjectDespawned;
|
||||
import net.runelite.api.events.GroundObjectSpawned;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.WallObjectChanged;
|
||||
import net.runelite.api.events.WallObjectDespawned;
|
||||
import net.runelite.api.events.WallObjectSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.api.MenuAction;
|
||||
import java.awt.Color;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Agility",
|
||||
description = "Show helpful information about agility courses and obstacles",
|
||||
tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"}
|
||||
)
|
||||
@Slf4j
|
||||
public class AgilityPlugin extends Plugin
|
||||
{
|
||||
private static final int AGILITY_ARENA_REGION_ID = 11157;
|
||||
|
||||
@Getter
|
||||
private final Map<TileObject, Obstacle> obstacles = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private final List<Tile> marksOfGrace = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AgilityOverlay agilityOverlay;
|
||||
|
||||
@Inject
|
||||
private LapCounterOverlay lapCounterOverlay;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private AgilityConfig config;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Getter
|
||||
private AgilitySession session;
|
||||
|
||||
private int lastAgilityXp;
|
||||
private WorldPoint lastArenaTicketPosition;
|
||||
|
||||
@Getter
|
||||
private int agilityLevel;
|
||||
|
||||
@Provides
|
||||
AgilityConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AgilityConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(agilityOverlay);
|
||||
overlayManager.add(lapCounterOverlay);
|
||||
agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(agilityOverlay);
|
||||
overlayManager.remove(lapCounterOverlay);
|
||||
marksOfGrace.clear();
|
||||
obstacles.clear();
|
||||
session = null;
|
||||
agilityLevel = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
switch (event.getGameState())
|
||||
{
|
||||
case HOPPING:
|
||||
case LOGIN_SCREEN:
|
||||
session = null;
|
||||
lastArenaTicketPosition = null;
|
||||
removeAgilityArenaTimer();
|
||||
break;
|
||||
case LOADING:
|
||||
marksOfGrace.clear();
|
||||
obstacles.clear();
|
||||
break;
|
||||
case LOGGED_IN:
|
||||
if (!isInAgilityArena())
|
||||
{
|
||||
lastArenaTicketPosition = null;
|
||||
removeAgilityArenaTimer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!config.showAgilityArenaTimer())
|
||||
{
|
||||
removeAgilityArenaTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event)
|
||||
{
|
||||
if (event.getSkill() != AGILITY || !config.showLapCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine how much EXP was actually gained
|
||||
int agilityXp = client.getSkillExperience(AGILITY);
|
||||
int skillGained = agilityXp - lastAgilityXp;
|
||||
lastAgilityXp = agilityXp;
|
||||
|
||||
// Get course
|
||||
Courses course = Courses.getCourse(client.getLocalPlayer().getWorldLocation().getRegionID());
|
||||
if (course == null
|
||||
|| (course.getCourseEndWorldPoints().length == 0
|
||||
? Math.abs(course.getLastObstacleXp() - skillGained) > 1
|
||||
: Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation()))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (session != null && session.getCourse() == course)
|
||||
{
|
||||
session.incrementLapCount(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
session = new AgilitySession(course);
|
||||
// New course found, reset lap count and set new course
|
||||
session.resetLapCount();
|
||||
session.incrementLapCount(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged)
|
||||
{
|
||||
Skill skill = boostedLevelChanged.getSkill();
|
||||
if (skill == AGILITY)
|
||||
{
|
||||
agilityLevel = client.getBoostedSkillLevel(skill);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
if (obstacles.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Item item = itemSpawned.getItem();
|
||||
final Tile tile = itemSpawned.getTile();
|
||||
|
||||
if (item.getId() == ItemID.MARK_OF_GRACE)
|
||||
{
|
||||
marksOfGrace.add(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemDespawned(ItemDespawned itemDespawned)
|
||||
{
|
||||
final Tile tile = itemDespawned.getTile();
|
||||
marksOfGrace.remove(tile);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
if (isInAgilityArena())
|
||||
{
|
||||
// Hint arrow has no plane, and always returns the current plane
|
||||
WorldPoint newTicketPosition = client.getHintArrowPoint();
|
||||
WorldPoint oldTickPosition = lastArenaTicketPosition;
|
||||
|
||||
lastArenaTicketPosition = newTicketPosition;
|
||||
|
||||
if (oldTickPosition != null && newTicketPosition != null
|
||||
&& (oldTickPosition.getX() != newTicketPosition.getX() || oldTickPosition.getY() != newTicketPosition.getY()))
|
||||
{
|
||||
log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition);
|
||||
|
||||
if (config.notifyAgilityArena())
|
||||
{
|
||||
notifier.notify("Ticket location changed");
|
||||
}
|
||||
|
||||
if (config.showAgilityArenaTimer())
|
||||
{
|
||||
showNewAgilityArenaTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInAgilityArena()
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
if (local == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint location = local.getWorldLocation();
|
||||
return location.getRegionID() == AGILITY_ARENA_REGION_ID;
|
||||
}
|
||||
|
||||
private void removeAgilityArenaTimer()
|
||||
{
|
||||
infoBoxManager.removeIf(infoBox -> infoBox instanceof AgilityArenaTimer);
|
||||
}
|
||||
|
||||
private void showNewAgilityArenaTimer()
|
||||
{
|
||||
removeAgilityArenaTimer();
|
||||
infoBoxManager.addInfoBox(new AgilityArenaTimer(this, itemManager.getImage(AGILITY_ARENA_TICKET)));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getGameObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectChanged(GameObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getGameObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getGameObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGroundObjectSpawned(GroundObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getGroundObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGroundObjectChanged(GroundObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGroundObjectDespawned(GroundObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getGroundObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectSpawned(WallObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getWallObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectChanged(WallObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getWallObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectDespawned(WallObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getWallObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDecorativeObjectSpawned(DecorativeObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getDecorativeObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDecorativeObjectChanged(DecorativeObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDecorativeObjectDespawned(DecorativeObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getDecorativeObject(), null);
|
||||
}
|
||||
|
||||
private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject)
|
||||
{
|
||||
obstacles.remove(oldObject);
|
||||
|
||||
if (newObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) ||
|
||||
(Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId())
|
||||
&& Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID())))
|
||||
{
|
||||
obstacles.put(newObject, new Obstacle(tile, null));
|
||||
}
|
||||
|
||||
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(newObject.getId()))
|
||||
{
|
||||
AgilityShortcut closestShortcut = null;
|
||||
int distance = -1;
|
||||
|
||||
// Find the closest shortcut to this object
|
||||
for (AgilityShortcut shortcut : Obstacles.SHORTCUT_OBSTACLE_IDS.get(newObject.getId()))
|
||||
{
|
||||
if (shortcut.getWorldLocation() == null)
|
||||
{
|
||||
closestShortcut = shortcut;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int newDistance = shortcut.getWorldLocation().distanceTo2D(newObject.getWorldLocation());
|
||||
if (closestShortcut == null || newDistance < distance)
|
||||
{
|
||||
closestShortcut = shortcut;
|
||||
distance = newDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestShortcut != null)
|
||||
{
|
||||
obstacles.put(newObject, new Obstacle(tile, closestShortcut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (!config.showShortcutLevel())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Guarding against non-first option because agility shortcuts are always that type of event.
|
||||
if (event.getType() != MenuAction.GAME_OBJECT_FIRST_OPTION.getId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int entryId = event.getIdentifier();
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
for (Obstacle nearbyObstacle : getObstacles().values())
|
||||
{
|
||||
AgilityShortcut shortcut = nearbyObstacle.getShortcut();
|
||||
if (shortcut != null && Arrays.stream(shortcut.getObstacleIds()).anyMatch(i -> i == entryId)) {
|
||||
MenuEntry entry = menuEntries[menuEntries.length - 1];
|
||||
int level = shortcut.getLevel();
|
||||
Color color = level <= getAgilityLevel() ? Color.GREEN : Color.RED;
|
||||
String requirementText = " (level-" + level + ")";
|
||||
|
||||
entry.setTarget(event.getTarget() + ColorUtil.prependColorTag(requirementText, color));
|
||||
client.setMenuEntries(menuEntries);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.agility;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemID;
|
||||
import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Skill;
|
||||
import static net.runelite.api.Skill.AGILITY;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.BoostedLevelChanged;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.DecorativeObjectChanged;
|
||||
import net.runelite.api.events.DecorativeObjectDespawned;
|
||||
import net.runelite.api.events.DecorativeObjectSpawned;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameObjectChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GroundObjectChanged;
|
||||
import net.runelite.api.events.GroundObjectDespawned;
|
||||
import net.runelite.api.events.GroundObjectSpawned;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.WallObjectChanged;
|
||||
import net.runelite.api.events.WallObjectDespawned;
|
||||
import net.runelite.api.events.WallObjectSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Agility",
|
||||
description = "Show helpful information about agility courses and obstacles",
|
||||
tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"}
|
||||
)
|
||||
@Slf4j
|
||||
public class AgilityPlugin extends Plugin
|
||||
{
|
||||
private static final int AGILITY_ARENA_REGION_ID = 11157;
|
||||
|
||||
@Getter
|
||||
private final Map<TileObject, Obstacle> obstacles = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private final List<Tile> marksOfGrace = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AgilityOverlay agilityOverlay;
|
||||
|
||||
@Inject
|
||||
private LapCounterOverlay lapCounterOverlay;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private AgilityConfig config;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Getter
|
||||
private AgilitySession session;
|
||||
|
||||
private int lastAgilityXp;
|
||||
private WorldPoint lastArenaTicketPosition;
|
||||
|
||||
@Getter
|
||||
private int agilityLevel;
|
||||
|
||||
@Provides
|
||||
AgilityConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AgilityConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(agilityOverlay);
|
||||
overlayManager.add(lapCounterOverlay);
|
||||
agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(agilityOverlay);
|
||||
overlayManager.remove(lapCounterOverlay);
|
||||
marksOfGrace.clear();
|
||||
obstacles.clear();
|
||||
session = null;
|
||||
agilityLevel = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
switch (event.getGameState())
|
||||
{
|
||||
case HOPPING:
|
||||
case LOGIN_SCREEN:
|
||||
session = null;
|
||||
lastArenaTicketPosition = null;
|
||||
removeAgilityArenaTimer();
|
||||
break;
|
||||
case LOADING:
|
||||
marksOfGrace.clear();
|
||||
obstacles.clear();
|
||||
break;
|
||||
case LOGGED_IN:
|
||||
if (!isInAgilityArena())
|
||||
{
|
||||
lastArenaTicketPosition = null;
|
||||
removeAgilityArenaTimer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!config.showAgilityArenaTimer())
|
||||
{
|
||||
removeAgilityArenaTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event)
|
||||
{
|
||||
if (event.getSkill() != AGILITY || !config.showLapCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine how much EXP was actually gained
|
||||
int agilityXp = client.getSkillExperience(AGILITY);
|
||||
int skillGained = agilityXp - lastAgilityXp;
|
||||
lastAgilityXp = agilityXp;
|
||||
|
||||
// Get course
|
||||
Courses course = Courses.getCourse(client.getLocalPlayer().getWorldLocation().getRegionID());
|
||||
if (course == null
|
||||
|| (course.getCourseEndWorldPoints().length == 0
|
||||
? Math.abs(course.getLastObstacleXp() - skillGained) > 1
|
||||
: Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation()))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (session != null && session.getCourse() == course)
|
||||
{
|
||||
session.incrementLapCount(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
session = new AgilitySession(course);
|
||||
// New course found, reset lap count and set new course
|
||||
session.resetLapCount();
|
||||
session.incrementLapCount(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onBoostedLevelChanged(BoostedLevelChanged boostedLevelChanged)
|
||||
{
|
||||
Skill skill = boostedLevelChanged.getSkill();
|
||||
if (skill == AGILITY)
|
||||
{
|
||||
agilityLevel = client.getBoostedSkillLevel(skill);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
if (obstacles.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Item item = itemSpawned.getItem();
|
||||
final Tile tile = itemSpawned.getTile();
|
||||
|
||||
if (item.getId() == ItemID.MARK_OF_GRACE)
|
||||
{
|
||||
marksOfGrace.add(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemDespawned(ItemDespawned itemDespawned)
|
||||
{
|
||||
final Tile tile = itemDespawned.getTile();
|
||||
marksOfGrace.remove(tile);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
if (isInAgilityArena())
|
||||
{
|
||||
// Hint arrow has no plane, and always returns the current plane
|
||||
WorldPoint newTicketPosition = client.getHintArrowPoint();
|
||||
WorldPoint oldTickPosition = lastArenaTicketPosition;
|
||||
|
||||
lastArenaTicketPosition = newTicketPosition;
|
||||
|
||||
if (oldTickPosition != null && newTicketPosition != null
|
||||
&& (oldTickPosition.getX() != newTicketPosition.getX() || oldTickPosition.getY() != newTicketPosition.getY()))
|
||||
{
|
||||
log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition);
|
||||
|
||||
if (config.notifyAgilityArena())
|
||||
{
|
||||
notifier.notify("Ticket location changed");
|
||||
}
|
||||
|
||||
if (config.showAgilityArenaTimer())
|
||||
{
|
||||
showNewAgilityArenaTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInAgilityArena()
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
if (local == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint location = local.getWorldLocation();
|
||||
return location.getRegionID() == AGILITY_ARENA_REGION_ID;
|
||||
}
|
||||
|
||||
private void removeAgilityArenaTimer()
|
||||
{
|
||||
infoBoxManager.removeIf(infoBox -> infoBox instanceof AgilityArenaTimer);
|
||||
}
|
||||
|
||||
private void showNewAgilityArenaTimer()
|
||||
{
|
||||
removeAgilityArenaTimer();
|
||||
infoBoxManager.addInfoBox(new AgilityArenaTimer(this, itemManager.getImage(AGILITY_ARENA_TICKET)));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getGameObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectChanged(GameObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getGameObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getGameObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGroundObjectSpawned(GroundObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getGroundObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGroundObjectChanged(GroundObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGroundObjectDespawned(GroundObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getGroundObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectSpawned(WallObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getWallObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectChanged(WallObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getWallObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWallObjectDespawned(WallObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getWallObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDecorativeObjectSpawned(DecorativeObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getDecorativeObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDecorativeObjectChanged(DecorativeObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDecorativeObjectDespawned(DecorativeObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getDecorativeObject(), null);
|
||||
}
|
||||
|
||||
private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject)
|
||||
{
|
||||
obstacles.remove(oldObject);
|
||||
|
||||
if (newObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) ||
|
||||
(Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId())
|
||||
&& Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID())))
|
||||
{
|
||||
obstacles.put(newObject, new Obstacle(tile, null));
|
||||
}
|
||||
|
||||
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(newObject.getId()))
|
||||
{
|
||||
AgilityShortcut closestShortcut = null;
|
||||
int distance = -1;
|
||||
|
||||
// Find the closest shortcut to this object
|
||||
for (AgilityShortcut shortcut : Obstacles.SHORTCUT_OBSTACLE_IDS.get(newObject.getId()))
|
||||
{
|
||||
if (shortcut.getWorldLocation() == null)
|
||||
{
|
||||
closestShortcut = shortcut;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int newDistance = shortcut.getWorldLocation().distanceTo2D(newObject.getWorldLocation());
|
||||
if (closestShortcut == null || newDistance < distance)
|
||||
{
|
||||
closestShortcut = shortcut;
|
||||
distance = newDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestShortcut != null)
|
||||
{
|
||||
obstacles.put(newObject, new Obstacle(tile, closestShortcut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (!config.showShortcutLevel())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Guarding against non-first option because agility shortcuts are always that type of event.
|
||||
if (event.getType() != MenuAction.GAME_OBJECT_FIRST_OPTION.getId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int entryId = event.getIdentifier();
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
for (Obstacle nearbyObstacle : getObstacles().values())
|
||||
{
|
||||
AgilityShortcut shortcut = nearbyObstacle.getShortcut();
|
||||
if (shortcut != null && Arrays.stream(shortcut.getObstacleIds()).anyMatch(i -> i == entryId))
|
||||
{
|
||||
MenuEntry entry = menuEntries[menuEntries.length - 1];
|
||||
int level = shortcut.getLevel();
|
||||
Color color = level <= getAgilityLevel() ? Color.GREEN : Color.RED;
|
||||
String requirementText = " (level-" + level + ")";
|
||||
|
||||
entry.setTarget(event.getTarget() + ColorUtil.prependColorTag(requirementText, color));
|
||||
client.setMenuEntries(menuEntries);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,131 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* 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.agility;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import static net.runelite.api.NullObjectID.NULL_10872;
|
||||
import static net.runelite.api.NullObjectID.NULL_10873;
|
||||
import static net.runelite.api.NullObjectID.NULL_12945;
|
||||
import static net.runelite.api.NullObjectID.NULL_18083;
|
||||
import static net.runelite.api.NullObjectID.NULL_18116;
|
||||
import static net.runelite.api.NullObjectID.NULL_18122;
|
||||
import static net.runelite.api.NullObjectID.NULL_18124;
|
||||
import static net.runelite.api.NullObjectID.NULL_18129;
|
||||
import static net.runelite.api.NullObjectID.NULL_18130;
|
||||
import static net.runelite.api.NullObjectID.NULL_18132;
|
||||
import static net.runelite.api.NullObjectID.NULL_18133;
|
||||
import static net.runelite.api.NullObjectID.NULL_18135;
|
||||
import static net.runelite.api.NullObjectID.NULL_18136;
|
||||
import static net.runelite.api.NullObjectID.NULL_3550;
|
||||
import static net.runelite.api.ObjectID.*;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
|
||||
class Obstacles
|
||||
{
|
||||
static final Set<Integer> COURSE_OBSTACLE_IDS = ImmutableSet.of(
|
||||
// Gnome
|
||||
OBSTACLE_NET_23134, TREE_BRANCH_23559, TREE_BRANCH_23560, OBSTACLE_NET_23135, OBSTACLE_PIPE_23138,
|
||||
OBSTACLE_PIPE_23139, LOG_BALANCE_23145, BALANCING_ROPE_23557,
|
||||
// Brimhaven
|
||||
PLANK_3572, PLANK_3571, PLANK_3570, ROPE_SWING, PILLAR_3578, LOW_WALL, LOG_BALANCE, LOG_BALANCE_3557,
|
||||
BALANCING_LEDGE_3561, BALANCING_LEDGE, MONKEY_BARS_3564, BALANCING_ROPE, HAND_HOLDS_3583,
|
||||
// Draynor
|
||||
ROUGH_WALL, TIGHTROPE, TIGHTROPE_10075, NARROW_WALL, WALL_10084, GAP_10085, CRATE_10086, STILE_7527,
|
||||
// Al-Kharid
|
||||
ROUGH_WALL_10093, TIGHTROPE_10284, CABLE, ZIP_LINE, TROPICAL_TREE_10357, ROOF_TOP_BEAMS,
|
||||
TIGHTROPE_10583, GAP_10352,
|
||||
// Pyramid
|
||||
STAIRS_10857, LOW_WALL_10865, LEDGE_10860, PLANK_10868, GAP_10882, LEDGE_10886, STAIRS_10857, GAP_10884,
|
||||
GAP_10859, GAP_10861, LOW_WALL_10865, GAP_10859, LEDGE_10888, PLANK_10868, CLIMBING_ROCKS_10851, DOORWAY_10855,
|
||||
// Varrock
|
||||
ROUGH_WALL_10586, CLOTHES_LINE, GAP_10642, WALL_10777, GAP_10778, GAP_10779, GAP_10780, LEDGE_10781, EDGE,
|
||||
// Penguin
|
||||
STEPPING_STONE_21120, STEPPING_STONE_21126, STEPPING_STONE_21128, STEPPING_STONE_21129,
|
||||
STEPPING_STONE_21130, STEPPING_STONE_21131, STEPPING_STONE_21132, STEPPING_STONE_21133,
|
||||
ICICLES, ICE, ICE_21149, ICE_21150, ICE_21151, ICE_21152, ICE_21153, ICE_21154, ICE_21155, ICE_21156,
|
||||
// Barbarian
|
||||
ROPESWING_23131, LOG_BALANCE_23144, OBSTACLE_NET_20211, BALANCING_LEDGE_23547, LADDER_16682, CRUMBLING_WALL_1948,
|
||||
// Canifis
|
||||
TALL_TREE_10819, GAP_10820, GAP_10821, GAP_10828, GAP_10822, POLEVAULT, GAP_10823, GAP_10832,
|
||||
// Ape atoll
|
||||
STEPPING_STONE_15412, TROPICAL_TREE_15414, MONKEYBARS_15417, SKULL_SLOPE_15483, ROPE_15487, TROPICAL_TREE_16062,
|
||||
// Falador
|
||||
ROUGH_WALL_10833, TIGHTROPE_10834, HAND_HOLDS_10836, GAP_11161, GAP_11360, TIGHTROPE_11361,
|
||||
TIGHTROPE_11364, GAP_11365, LEDGE_11366, LEDGE_11367, LEDGE_11369, LEDGE_11370, EDGE_11371,
|
||||
// Wilderness
|
||||
OBSTACLE_PIPE_23137, ROPESWING_23132, STEPPING_STONE_23556, LOG_BALANCE_23542, ROCKS_23640,
|
||||
// Seers
|
||||
WALL_11373, GAP_11374, TIGHTROPE_11378, GAP_11375, GAP_11376, EDGE_11377,
|
||||
// Dorgesh-Kaan
|
||||
CABLE_22569, CABLE_22572, LADDER_22564, JUTTING_WALL_22552, TUNNEL_22557, PYLON_22664,
|
||||
CONSOLE, BOILER_22635, STAIRS_22650, STAIRS_22651, STAIRS_22609, STAIRS_22608,
|
||||
// Pollniveach
|
||||
BASKET_11380, MARKET_STALL_11381, BANNER_11382, GAP_11383, TREE_11384, ROUGH_WALL_11385,
|
||||
MONKEYBARS, TREE_11389, DRYING_LINE,
|
||||
// Rellaka
|
||||
ROUGH_WALL_11391, GAP_11392, TIGHTROPE_11393, GAP_11395, GAP_11396, TIGHTROPE_11397, PILE_OF_FISH,
|
||||
// Ardougne
|
||||
GAP_11406, GAP_11429, GAP_11430, STEEP_ROOF, GAP_11630, PLANK_11631, WOODEN_BEAMS,
|
||||
// Meiyerditch
|
||||
NULL_12945, ROCK_17958, ROCK_17959, ROCK_17960, BOAT_17961, NULL_18122, NULL_18124, WALL_RUBBLE,
|
||||
WALL_RUBBLE_18038, FLOORBOARDS, FLOORBOARDS_18071, FLOORBOARDS_18072, FLOORBOARDS_18073, NULL_18129, NULL_18130,
|
||||
WALL_18078, NULL_18132, NULL_18133, NULL_18083, TUNNEL_18085, SHELF_18086, SHELF_18087, WALL_18088,
|
||||
FLOORBOARDS_18089, FLOORBOARDS_18090, DOOR_18091, FLOORBOARDS_18093, FLOORBOARDS_18094, SHELF_18095,
|
||||
SHELF_18096, FLOORBOARDS_18097, FLOORBOARDS_18098, WASHING_LINE_18099, WASHING_LINE_18100,
|
||||
NULL_18135, NULL_18136, SHELF_18105, SHELF_18106, SHELF_18107, SHELF_18108, FLOORBOARDS_18109,
|
||||
FLOORBOARDS_18110, FLOORBOARDS_18112, FLOORBOARDS_18111, FLOORBOARDS_18114, FLOORBOARDS_18113,
|
||||
NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980,
|
||||
// Werewolf
|
||||
STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE_11644,
|
||||
ZIP_LINE_11645, ZIP_LINE_11646
|
||||
);
|
||||
|
||||
static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS;
|
||||
|
||||
static final Set<Integer> TRAP_OBSTACLE_IDS = ImmutableSet.of(
|
||||
// Agility pyramid
|
||||
NULL_3550, NULL_10872, NULL_10873
|
||||
);
|
||||
|
||||
static final List<Integer> TRAP_OBSTACLE_REGIONS = ImmutableList.of(12105, 13356);
|
||||
|
||||
static
|
||||
{
|
||||
final ImmutableMultimap.Builder<Integer, AgilityShortcut> builder = ImmutableMultimap.builder();
|
||||
for (final AgilityShortcut item : AgilityShortcut.values())
|
||||
{
|
||||
for (int obstacle : item.getObstacleIds())
|
||||
{
|
||||
builder.put(obstacle, item);
|
||||
}
|
||||
}
|
||||
SHORTCUT_OBSTACLE_IDS = builder.build();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* 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.agility;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import static net.runelite.api.NullObjectID.NULL_10872;
|
||||
import static net.runelite.api.NullObjectID.NULL_10873;
|
||||
import static net.runelite.api.NullObjectID.NULL_12945;
|
||||
import static net.runelite.api.NullObjectID.NULL_18083;
|
||||
import static net.runelite.api.NullObjectID.NULL_18116;
|
||||
import static net.runelite.api.NullObjectID.NULL_18122;
|
||||
import static net.runelite.api.NullObjectID.NULL_18124;
|
||||
import static net.runelite.api.NullObjectID.NULL_18129;
|
||||
import static net.runelite.api.NullObjectID.NULL_18130;
|
||||
import static net.runelite.api.NullObjectID.NULL_18132;
|
||||
import static net.runelite.api.NullObjectID.NULL_18133;
|
||||
import static net.runelite.api.NullObjectID.NULL_18135;
|
||||
import static net.runelite.api.NullObjectID.NULL_18136;
|
||||
import static net.runelite.api.NullObjectID.NULL_3550;
|
||||
import static net.runelite.api.ObjectID.BALANCING_LEDGE;
|
||||
import static net.runelite.api.ObjectID.BALANCING_LEDGE_23547;
|
||||
import static net.runelite.api.ObjectID.BALANCING_LEDGE_3561;
|
||||
import static net.runelite.api.ObjectID.BALANCING_ROPE;
|
||||
import static net.runelite.api.ObjectID.BALANCING_ROPE_23557;
|
||||
import static net.runelite.api.ObjectID.BANNER_11382;
|
||||
import static net.runelite.api.ObjectID.BASKET_11380;
|
||||
import static net.runelite.api.ObjectID.BOAT_17961;
|
||||
import static net.runelite.api.ObjectID.BOILER_22635;
|
||||
import static net.runelite.api.ObjectID.CABLE;
|
||||
import static net.runelite.api.ObjectID.CABLE_22569;
|
||||
import static net.runelite.api.ObjectID.CABLE_22572;
|
||||
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_10851;
|
||||
import static net.runelite.api.ObjectID.CLOTHES_LINE;
|
||||
import static net.runelite.api.ObjectID.CONSOLE;
|
||||
import static net.runelite.api.ObjectID.CRATE_10086;
|
||||
import static net.runelite.api.ObjectID.CRUMBLING_WALL_1948;
|
||||
import static net.runelite.api.ObjectID.DOORWAY_10855;
|
||||
import static net.runelite.api.ObjectID.DOOR_18091;
|
||||
import static net.runelite.api.ObjectID.DRYING_LINE;
|
||||
import static net.runelite.api.ObjectID.EDGE;
|
||||
import static net.runelite.api.ObjectID.EDGE_11371;
|
||||
import static net.runelite.api.ObjectID.EDGE_11377;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18071;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18072;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18073;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18089;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18090;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18093;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18094;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18097;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18098;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18109;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18110;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18111;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18112;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18113;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18114;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18117;
|
||||
import static net.runelite.api.ObjectID.FLOORBOARDS_18118;
|
||||
import static net.runelite.api.ObjectID.GAP_10085;
|
||||
import static net.runelite.api.ObjectID.GAP_10352;
|
||||
import static net.runelite.api.ObjectID.GAP_10642;
|
||||
import static net.runelite.api.ObjectID.GAP_10778;
|
||||
import static net.runelite.api.ObjectID.GAP_10779;
|
||||
import static net.runelite.api.ObjectID.GAP_10780;
|
||||
import static net.runelite.api.ObjectID.GAP_10820;
|
||||
import static net.runelite.api.ObjectID.GAP_10821;
|
||||
import static net.runelite.api.ObjectID.GAP_10822;
|
||||
import static net.runelite.api.ObjectID.GAP_10823;
|
||||
import static net.runelite.api.ObjectID.GAP_10828;
|
||||
import static net.runelite.api.ObjectID.GAP_10832;
|
||||
import static net.runelite.api.ObjectID.GAP_10859;
|
||||
import static net.runelite.api.ObjectID.GAP_10861;
|
||||
import static net.runelite.api.ObjectID.GAP_10882;
|
||||
import static net.runelite.api.ObjectID.GAP_10884;
|
||||
import static net.runelite.api.ObjectID.GAP_11161;
|
||||
import static net.runelite.api.ObjectID.GAP_11360;
|
||||
import static net.runelite.api.ObjectID.GAP_11365;
|
||||
import static net.runelite.api.ObjectID.GAP_11374;
|
||||
import static net.runelite.api.ObjectID.GAP_11375;
|
||||
import static net.runelite.api.ObjectID.GAP_11376;
|
||||
import static net.runelite.api.ObjectID.GAP_11383;
|
||||
import static net.runelite.api.ObjectID.GAP_11392;
|
||||
import static net.runelite.api.ObjectID.GAP_11395;
|
||||
import static net.runelite.api.ObjectID.GAP_11396;
|
||||
import static net.runelite.api.ObjectID.GAP_11406;
|
||||
import static net.runelite.api.ObjectID.GAP_11429;
|
||||
import static net.runelite.api.ObjectID.GAP_11430;
|
||||
import static net.runelite.api.ObjectID.GAP_11630;
|
||||
import static net.runelite.api.ObjectID.HAND_HOLDS_10836;
|
||||
import static net.runelite.api.ObjectID.HAND_HOLDS_3583;
|
||||
import static net.runelite.api.ObjectID.HURDLE;
|
||||
import static net.runelite.api.ObjectID.HURDLE_11639;
|
||||
import static net.runelite.api.ObjectID.HURDLE_11640;
|
||||
import static net.runelite.api.ObjectID.ICE;
|
||||
import static net.runelite.api.ObjectID.ICE_21149;
|
||||
import static net.runelite.api.ObjectID.ICE_21150;
|
||||
import static net.runelite.api.ObjectID.ICE_21151;
|
||||
import static net.runelite.api.ObjectID.ICE_21152;
|
||||
import static net.runelite.api.ObjectID.ICE_21153;
|
||||
import static net.runelite.api.ObjectID.ICE_21154;
|
||||
import static net.runelite.api.ObjectID.ICE_21155;
|
||||
import static net.runelite.api.ObjectID.ICE_21156;
|
||||
import static net.runelite.api.ObjectID.ICICLES;
|
||||
import static net.runelite.api.ObjectID.JUTTING_WALL_22552;
|
||||
import static net.runelite.api.ObjectID.LADDER_16682;
|
||||
import static net.runelite.api.ObjectID.LADDER_22564;
|
||||
import static net.runelite.api.ObjectID.LEDGE_10781;
|
||||
import static net.runelite.api.ObjectID.LEDGE_10860;
|
||||
import static net.runelite.api.ObjectID.LEDGE_10886;
|
||||
import static net.runelite.api.ObjectID.LEDGE_10888;
|
||||
import static net.runelite.api.ObjectID.LEDGE_11366;
|
||||
import static net.runelite.api.ObjectID.LEDGE_11367;
|
||||
import static net.runelite.api.ObjectID.LEDGE_11369;
|
||||
import static net.runelite.api.ObjectID.LEDGE_11370;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_23144;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_23145;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_23542;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_3557;
|
||||
import static net.runelite.api.ObjectID.LOW_WALL;
|
||||
import static net.runelite.api.ObjectID.LOW_WALL_10865;
|
||||
import static net.runelite.api.ObjectID.MARKET_STALL_11381;
|
||||
import static net.runelite.api.ObjectID.MONKEYBARS;
|
||||
import static net.runelite.api.ObjectID.MONKEYBARS_15417;
|
||||
import static net.runelite.api.ObjectID.MONKEY_BARS_3564;
|
||||
import static net.runelite.api.ObjectID.NARROW_WALL;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_NET_20211;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_NET_23134;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_NET_23135;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23137;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23138;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23139;
|
||||
import static net.runelite.api.ObjectID.PILE_OF_FISH;
|
||||
import static net.runelite.api.ObjectID.PILLAR_3578;
|
||||
import static net.runelite.api.ObjectID.PIPE_11657;
|
||||
import static net.runelite.api.ObjectID.PLANK_10868;
|
||||
import static net.runelite.api.ObjectID.PLANK_11631;
|
||||
import static net.runelite.api.ObjectID.PLANK_3570;
|
||||
import static net.runelite.api.ObjectID.PLANK_3571;
|
||||
import static net.runelite.api.ObjectID.PLANK_3572;
|
||||
import static net.runelite.api.ObjectID.POLEVAULT;
|
||||
import static net.runelite.api.ObjectID.PYLON_22664;
|
||||
import static net.runelite.api.ObjectID.ROCKS_23640;
|
||||
import static net.runelite.api.ObjectID.ROCK_17958;
|
||||
import static net.runelite.api.ObjectID.ROCK_17959;
|
||||
import static net.runelite.api.ObjectID.ROCK_17960;
|
||||
import static net.runelite.api.ObjectID.ROOF_TOP_BEAMS;
|
||||
import static net.runelite.api.ObjectID.ROPESWING_23131;
|
||||
import static net.runelite.api.ObjectID.ROPESWING_23132;
|
||||
import static net.runelite.api.ObjectID.ROPE_15487;
|
||||
import static net.runelite.api.ObjectID.ROPE_SWING;
|
||||
import static net.runelite.api.ObjectID.ROUGH_WALL;
|
||||
import static net.runelite.api.ObjectID.ROUGH_WALL_10093;
|
||||
import static net.runelite.api.ObjectID.ROUGH_WALL_10586;
|
||||
import static net.runelite.api.ObjectID.ROUGH_WALL_10833;
|
||||
import static net.runelite.api.ObjectID.ROUGH_WALL_11385;
|
||||
import static net.runelite.api.ObjectID.ROUGH_WALL_11391;
|
||||
import static net.runelite.api.ObjectID.SHELF_18086;
|
||||
import static net.runelite.api.ObjectID.SHELF_18087;
|
||||
import static net.runelite.api.ObjectID.SHELF_18095;
|
||||
import static net.runelite.api.ObjectID.SHELF_18096;
|
||||
import static net.runelite.api.ObjectID.SHELF_18105;
|
||||
import static net.runelite.api.ObjectID.SHELF_18106;
|
||||
import static net.runelite.api.ObjectID.SHELF_18107;
|
||||
import static net.runelite.api.ObjectID.SHELF_18108;
|
||||
import static net.runelite.api.ObjectID.SKULL_SLOPE;
|
||||
import static net.runelite.api.ObjectID.SKULL_SLOPE_15483;
|
||||
import static net.runelite.api.ObjectID.STAIRS_10857;
|
||||
import static net.runelite.api.ObjectID.STAIRS_22608;
|
||||
import static net.runelite.api.ObjectID.STAIRS_22609;
|
||||
import static net.runelite.api.ObjectID.STAIRS_22650;
|
||||
import static net.runelite.api.ObjectID.STAIRS_22651;
|
||||
import static net.runelite.api.ObjectID.STAIRS_DOWN;
|
||||
import static net.runelite.api.ObjectID.STEEP_ROOF;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_11643;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_15412;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21120;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21126;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21128;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21129;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21130;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21131;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21132;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21133;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_23556;
|
||||
import static net.runelite.api.ObjectID.STILE_7527;
|
||||
import static net.runelite.api.ObjectID.TALL_TREE_10819;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_10075;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_10284;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_10583;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_10834;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_11361;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_11364;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_11378;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_11393;
|
||||
import static net.runelite.api.ObjectID.TIGHTROPE_11397;
|
||||
import static net.runelite.api.ObjectID.TREE_11384;
|
||||
import static net.runelite.api.ObjectID.TREE_11389;
|
||||
import static net.runelite.api.ObjectID.TREE_BRANCH_23559;
|
||||
import static net.runelite.api.ObjectID.TREE_BRANCH_23560;
|
||||
import static net.runelite.api.ObjectID.TROPICAL_TREE_10357;
|
||||
import static net.runelite.api.ObjectID.TROPICAL_TREE_15414;
|
||||
import static net.runelite.api.ObjectID.TROPICAL_TREE_16062;
|
||||
import static net.runelite.api.ObjectID.TUNNEL_18085;
|
||||
import static net.runelite.api.ObjectID.TUNNEL_22557;
|
||||
import static net.runelite.api.ObjectID.WALL_10084;
|
||||
import static net.runelite.api.ObjectID.WALL_10777;
|
||||
import static net.runelite.api.ObjectID.WALL_11373;
|
||||
import static net.runelite.api.ObjectID.WALL_17980;
|
||||
import static net.runelite.api.ObjectID.WALL_18078;
|
||||
import static net.runelite.api.ObjectID.WALL_18088;
|
||||
import static net.runelite.api.ObjectID.WALL_RUBBLE;
|
||||
import static net.runelite.api.ObjectID.WALL_RUBBLE_18038;
|
||||
import static net.runelite.api.ObjectID.WASHING_LINE_18099;
|
||||
import static net.runelite.api.ObjectID.WASHING_LINE_18100;
|
||||
import static net.runelite.api.ObjectID.WOODEN_BEAMS;
|
||||
import static net.runelite.api.ObjectID.ZIP_LINE;
|
||||
import static net.runelite.api.ObjectID.ZIP_LINE_11644;
|
||||
import static net.runelite.api.ObjectID.ZIP_LINE_11645;
|
||||
import static net.runelite.api.ObjectID.ZIP_LINE_11646;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
|
||||
class Obstacles
|
||||
{
|
||||
static final Set<Integer> COURSE_OBSTACLE_IDS = ImmutableSet.of(
|
||||
// Gnome
|
||||
OBSTACLE_NET_23134, TREE_BRANCH_23559, TREE_BRANCH_23560, OBSTACLE_NET_23135, OBSTACLE_PIPE_23138,
|
||||
OBSTACLE_PIPE_23139, LOG_BALANCE_23145, BALANCING_ROPE_23557,
|
||||
// Brimhaven
|
||||
PLANK_3572, PLANK_3571, PLANK_3570, ROPE_SWING, PILLAR_3578, LOW_WALL, LOG_BALANCE, LOG_BALANCE_3557,
|
||||
BALANCING_LEDGE_3561, BALANCING_LEDGE, MONKEY_BARS_3564, BALANCING_ROPE, HAND_HOLDS_3583,
|
||||
// Draynor
|
||||
ROUGH_WALL, TIGHTROPE, TIGHTROPE_10075, NARROW_WALL, WALL_10084, GAP_10085, CRATE_10086, STILE_7527,
|
||||
// Al-Kharid
|
||||
ROUGH_WALL_10093, TIGHTROPE_10284, CABLE, ZIP_LINE, TROPICAL_TREE_10357, ROOF_TOP_BEAMS,
|
||||
TIGHTROPE_10583, GAP_10352,
|
||||
// Pyramid
|
||||
STAIRS_10857, LOW_WALL_10865, LEDGE_10860, PLANK_10868, GAP_10882, LEDGE_10886, STAIRS_10857, GAP_10884,
|
||||
GAP_10859, GAP_10861, LOW_WALL_10865, GAP_10859, LEDGE_10888, PLANK_10868, CLIMBING_ROCKS_10851, DOORWAY_10855,
|
||||
// Varrock
|
||||
ROUGH_WALL_10586, CLOTHES_LINE, GAP_10642, WALL_10777, GAP_10778, GAP_10779, GAP_10780, LEDGE_10781, EDGE,
|
||||
// Penguin
|
||||
STEPPING_STONE_21120, STEPPING_STONE_21126, STEPPING_STONE_21128, STEPPING_STONE_21129,
|
||||
STEPPING_STONE_21130, STEPPING_STONE_21131, STEPPING_STONE_21132, STEPPING_STONE_21133,
|
||||
ICICLES, ICE, ICE_21149, ICE_21150, ICE_21151, ICE_21152, ICE_21153, ICE_21154, ICE_21155, ICE_21156,
|
||||
// Barbarian
|
||||
ROPESWING_23131, LOG_BALANCE_23144, OBSTACLE_NET_20211, BALANCING_LEDGE_23547, LADDER_16682, CRUMBLING_WALL_1948,
|
||||
// Canifis
|
||||
TALL_TREE_10819, GAP_10820, GAP_10821, GAP_10828, GAP_10822, POLEVAULT, GAP_10823, GAP_10832,
|
||||
// Ape atoll
|
||||
STEPPING_STONE_15412, TROPICAL_TREE_15414, MONKEYBARS_15417, SKULL_SLOPE_15483, ROPE_15487, TROPICAL_TREE_16062,
|
||||
// Falador
|
||||
ROUGH_WALL_10833, TIGHTROPE_10834, HAND_HOLDS_10836, GAP_11161, GAP_11360, TIGHTROPE_11361,
|
||||
TIGHTROPE_11364, GAP_11365, LEDGE_11366, LEDGE_11367, LEDGE_11369, LEDGE_11370, EDGE_11371,
|
||||
// Wilderness
|
||||
OBSTACLE_PIPE_23137, ROPESWING_23132, STEPPING_STONE_23556, LOG_BALANCE_23542, ROCKS_23640,
|
||||
// Seers
|
||||
WALL_11373, GAP_11374, TIGHTROPE_11378, GAP_11375, GAP_11376, EDGE_11377,
|
||||
// Dorgesh-Kaan
|
||||
CABLE_22569, CABLE_22572, LADDER_22564, JUTTING_WALL_22552, TUNNEL_22557, PYLON_22664,
|
||||
CONSOLE, BOILER_22635, STAIRS_22650, STAIRS_22651, STAIRS_22609, STAIRS_22608,
|
||||
// Pollniveach
|
||||
BASKET_11380, MARKET_STALL_11381, BANNER_11382, GAP_11383, TREE_11384, ROUGH_WALL_11385,
|
||||
MONKEYBARS, TREE_11389, DRYING_LINE,
|
||||
// Rellaka
|
||||
ROUGH_WALL_11391, GAP_11392, TIGHTROPE_11393, GAP_11395, GAP_11396, TIGHTROPE_11397, PILE_OF_FISH,
|
||||
// Ardougne
|
||||
GAP_11406, GAP_11429, GAP_11430, STEEP_ROOF, GAP_11630, PLANK_11631, WOODEN_BEAMS,
|
||||
// Meiyerditch
|
||||
NULL_12945, ROCK_17958, ROCK_17959, ROCK_17960, BOAT_17961, NULL_18122, NULL_18124, WALL_RUBBLE,
|
||||
WALL_RUBBLE_18038, FLOORBOARDS, FLOORBOARDS_18071, FLOORBOARDS_18072, FLOORBOARDS_18073, NULL_18129, NULL_18130,
|
||||
WALL_18078, NULL_18132, NULL_18133, NULL_18083, TUNNEL_18085, SHELF_18086, SHELF_18087, WALL_18088,
|
||||
FLOORBOARDS_18089, FLOORBOARDS_18090, DOOR_18091, FLOORBOARDS_18093, FLOORBOARDS_18094, SHELF_18095,
|
||||
SHELF_18096, FLOORBOARDS_18097, FLOORBOARDS_18098, WASHING_LINE_18099, WASHING_LINE_18100,
|
||||
NULL_18135, NULL_18136, SHELF_18105, SHELF_18106, SHELF_18107, SHELF_18108, FLOORBOARDS_18109,
|
||||
FLOORBOARDS_18110, FLOORBOARDS_18112, FLOORBOARDS_18111, FLOORBOARDS_18114, FLOORBOARDS_18113,
|
||||
NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980,
|
||||
// Werewolf
|
||||
STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE_11644,
|
||||
ZIP_LINE_11645, ZIP_LINE_11646
|
||||
);
|
||||
|
||||
static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS;
|
||||
|
||||
static final Set<Integer> TRAP_OBSTACLE_IDS = ImmutableSet.of(
|
||||
// Agility pyramid
|
||||
NULL_3550, NULL_10872, NULL_10873
|
||||
);
|
||||
|
||||
static final List<Integer> TRAP_OBSTACLE_REGIONS = ImmutableList.of(12105, 13356);
|
||||
|
||||
static
|
||||
{
|
||||
final ImmutableMultimap.Builder<Integer, AgilityShortcut> builder = ImmutableMultimap.builder();
|
||||
for (final AgilityShortcut item : AgilityShortcut.values())
|
||||
{
|
||||
for (int obstacle : item.getObstacleIds())
|
||||
{
|
||||
builder.put(obstacle, item);
|
||||
}
|
||||
}
|
||||
SHORTCUT_OBSTACLE_IDS = builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,71 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
enum HydraPhase
|
||||
{ // Sorry for the autism
|
||||
ONE (3, AnimationID.HYDRA_1_1, AnimationID.HYDRA_1_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, new WorldPoint(1371, 10263, 0)),
|
||||
TWO (3, AnimationID.HYDRA_2_1, AnimationID.HYDRA_2_2, 0, AnimationID.HYDRA_LIGHTNING, SpriteID.BIG_SPEC_TRANSFER, new WorldPoint(1371, 10272, 0)),
|
||||
THREE (3, AnimationID.HYDRA_3_1, AnimationID.HYDRA_3_2, 0, AnimationID.HYDRA_FIRE, SpriteID.BIG_SUPERHEAT, new WorldPoint(1362, 10272, 0)),
|
||||
FOUR (1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
|
||||
|
||||
@Getter
|
||||
private final int attacksPerSwitch;
|
||||
|
||||
@Getter
|
||||
private final int deathAnim1;
|
||||
|
||||
@Getter
|
||||
private final int deathAnim2;
|
||||
|
||||
@Getter
|
||||
private final int specProjectileId;
|
||||
|
||||
@Getter
|
||||
private final int specAnimationId;
|
||||
|
||||
@Getter
|
||||
private final int specImage;
|
||||
|
||||
@Getter
|
||||
private WorldPoint fountain;
|
||||
|
||||
HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain)
|
||||
{
|
||||
this.attacksPerSwitch = attacksPerSwitch;
|
||||
this.deathAnim1 = deathAnim1;
|
||||
this.deathAnim2 = deathAnim2;
|
||||
this.specProjectileId = specProjectileId;
|
||||
this.specAnimationId = specAnimationId;
|
||||
this.specImage = specImage;
|
||||
this.fountain = fountain;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
enum HydraPhase
|
||||
{ // Sorry for the autism
|
||||
ONE(3, AnimationID.HYDRA_1_1, AnimationID.HYDRA_1_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, new WorldPoint(1371, 10263, 0)),
|
||||
TWO(3, AnimationID.HYDRA_2_1, AnimationID.HYDRA_2_2, 0, AnimationID.HYDRA_LIGHTNING, SpriteID.BIG_SPEC_TRANSFER, new WorldPoint(1371, 10272, 0)),
|
||||
THREE(3, AnimationID.HYDRA_3_1, AnimationID.HYDRA_3_2, 0, AnimationID.HYDRA_FIRE, SpriteID.BIG_SUPERHEAT, new WorldPoint(1362, 10272, 0)),
|
||||
FOUR(1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
|
||||
|
||||
@Getter
|
||||
private final int attacksPerSwitch;
|
||||
|
||||
@Getter
|
||||
private final int deathAnim1;
|
||||
|
||||
@Getter
|
||||
private final int deathAnim2;
|
||||
|
||||
@Getter
|
||||
private final int specProjectileId;
|
||||
|
||||
@Getter
|
||||
private final int specAnimationId;
|
||||
|
||||
@Getter
|
||||
private final int specImage;
|
||||
|
||||
@Getter
|
||||
private WorldPoint fountain;
|
||||
|
||||
HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain)
|
||||
{
|
||||
this.attacksPerSwitch = attacksPerSwitch;
|
||||
this.deathAnim1 = deathAnim1;
|
||||
this.deathAnim2 = deathAnim2;
|
||||
this.specProjectileId = specProjectileId;
|
||||
this.specAnimationId = specAnimationId;
|
||||
this.specImage = specImage;
|
||||
this.fountain = fountain;
|
||||
}
|
||||
}
|
||||
@@ -117,9 +117,9 @@ public class HydraPlugin extends Plugin
|
||||
{
|
||||
|
||||
if (hydra != null)
|
||||
{
|
||||
removeOverlays();
|
||||
hydra = null;
|
||||
{
|
||||
removeOverlays();
|
||||
hydra = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -305,8 +305,8 @@ public class HydraPlugin extends Plugin
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra.setNextSwitch(hydra.getNextSwitch() - 1);
|
||||
hydra.setLastAttack(hydra.getNextAttack());
|
||||
hydra.setNextSwitch(hydra.getNextSwitch() - 1);
|
||||
hydra.setLastAttack(hydra.getNextAttack());
|
||||
}
|
||||
|
||||
hydra.setAttackCount(hydra.getAttackCount() + 1);
|
||||
|
||||
@@ -1,145 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Perspective.getCanvasTileAreaPoly;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldArea;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@Singleton
|
||||
class HydraPoisonOverlay extends Overlay
|
||||
{
|
||||
private final HydraPlugin plugin;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public HydraPoisonOverlay(Client client, HydraPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Hydra hydra = plugin.getHydra();
|
||||
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles();
|
||||
|
||||
if (!poisonProjectiles.isEmpty())
|
||||
{
|
||||
drawPoisonArea(graphics, poisonProjectiles);
|
||||
}
|
||||
|
||||
if (hydra.getPhase().getFountain() != null)
|
||||
{
|
||||
drawFountain(graphics, hydra);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawPoisonArea(Graphics2D graphics, Map<LocalPoint, Projectile> poisonProjectiles)
|
||||
{
|
||||
Area poisonTiles = new Area();
|
||||
|
||||
for (Map.Entry<LocalPoint, Projectile> entry : poisonProjectiles.entrySet())
|
||||
{
|
||||
if (entry.getValue().getEndCycle() < client.getGameCycle())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint point = entry.getKey();
|
||||
Polygon poly = getCanvasTileAreaPoly(client, point, 3);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
poisonTiles.add(new Area(poly));
|
||||
}
|
||||
}
|
||||
|
||||
graphics.setPaintMode();
|
||||
graphics.setColor(new Color(255, 0, 0, 100));
|
||||
graphics.draw(poisonTiles);
|
||||
graphics.setColor(new Color(255, 0, 0, 50));
|
||||
graphics.fill(poisonTiles);
|
||||
}
|
||||
|
||||
private void drawFountain(Graphics2D graphics, Hydra hydra)
|
||||
{
|
||||
Collection<WorldPoint> fountainWorldPoint = WorldPoint.toLocalInstance(client, hydra.getPhase().getFountain()); // thanks
|
||||
if (fountainWorldPoint.size() > 1) // for
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPoint wp = null;
|
||||
for (WorldPoint p : fountainWorldPoint) // this
|
||||
{
|
||||
wp = p;
|
||||
}
|
||||
|
||||
LocalPoint fountainPoint = wp == null ? null : LocalPoint.fromWorld(client, wp); // trash
|
||||
|
||||
if (fountainPoint == null || hydra.isWeakened()) // I
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Polygon poly = getCanvasTileAreaPoly(client, fountainPoint, 3); // don't
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = new Color(255, 0, 0, 100); // like
|
||||
|
||||
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
|
||||
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
|
||||
color = new Color(0, 255, 0, 100);
|
||||
}
|
||||
|
||||
graphics.setColor(color);
|
||||
graphics.draw(poly);
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Perspective.getCanvasTileAreaPoly;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldArea;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@Singleton
|
||||
class HydraPoisonOverlay extends Overlay
|
||||
{
|
||||
private final HydraPlugin plugin;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public HydraPoisonOverlay(Client client, HydraPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Hydra hydra = plugin.getHydra();
|
||||
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles();
|
||||
|
||||
if (!poisonProjectiles.isEmpty())
|
||||
{
|
||||
drawPoisonArea(graphics, poisonProjectiles);
|
||||
}
|
||||
|
||||
if (hydra.getPhase().getFountain() != null)
|
||||
{
|
||||
drawFountain(graphics, hydra);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawPoisonArea(Graphics2D graphics, Map<LocalPoint, Projectile> poisonProjectiles)
|
||||
{
|
||||
Area poisonTiles = new Area();
|
||||
|
||||
for (Map.Entry<LocalPoint, Projectile> entry : poisonProjectiles.entrySet())
|
||||
{
|
||||
if (entry.getValue().getEndCycle() < client.getGameCycle())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint point = entry.getKey();
|
||||
Polygon poly = getCanvasTileAreaPoly(client, point, 3);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
poisonTiles.add(new Area(poly));
|
||||
}
|
||||
}
|
||||
|
||||
graphics.setPaintMode();
|
||||
graphics.setColor(new Color(255, 0, 0, 100));
|
||||
graphics.draw(poisonTiles);
|
||||
graphics.setColor(new Color(255, 0, 0, 50));
|
||||
graphics.fill(poisonTiles);
|
||||
}
|
||||
|
||||
private void drawFountain(Graphics2D graphics, Hydra hydra)
|
||||
{
|
||||
Collection<WorldPoint> fountainWorldPoint = WorldPoint.toLocalInstance(client, hydra.getPhase().getFountain()); // thanks
|
||||
if (fountainWorldPoint.size() > 1) // for
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPoint wp = null;
|
||||
for (WorldPoint p : fountainWorldPoint) // this
|
||||
{
|
||||
wp = p;
|
||||
}
|
||||
|
||||
LocalPoint fountainPoint = wp == null ? null : LocalPoint.fromWorld(client, wp); // trash
|
||||
|
||||
if (fountainPoint == null || hydra.isWeakened()) // I
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Polygon poly = getCanvasTileAreaPoly(client, fountainPoint, 3); // don't
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = new Color(255, 0, 0, 100); // like
|
||||
|
||||
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
|
||||
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
|
||||
color = new Color(0, 255, 0, 100);
|
||||
}
|
||||
|
||||
graphics.setColor(color);
|
||||
graphics.draw(poly);
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,8 @@ package net.runelite.client.plugins.antidrag;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.KeyEvent;
|
||||
import net.runelite.client.config.Alpha;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.client.config.Alpha;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@@ -32,7 +32,6 @@ import java.util.Map;
|
||||
import net.runelite.api.ProjectileID;
|
||||
|
||||
|
||||
|
||||
public enum AoeProjectileInfo
|
||||
{
|
||||
LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 5),
|
||||
@@ -108,10 +107,10 @@ public enum AoeProjectileInfo
|
||||
ADDY_DRAG_POISON(ProjectileID.ADDY_DRAG_POISON, 1),
|
||||
|
||||
/**
|
||||
* the Breath of the Drake
|
||||
*/
|
||||
* the Breath of the Drake
|
||||
*/
|
||||
DRAKE_BREATH(ProjectileID.DRAKE_BREATH, 1),
|
||||
|
||||
|
||||
/**
|
||||
* Cerbs fire
|
||||
*/
|
||||
|
||||
@@ -71,7 +71,7 @@ public class AoeWarningOverlay extends Overlay
|
||||
{
|
||||
for (WorldPoint point : plugin.getLightningTrail())
|
||||
{
|
||||
drawTile(graphics, point, new Color(0,150,200), 2, 150, 50);
|
||||
drawTile(graphics, point, new Color(0, 150, 200), 2, 150, 50);
|
||||
}
|
||||
for (WorldPoint point : plugin.getAcidTrail())
|
||||
{
|
||||
@@ -84,7 +84,7 @@ public class AoeWarningOverlay extends Overlay
|
||||
|
||||
Instant now = Instant.now();
|
||||
Map<Projectile, AoeProjectile> projectiles = plugin.getProjectiles();
|
||||
for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext();)
|
||||
for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext(); )
|
||||
{
|
||||
AoeProjectile aoeProjectile = it.next();
|
||||
|
||||
@@ -145,18 +145,22 @@ public class AoeWarningOverlay extends Overlay
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) {
|
||||
private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
if (point.distanceTo(playerLocation) >= 32) {
|
||||
if (point.distanceTo(playerLocation) >= 32)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, point);
|
||||
if (lp == null) {
|
||||
if (lp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
if (poly == null) {
|
||||
if (poly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
|
||||
@@ -301,8 +301,8 @@ public class AoeWarningPlugin extends Plugin
|
||||
return config.isXarpusEnabled();
|
||||
case ADDY_DRAG_POISON:
|
||||
return config.addyDrags();
|
||||
case DRAKE_BREATH:
|
||||
return config.isDrakeEnabled();
|
||||
case DRAKE_BREATH:
|
||||
return config.isDrakeEnabled();
|
||||
case CERB_FIRE:
|
||||
return config.isCerbFireEnabled();
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class BombOverlay extends Overlay
|
||||
|
||||
//Utilized from the npc highlight code for formatting text being displayed on the client canvas.
|
||||
private static final NumberFormat TIME_LEFT_FORMATTER =
|
||||
DecimalFormat.getInstance(Locale.US);
|
||||
DecimalFormat.getInstance(Locale.US);
|
||||
|
||||
static
|
||||
{
|
||||
@@ -157,22 +157,22 @@ public class BombOverlay extends Overlay
|
||||
|
||||
Instant now = Instant.now();
|
||||
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() -
|
||||
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
|
||||
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
|
||||
//divided by 1000.00 because of milliseconds :)
|
||||
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
|
||||
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
|
||||
//divided by 1000.00 because of milliseconds :)
|
||||
|
||||
timeLeft = Math.max(0.0, timeLeft);
|
||||
String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
|
||||
int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
|
||||
int textHeight = graphics.getFontMetrics().getAscent();
|
||||
Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(),
|
||||
localLoc.getY(), bomb.getWorldLocation().getPlane());
|
||||
localLoc.getY(), bomb.getWorldLocation().getPlane());
|
||||
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX() - textWidth / 2,
|
||||
canvasPoint.getY() + textHeight / 2);
|
||||
canvasPoint.getX() - textWidth / 2,
|
||||
canvasPoint.getY() + textHeight / 2);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("banktags")
|
||||
public interface BankTagsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "useTabs",
|
||||
name = "Use Tag Tabs",
|
||||
description = "Enable the ability to add tabs to your bank which allow fast access to tags.",
|
||||
position = 1
|
||||
)
|
||||
default boolean tabs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rememberTab",
|
||||
name = "Remember last Tag Tab",
|
||||
description = "Enable the ability to remember last Tag Tab when closing/opening the bank.",
|
||||
position = 2
|
||||
)
|
||||
default boolean rememberTab()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeSeparators",
|
||||
name = "Remove tab separators in Tag Tabs",
|
||||
description = "Removes tab separators and corrects item layouts in Tag Tabs to mimic a regular tab",
|
||||
position = 3
|
||||
)
|
||||
default boolean removeSeparators()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hidePlaceholders",
|
||||
name = "Hide placeholders",
|
||||
description = "Hide placeholders in tag tabs or tag search.",
|
||||
position = 4
|
||||
)
|
||||
default boolean hidePlaceholders()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "position",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default int position()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "position",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void position(int idx);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tab",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default String tab()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tab",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void tab(String tab);
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("banktags")
|
||||
public interface BankTagsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "useTabs",
|
||||
name = "Use Tag Tabs",
|
||||
description = "Enable the ability to add tabs to your bank which allow fast access to tags.",
|
||||
position = 1
|
||||
)
|
||||
default boolean tabs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rememberTab",
|
||||
name = "Remember last Tag Tab",
|
||||
description = "Enable the ability to remember last Tag Tab when closing/opening the bank.",
|
||||
position = 2
|
||||
)
|
||||
default boolean rememberTab()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeSeparators",
|
||||
name = "Remove tab separators in Tag Tabs",
|
||||
description = "Removes tab separators and corrects item layouts in Tag Tabs to mimic a regular tab",
|
||||
position = 3
|
||||
)
|
||||
default boolean removeSeparators()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hidePlaceholders",
|
||||
name = "Hide placeholders",
|
||||
description = "Hide placeholders in tag tabs or tag search.",
|
||||
position = 4
|
||||
)
|
||||
default boolean hidePlaceholders()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "position",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default int position()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "position",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void position(int idx);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tab",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default String tab()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tab",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void tab(String tab);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018, whartd <github.com/whartd>
|
||||
* 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.barbarianassault;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
enum HealerTeam
|
||||
{
|
||||
TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115),
|
||||
TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115),
|
||||
TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115),
|
||||
TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115);
|
||||
|
||||
private WidgetInfo teammate;
|
||||
private Point offset;
|
||||
private int width;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, whartd <github.com/whartd>
|
||||
* 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.barbarianassault;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
enum HealerTeam
|
||||
{
|
||||
TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115),
|
||||
TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115),
|
||||
TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115),
|
||||
TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115);
|
||||
|
||||
private WidgetInfo teammate;
|
||||
private Point offset;
|
||||
private int width;
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* 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.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class BarrowsBrotherSlainOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private BarrowsBrotherSlainOverlay(BarrowsPlugin plugin, Client client)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
this.client = client;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Barrows overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Do not display overlay if potential is null/hidden
|
||||
final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL);
|
||||
if (potential == null || potential.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Hide original overlay
|
||||
final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS);
|
||||
if (barrowsBrothers != null)
|
||||
{
|
||||
barrowsBrothers.setHidden(true);
|
||||
potential.setHidden(true);
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
for (BarrowsBrothers brother : BarrowsBrothers.values())
|
||||
{
|
||||
final boolean brotherSlain = client.getVar(brother.getKilledVarbit()) > 0;
|
||||
String slain = brotherSlain ? "\u2713" : "\u2717";
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(brother.getName())
|
||||
.right(slain)
|
||||
.rightColor(brotherSlain ? Color.GREEN : Color.RED)
|
||||
.build());
|
||||
}
|
||||
|
||||
float rewardPercent = client.getVar(Varbits.BARROWS_REWARD_POTENTIAL) / 10.0f;
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Potential")
|
||||
.right(rewardPercent != 0 ? rewardPercent + "%" : "0%")
|
||||
.rightColor(rewardPercent >= 73.0f && rewardPercent <= 88.0f ? Color.GREEN : rewardPercent < 65.6f ? Color.WHITE : Color.YELLOW)
|
||||
.build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* 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.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class BarrowsBrotherSlainOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private BarrowsBrotherSlainOverlay(BarrowsPlugin plugin, Client client)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
this.client = client;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Barrows overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Do not display overlay if potential is null/hidden
|
||||
final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL);
|
||||
if (potential == null || potential.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Hide original overlay
|
||||
final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS);
|
||||
if (barrowsBrothers != null)
|
||||
{
|
||||
barrowsBrothers.setHidden(true);
|
||||
potential.setHidden(true);
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
for (BarrowsBrothers brother : BarrowsBrothers.values())
|
||||
{
|
||||
final boolean brotherSlain = client.getVar(brother.getKilledVarbit()) > 0;
|
||||
String slain = brotherSlain ? "\u2713" : "\u2717";
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(brother.getName())
|
||||
.right(slain)
|
||||
.rightColor(brotherSlain ? Color.GREEN : Color.RED)
|
||||
.build());
|
||||
}
|
||||
|
||||
float rewardPercent = client.getVar(Varbits.BARROWS_REWARD_POTENTIAL) / 10.0f;
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Potential")
|
||||
.right(rewardPercent != 0 ? rewardPercent + "%" : "0%")
|
||||
.rightColor(rewardPercent >= 73.0f && rewardPercent <= 88.0f ? Color.GREEN : rewardPercent < 65.6f ? Color.WHITE : Color.YELLOW)
|
||||
.build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,243 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.ObjectComposition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
class BarrowsOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
|
||||
private final Client client;
|
||||
private final BarrowsPlugin plugin;
|
||||
private final BarrowsConfig config;
|
||||
|
||||
@Inject
|
||||
private BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
final Color npcColor = getMinimapDotColor(1);
|
||||
final Color playerColor = getMinimapDotColor(2);
|
||||
Widget puzzleAnswer = plugin.getPuzzleAnswer();
|
||||
|
||||
// tunnels are only on z=0
|
||||
if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap())
|
||||
{
|
||||
// NPC dots
|
||||
graphics.setColor(npcColor);
|
||||
final List<NPC> npcs = client.getNpcs();
|
||||
for (NPC npc : npcs)
|
||||
{
|
||||
final NPCComposition composition = npc.getComposition();
|
||||
|
||||
if (composition != null && !composition.isMinimapVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Player dots
|
||||
graphics.setColor(playerColor);
|
||||
final List<Player> players = client.getPlayers();
|
||||
for (Player player : players)
|
||||
{
|
||||
if (player == local)
|
||||
{
|
||||
// Skip local player as we draw square for it later
|
||||
continue;
|
||||
}
|
||||
|
||||
net.runelite.api.Point minimapLocation = player.getMinimapLocation();
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Render barrows walls/doors
|
||||
renderObjects(graphics, local);
|
||||
|
||||
// Local player square
|
||||
graphics.setColor(playerColor);
|
||||
graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3);
|
||||
}
|
||||
else if (config.showBrotherLoc())
|
||||
{
|
||||
renderBarrowsBrothers(graphics);
|
||||
}
|
||||
|
||||
if (puzzleAnswer != null && config.showPuzzleAnswer() && !puzzleAnswer.isHidden())
|
||||
{
|
||||
Rectangle answerRect = puzzleAnswer.getBounds();
|
||||
graphics.setColor(Color.GREEN);
|
||||
graphics.draw(answerRect);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderObjects(Graphics2D graphics, Player localPlayer)
|
||||
{
|
||||
LocalPoint localLocation = localPlayer.getLocalLocation();
|
||||
for (WallObject wall : plugin.getWalls())
|
||||
{
|
||||
LocalPoint location = wall.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderWalls(graphics, wall);
|
||||
}
|
||||
}
|
||||
|
||||
for (GameObject ladder : plugin.getLadders())
|
||||
{
|
||||
LocalPoint location = ladder.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderLadders(graphics, ladder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderWalls(Graphics2D graphics, WallObject wall)
|
||||
{
|
||||
net.runelite.api.Point minimapLocation = wall.getMinimapLocation();
|
||||
|
||||
if (minimapLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectComposition objectComp = client.getObjectDefinition(wall.getId());
|
||||
ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null;
|
||||
|
||||
if (impostor != null && impostor.getActions()[0] != null)
|
||||
{
|
||||
graphics.setColor(Color.green);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(Color.gray);
|
||||
}
|
||||
|
||||
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimap dot color from client
|
||||
* @param typeIndex index of minimap dot type (1 npcs, 2 players)
|
||||
* @return color
|
||||
*/
|
||||
private Color getMinimapDotColor(int typeIndex)
|
||||
{
|
||||
final int pixel = client.getMapDots()[typeIndex].getPixels()[1];
|
||||
return new Color(pixel);
|
||||
}
|
||||
|
||||
private void renderLadders(Graphics2D graphics, GameObject ladder)
|
||||
{
|
||||
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation();
|
||||
|
||||
if (minimapLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectComposition objectComp = client.getObjectDefinition(ladder.getId());
|
||||
|
||||
if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
|
||||
{
|
||||
graphics.setColor(Color.orange);
|
||||
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderBarrowsBrothers(Graphics2D graphics)
|
||||
{
|
||||
for (BarrowsBrothers brother : BarrowsBrothers.values())
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String brotherLetter = Character.toString(brother.getName().charAt(0));
|
||||
net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics,
|
||||
localLocation, brotherLetter);
|
||||
|
||||
if (minimapText != null)
|
||||
{
|
||||
graphics.setColor(Color.black);
|
||||
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1);
|
||||
|
||||
if (client.getVar(brother.getKilledVarbit()) > 0)
|
||||
{
|
||||
graphics.setColor(config.deadBrotherLocColor());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(config.brotherLocColor());
|
||||
}
|
||||
|
||||
graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.ObjectComposition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
class BarrowsOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
|
||||
private final Client client;
|
||||
private final BarrowsPlugin plugin;
|
||||
private final BarrowsConfig config;
|
||||
|
||||
@Inject
|
||||
private BarrowsOverlay(Client client, BarrowsPlugin plugin, BarrowsConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
final Color npcColor = getMinimapDotColor(1);
|
||||
final Color playerColor = getMinimapDotColor(2);
|
||||
Widget puzzleAnswer = plugin.getPuzzleAnswer();
|
||||
|
||||
// tunnels are only on z=0
|
||||
if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && config.showMinimap())
|
||||
{
|
||||
// NPC dots
|
||||
graphics.setColor(npcColor);
|
||||
final List<NPC> npcs = client.getNpcs();
|
||||
for (NPC npc : npcs)
|
||||
{
|
||||
final NPCComposition composition = npc.getComposition();
|
||||
|
||||
if (composition != null && !composition.isMinimapVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Player dots
|
||||
graphics.setColor(playerColor);
|
||||
final List<Player> players = client.getPlayers();
|
||||
for (Player player : players)
|
||||
{
|
||||
if (player == local)
|
||||
{
|
||||
// Skip local player as we draw square for it later
|
||||
continue;
|
||||
}
|
||||
|
||||
net.runelite.api.Point minimapLocation = player.getMinimapLocation();
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Render barrows walls/doors
|
||||
renderObjects(graphics, local);
|
||||
|
||||
// Local player square
|
||||
graphics.setColor(playerColor);
|
||||
graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3);
|
||||
}
|
||||
else if (config.showBrotherLoc())
|
||||
{
|
||||
renderBarrowsBrothers(graphics);
|
||||
}
|
||||
|
||||
if (puzzleAnswer != null && config.showPuzzleAnswer() && !puzzleAnswer.isHidden())
|
||||
{
|
||||
Rectangle answerRect = puzzleAnswer.getBounds();
|
||||
graphics.setColor(Color.GREEN);
|
||||
graphics.draw(answerRect);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderObjects(Graphics2D graphics, Player localPlayer)
|
||||
{
|
||||
LocalPoint localLocation = localPlayer.getLocalLocation();
|
||||
for (WallObject wall : plugin.getWalls())
|
||||
{
|
||||
LocalPoint location = wall.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderWalls(graphics, wall);
|
||||
}
|
||||
}
|
||||
|
||||
for (GameObject ladder : plugin.getLadders())
|
||||
{
|
||||
LocalPoint location = ladder.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderLadders(graphics, ladder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderWalls(Graphics2D graphics, WallObject wall)
|
||||
{
|
||||
net.runelite.api.Point minimapLocation = wall.getMinimapLocation();
|
||||
|
||||
if (minimapLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectComposition objectComp = client.getObjectDefinition(wall.getId());
|
||||
ObjectComposition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null;
|
||||
|
||||
if (impostor != null && impostor.getActions()[0] != null)
|
||||
{
|
||||
graphics.setColor(Color.green);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(Color.gray);
|
||||
}
|
||||
|
||||
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimap dot color from client
|
||||
*
|
||||
* @param typeIndex index of minimap dot type (1 npcs, 2 players)
|
||||
* @return color
|
||||
*/
|
||||
private Color getMinimapDotColor(int typeIndex)
|
||||
{
|
||||
final int pixel = client.getMapDots()[typeIndex].getPixels()[1];
|
||||
return new Color(pixel);
|
||||
}
|
||||
|
||||
private void renderLadders(Graphics2D graphics, GameObject ladder)
|
||||
{
|
||||
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation();
|
||||
|
||||
if (minimapLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectComposition objectComp = client.getObjectDefinition(ladder.getId());
|
||||
|
||||
if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
|
||||
{
|
||||
graphics.setColor(Color.orange);
|
||||
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderBarrowsBrothers(Graphics2D graphics)
|
||||
{
|
||||
for (BarrowsBrothers brother : BarrowsBrothers.values())
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String brotherLetter = Character.toString(brother.getName().charAt(0));
|
||||
net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics,
|
||||
localLocation, brotherLetter);
|
||||
|
||||
if (minimapText != null)
|
||||
{
|
||||
graphics.setColor(Color.black);
|
||||
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1);
|
||||
|
||||
if (client.getVar(brother.getKilledVarbit()) > 0)
|
||||
{
|
||||
graphics.setColor(config.deadBrotherLocColor());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(config.brotherLocColor());
|
||||
}
|
||||
|
||||
graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,13 +81,13 @@ public class BarrowsPlugin extends Plugin
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private static final Set<Integer> BARROWS_WALLS = Sets.newHashSet
|
||||
(
|
||||
ObjectID.DOOR_20678, NullObjectID.NULL_20681, NullObjectID.NULL_20682, NullObjectID.NULL_20683, NullObjectID.NULL_20684, NullObjectID.NULL_20685, NullObjectID.NULL_20686, NullObjectID.NULL_20687,
|
||||
NullObjectID.NULL_20688, NullObjectID.NULL_20689, NullObjectID.NULL_20690, NullObjectID.NULL_20691, NullObjectID.NULL_20692, NullObjectID.NULL_20693, NullObjectID.NULL_20694, NullObjectID.NULL_20695,
|
||||
NullObjectID.NULL_20696, ObjectID.DOOR_20697, NullObjectID.NULL_20700, NullObjectID.NULL_20701, NullObjectID.NULL_20702, NullObjectID.NULL_20703, NullObjectID.NULL_20704, NullObjectID.NULL_20705,
|
||||
NullObjectID.NULL_20706, NullObjectID.NULL_20707, NullObjectID.NULL_20708, NullObjectID.NULL_20709, NullObjectID.NULL_20710, NullObjectID.NULL_20711, NullObjectID.NULL_20712, NullObjectID.NULL_20713,
|
||||
NullObjectID.NULL_20714, NullObjectID.NULL_20715, NullObjectID.NULL_20728, NullObjectID.NULL_20730
|
||||
);
|
||||
(
|
||||
ObjectID.DOOR_20678, NullObjectID.NULL_20681, NullObjectID.NULL_20682, NullObjectID.NULL_20683, NullObjectID.NULL_20684, NullObjectID.NULL_20685, NullObjectID.NULL_20686, NullObjectID.NULL_20687,
|
||||
NullObjectID.NULL_20688, NullObjectID.NULL_20689, NullObjectID.NULL_20690, NullObjectID.NULL_20691, NullObjectID.NULL_20692, NullObjectID.NULL_20693, NullObjectID.NULL_20694, NullObjectID.NULL_20695,
|
||||
NullObjectID.NULL_20696, ObjectID.DOOR_20697, NullObjectID.NULL_20700, NullObjectID.NULL_20701, NullObjectID.NULL_20702, NullObjectID.NULL_20703, NullObjectID.NULL_20704, NullObjectID.NULL_20705,
|
||||
NullObjectID.NULL_20706, NullObjectID.NULL_20707, NullObjectID.NULL_20708, NullObjectID.NULL_20709, NullObjectID.NULL_20710, NullObjectID.NULL_20711, NullObjectID.NULL_20712, NullObjectID.NULL_20713,
|
||||
NullObjectID.NULL_20714, NullObjectID.NULL_20715, NullObjectID.NULL_20728, NullObjectID.NULL_20730
|
||||
);
|
||||
|
||||
private static final Set<Integer> BARROWS_LADDERS = Sets.newHashSet(NullObjectID.NULL_20675, NullObjectID.NULL_20676, NullObjectID.NULL_20677);
|
||||
private static final ImmutableList<WidgetInfo> POSSIBLE_SOLUTIONS = ImmutableList.of(
|
||||
|
||||
@@ -31,8 +31,6 @@ import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@@ -63,7 +63,6 @@ import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
@@ -371,10 +370,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (healers.remove(event.getNpc()) != null && healers.isEmpty())
|
||||
{
|
||||
healers.clear();
|
||||
}
|
||||
healers.remove(event.getNpc());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -450,7 +446,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
remove(new String[]{"take", "light"}, target, true);
|
||||
}
|
||||
else//remove "Light" option (and "Take" option if not defender).
|
||||
else //remove "Light" option (and "Take" option if not defender).
|
||||
{
|
||||
remove("light", target, true);
|
||||
}
|
||||
@@ -466,7 +462,8 @@ public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
List<String> poison = Arrays.asList("poisoned tofu", "poisoned meat", "poisoned worms");
|
||||
List<String> vials = Arrays.asList("healing vial", "healing vial(1)", "healing vial(2)", "healing vial(3)", "healing vial(4)");//"healing vial(4)"
|
||||
if (poison.contains(item))
|
||||
{//if item is a poison item
|
||||
{
|
||||
//if item is a poison item
|
||||
int calledPoison = 0;
|
||||
switch (healer.getText())//choose which poison to hide the use/destroy option for
|
||||
{
|
||||
@@ -509,11 +506,13 @@ public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
}
|
||||
}
|
||||
else if (option.equals("attack") && client.getWidget(WidgetInfo.BA_ATK_ROLE_TEXT) == null && !target.equals("queen spawn"))//if not attacker
|
||||
{//remove attack option from everything but queen spawns
|
||||
{
|
||||
//remove attack option from everything but queen spawns
|
||||
remove(option, target, true);
|
||||
}
|
||||
else if ((option.equals("fix") || (option.equals("block") && target.equals("penance cave"))) && client.getWidget(WidgetInfo.BA_DEF_ROLE_TEXT) == null)//if not defender
|
||||
{//the check for option requires checking target as well because defensive attack style option is also called "block".
|
||||
{
|
||||
//the check for option requires checking target as well because defensive attack style option is also called "block".
|
||||
remove(option, target, true);
|
||||
}
|
||||
else if ((option.equals("load")) && client.getWidget(WidgetInfo.BA_COLL_ROLE_TEXT) == null)//if not collector, remove hopper options
|
||||
@@ -632,7 +631,7 @@ public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum Calls
|
||||
{
|
||||
|
||||
@@ -24,11 +24,10 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
class CycleCounter extends Counter
|
||||
{
|
||||
CycleCounter(BufferedImage img, Plugin plugin, int tick)
|
||||
|
||||
@@ -27,9 +27,7 @@ package net.runelite.client.plugins.batools;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Actor;
|
||||
|
||||
|
||||
class Healer
|
||||
@@ -75,7 +73,7 @@ class Healer
|
||||
|
||||
private HealerCode getCode(int wave)
|
||||
{
|
||||
switch(wave)
|
||||
switch (wave)
|
||||
{
|
||||
case 1:
|
||||
return HealerCode.WAVEONE;
|
||||
@@ -97,7 +95,8 @@ class Healer
|
||||
return HealerCode.WAVENINE;
|
||||
case 10:
|
||||
return HealerCode.WAVETEN;
|
||||
default: return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,16 +30,16 @@ import lombok.Getter;
|
||||
enum HealerCode
|
||||
{
|
||||
|
||||
WAVEONE(new int[] {1,1}, new int[] {0,0}, new int[] {0,0}),
|
||||
WAVETWO(new int[] {1,1,2}, new int[] {0,0,0}, new int[] {0,0,21}),
|
||||
WAVETHREE(new int[] {1,6,2}, new int[] {0,0,0}, new int[] {0,0,0}),
|
||||
WAVEFOUR(new int[] {2,5,2,0}, new int[] {0,0,7,10}, new int[] {0,0,0,0}),
|
||||
WAVEFIVE(new int[] {2,5,2,3,0}, new int[] {0,0,0,0,7}, new int[] {0,0,21,30,0}),
|
||||
WAVESIX(new int[] {3,5,2,2,0,0}, new int[] {0,0,0,2,9,10}, new int[] {12,18,21,0,0,0}),
|
||||
WAVESEVEN(new int[] {3,7,1,1,0,0,0}, new int[] {2,0,1,1,2,4,10}, new int[] {0,21,0,0,30,45,0}),
|
||||
WAVEEIGHT(new int[] {1,9,1,1,0,0,0}, new int[] {1,0,1,1,2,2,10}, new int[] {0,0,0,0,33,42,0}),
|
||||
WAVENINE(new int[] {2,8,1,1,0,0,0,0}, new int[] {1,0,1,1,2,1,1,10}, new int[] {0,21,0,0,0,0,0,0,0}),
|
||||
WAVETEN(new int[] {2,5,1,1,0,0,0}, new int[] {1,0,1,1,4,4,8}, new int[] {21,33,0,33,30,45,0});
|
||||
WAVEONE(new int[]{1, 1}, new int[]{0, 0}, new int[]{0, 0}),
|
||||
WAVETWO(new int[]{1, 1, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 21}),
|
||||
WAVETHREE(new int[]{1, 6, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 0}),
|
||||
WAVEFOUR(new int[]{2, 5, 2, 0}, new int[]{0, 0, 7, 10}, new int[]{0, 0, 0, 0}),
|
||||
WAVEFIVE(new int[]{2, 5, 2, 3, 0}, new int[]{0, 0, 0, 0, 7}, new int[]{0, 0, 21, 30, 0}),
|
||||
WAVESIX(new int[]{3, 5, 2, 2, 0, 0}, new int[]{0, 0, 0, 2, 9, 10}, new int[]{12, 18, 21, 0, 0, 0}),
|
||||
WAVESEVEN(new int[]{3, 7, 1, 1, 0, 0, 0}, new int[]{2, 0, 1, 1, 2, 4, 10}, new int[]{0, 21, 0, 0, 30, 45, 0}),
|
||||
WAVEEIGHT(new int[]{1, 9, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 2, 10}, new int[]{0, 0, 0, 0, 33, 42, 0}),
|
||||
WAVENINE(new int[]{2, 8, 1, 1, 0, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 1, 1, 10}, new int[]{0, 21, 0, 0, 0, 0, 0, 0, 0}),
|
||||
WAVETEN(new int[]{2, 5, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 4, 4, 8}, new int[]{21, 33, 0, 33, 30, 45, 0});
|
||||
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -36,7 +36,6 @@ import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@@ -1,101 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Unmoon <https://github.com/Unmoon>
|
||||
* 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.blastmine;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
@ConfigGroup("blastmine")
|
||||
public interface BlastMinePluginConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "showOreOverlay",
|
||||
name = "Show ore overlay",
|
||||
description = "Configures whether or not the ore count overlay is displayed"
|
||||
)
|
||||
default boolean showOreOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "showRockIconOverlay",
|
||||
name = "Show icons overlay",
|
||||
description = "Configures whether or not the icon overlay is displayed"
|
||||
)
|
||||
default boolean showRockIconOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "showTimerOverlay",
|
||||
name = "Show timer overlay",
|
||||
description = "Configures whether or not the timer overlay is displayed"
|
||||
)
|
||||
default boolean showTimerOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "showWarningOverlay",
|
||||
name = "Show explosion warning",
|
||||
description = "Configures whether or not the explosion warning overlay is displayed"
|
||||
)
|
||||
default boolean showWarningOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "hexTimerColor",
|
||||
name = "Timer color",
|
||||
description = "Color of timer overlay"
|
||||
)
|
||||
default Color getTimerColor()
|
||||
{
|
||||
return new Color(217, 54, 0);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "hexWarningColor",
|
||||
name = "Warning color",
|
||||
description = "Color of warning overlay"
|
||||
)
|
||||
default Color getWarningColor()
|
||||
{
|
||||
return new Color(217, 54, 0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Unmoon <https://github.com/Unmoon>
|
||||
* 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.blastmine;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("blastmine")
|
||||
public interface BlastMinePluginConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "showOreOverlay",
|
||||
name = "Show ore overlay",
|
||||
description = "Configures whether or not the ore count overlay is displayed"
|
||||
)
|
||||
default boolean showOreOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "showRockIconOverlay",
|
||||
name = "Show icons overlay",
|
||||
description = "Configures whether or not the icon overlay is displayed"
|
||||
)
|
||||
default boolean showRockIconOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "showTimerOverlay",
|
||||
name = "Show timer overlay",
|
||||
description = "Configures whether or not the timer overlay is displayed"
|
||||
)
|
||||
default boolean showTimerOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "showWarningOverlay",
|
||||
name = "Show explosion warning",
|
||||
description = "Configures whether or not the explosion warning overlay is displayed"
|
||||
)
|
||||
default boolean showWarningOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "hexTimerColor",
|
||||
name = "Timer color",
|
||||
description = "Color of timer overlay"
|
||||
)
|
||||
default Color getTimerColor()
|
||||
{
|
||||
return new Color(217, 54, 0);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "hexWarningColor",
|
||||
name = "Warning color",
|
||||
description = "Color of warning overlay"
|
||||
)
|
||||
default Color getWarningColor()
|
||||
{
|
||||
return new Color(217, 54, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ public class BoostsPlugin extends Plugin
|
||||
* section it will "activate" adding an additional 15 second section
|
||||
* to the boost timing. If again the preserve prayer is active for that
|
||||
* entire section a second 15 second section will be added.
|
||||
*
|
||||
* <p>
|
||||
* Preserve is only required to be on for the 4th and 5th sections of the boost timer
|
||||
* to gain full effect (seconds 45-75).
|
||||
*
|
||||
@@ -365,8 +365,8 @@ public class BoostsPlugin extends Plugin
|
||||
int getChangeDownTicks()
|
||||
{
|
||||
if (lastChangeDown == -1 ||
|
||||
config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
|
||||
(config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp))
|
||||
config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
|
||||
(config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -393,8 +393,8 @@ public class BoostsPlugin extends Plugin
|
||||
int getChangeUpTicks()
|
||||
{
|
||||
if (lastChangeUp == -1 ||
|
||||
config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
|
||||
(config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown))
|
||||
config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER ||
|
||||
(config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -406,12 +406,13 @@ public class BoostsPlugin extends Plugin
|
||||
|
||||
/**
|
||||
* Converts tick-based time to accurate second time
|
||||
*
|
||||
* @param time tick-based time
|
||||
* @return second-based time
|
||||
*/
|
||||
int getChangeTime(final int time)
|
||||
{
|
||||
final long diff = System.currentTimeMillis() - lastTickMillis;
|
||||
return time != -1 ? (int)((time * Constants.GAME_TICK_LENGTH - diff) / 1000d) : time;
|
||||
return time != -1 ? (int) ((time * Constants.GAME_TICK_LENGTH - diff) / 1000d) : time;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ enum Boss
|
||||
bosses = builder.build();
|
||||
}
|
||||
|
||||
private Boss(int id, long period, ChronoUnit unit, int itemSpriteId)
|
||||
Boss(int id, long period, ChronoUnit unit, int itemSpriteId)
|
||||
{
|
||||
this.id = id;
|
||||
this.spawnTime = Duration.of(period, unit);
|
||||
|
||||
@@ -1,141 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cannon;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import static net.runelite.api.Perspective.LOCAL_TILE_SIZE;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.TextComponent;
|
||||
|
||||
class CannonOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2500;
|
||||
|
||||
private final Client client;
|
||||
private final CannonConfig config;
|
||||
private final CannonPlugin plugin;
|
||||
private final TextComponent textComponent = new TextComponent();
|
||||
|
||||
@Inject
|
||||
CannonOverlay(Client client, CannonConfig config, CannonPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPoint cannonPoint = LocalPoint.fromWorld(client, plugin.getCannonPosition());
|
||||
|
||||
if (cannonPoint == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
if (localLocation.distanceTo(cannonPoint) <= MAX_DISTANCE)
|
||||
{
|
||||
Point cannonLoc = Perspective.getCanvasTextLocation(client,
|
||||
graphics,
|
||||
cannonPoint,
|
||||
String.valueOf(plugin.getCballsLeft()), 150);
|
||||
|
||||
if (cannonLoc != null)
|
||||
{
|
||||
textComponent.setText(String.valueOf(plugin.getCballsLeft()));
|
||||
textComponent.setPosition(new java.awt.Point(cannonLoc.getX(), cannonLoc.getY()));
|
||||
textComponent.setColor(plugin.getStateColor());
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
|
||||
if (config.showDoubleHitSpot())
|
||||
{
|
||||
Color color = config.highlightDoubleHitColor();
|
||||
drawDoubleHitSpots(graphics, cannonPoint, color);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw the double hit spots on a 6 by 6 grid around the cannon
|
||||
* @param startTile The position of the cannon
|
||||
*/
|
||||
private void drawDoubleHitSpots(Graphics2D graphics, LocalPoint startTile, Color color)
|
||||
{
|
||||
for (int x = -3; x <= 3; x++)
|
||||
{
|
||||
for (int y = -3; y <= 3; y++)
|
||||
{
|
||||
if (y != 1 && x != 1 && y != -1 && x != -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Ignore center square
|
||||
if (y >= -1 && y <= 1 && x >= -1 && x <= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int xPos = startTile.getX() - (x * LOCAL_TILE_SIZE);
|
||||
int yPos = startTile.getY() - (y * LOCAL_TILE_SIZE);
|
||||
|
||||
LocalPoint marker = new LocalPoint(xPos, yPos);
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, marker);
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2016-2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cannon;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import static net.runelite.api.Perspective.LOCAL_TILE_SIZE;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.TextComponent;
|
||||
|
||||
class CannonOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2500;
|
||||
|
||||
private final Client client;
|
||||
private final CannonConfig config;
|
||||
private final CannonPlugin plugin;
|
||||
private final TextComponent textComponent = new TextComponent();
|
||||
|
||||
@Inject
|
||||
CannonOverlay(Client client, CannonConfig config, CannonPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.isCannonPlaced() || plugin.getCannonPosition() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPoint cannonPoint = LocalPoint.fromWorld(client, plugin.getCannonPosition());
|
||||
|
||||
if (cannonPoint == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
if (localLocation.distanceTo(cannonPoint) <= MAX_DISTANCE)
|
||||
{
|
||||
Point cannonLoc = Perspective.getCanvasTextLocation(client,
|
||||
graphics,
|
||||
cannonPoint,
|
||||
String.valueOf(plugin.getCballsLeft()), 150);
|
||||
|
||||
if (cannonLoc != null)
|
||||
{
|
||||
textComponent.setText(String.valueOf(plugin.getCballsLeft()));
|
||||
textComponent.setPosition(new java.awt.Point(cannonLoc.getX(), cannonLoc.getY()));
|
||||
textComponent.setColor(plugin.getStateColor());
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
|
||||
if (config.showDoubleHitSpot())
|
||||
{
|
||||
Color color = config.highlightDoubleHitColor();
|
||||
drawDoubleHitSpots(graphics, cannonPoint, color);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw the double hit spots on a 6 by 6 grid around the cannon
|
||||
*
|
||||
* @param startTile The position of the cannon
|
||||
*/
|
||||
private void drawDoubleHitSpots(Graphics2D graphics, LocalPoint startTile, Color color)
|
||||
{
|
||||
for (int x = -3; x <= 3; x++)
|
||||
{
|
||||
for (int y = -3; y <= 3; y++)
|
||||
{
|
||||
if (y != 1 && x != 1 && y != -1 && x != -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Ignore center square
|
||||
if (y >= -1 && y <= 1 && x >= -1 && x <= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int xPos = startTile.getX() - (x * LOCAL_TILE_SIZE);
|
||||
int yPos = startTile.getY() - (y * LOCAL_TILE_SIZE);
|
||||
|
||||
LocalPoint marker = new LocalPoint(xPos, yPos);
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, marker);
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,7 @@ public enum CerberusGhost
|
||||
|
||||
/**
|
||||
* Try to identify if NPC is ghost
|
||||
*
|
||||
* @param npc npc
|
||||
* @return optional ghost
|
||||
*/
|
||||
|
||||
@@ -63,13 +63,13 @@ public class CerberusOverlay extends Overlay
|
||||
|
||||
// Ghosts are already sorted
|
||||
plugin.getGhosts().stream()
|
||||
// Iterate only through the correct amount of ghosts
|
||||
.limit(CerberusGhost.values().length)
|
||||
.forEach(npc -> CerberusGhost
|
||||
.fromNPC(npc)
|
||||
.ifPresent(ghost -> panelComponent
|
||||
.getChildren()
|
||||
.add(new ImageComponent(iconManager.getSkillImage(ghost.getType())))));
|
||||
// Iterate only through the correct amount of ghosts
|
||||
.limit(CerberusGhost.values().length)
|
||||
.forEach(npc -> CerberusGhost
|
||||
.fromNPC(npc)
|
||||
.ifPresent(ghost -> panelComponent
|
||||
.getChildren()
|
||||
.add(new ImageComponent(iconManager.getSkillImage(ghost.getType())))));
|
||||
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
|
||||
@@ -1,158 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* 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.chatboxperformance;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.api.events.WidgetPositioned;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetPositionMode;
|
||||
import net.runelite.api.widgets.WidgetSizeMode;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chatbox performance",
|
||||
hidden = true
|
||||
)
|
||||
public class ChatboxPerformancePlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetPositioned(WidgetPositioned event)
|
||||
{
|
||||
if (!areWidgetsFixed())
|
||||
{
|
||||
fixChatbox();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areWidgetsFixed()
|
||||
{
|
||||
Widget widget = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND);
|
||||
if (widget == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Widget[] widgets = widget.getChildren();
|
||||
|
||||
if (widgets != null && widgets.length > 0)
|
||||
{
|
||||
Widget last = widgets[widgets.length - 1];
|
||||
return last != null && last.getOpacity() < 254;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void fixChatbox()
|
||||
{
|
||||
fixDarkBackground();
|
||||
fixWhiteLines(true);
|
||||
fixWhiteLines(false);
|
||||
}
|
||||
|
||||
private void fixDarkBackground()
|
||||
{
|
||||
int currOpacity = 256;
|
||||
int prevY = 0;
|
||||
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND).getDynamicChildren();
|
||||
Widget prev = null;
|
||||
for (Widget w : children)
|
||||
{
|
||||
if (w.getType() != WidgetType.RECTANGLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev != null)
|
||||
{
|
||||
int relY = w.getRelativeY();
|
||||
prev.setHeightMode(WidgetSizeMode.ABSOLUTE);
|
||||
prev.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
prev.setRelativeY(prevY);
|
||||
prev.setOriginalY(prev.getRelativeY());
|
||||
prev.setHeight(relY - prevY);
|
||||
prev.setOriginalHeight(prev.getHeight());
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
|
||||
prevY = w.getRelativeY();
|
||||
currOpacity -= 3; // Rough number, can't get exactly the same as Jagex because of rounding
|
||||
prev = w;
|
||||
}
|
||||
if (prev != null)
|
||||
{
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
}
|
||||
|
||||
private void fixWhiteLines(boolean upperLine)
|
||||
{
|
||||
int currOpacity = 256;
|
||||
int prevWidth = 0;
|
||||
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_LINES).getDynamicChildren();
|
||||
Widget prev = null;
|
||||
for (Widget w : children)
|
||||
{
|
||||
if (w.getType() != WidgetType.RECTANGLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((w.getRelativeY() == 0 && !upperLine) ||
|
||||
(w.getRelativeY() != 0 && upperLine))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev != null)
|
||||
{
|
||||
int width = w.getWidth();
|
||||
prev.setWidthMode(WidgetSizeMode.ABSOLUTE);
|
||||
prev.setRelativeX(width);
|
||||
prev.setOriginalX(width);
|
||||
prev.setWidth(prevWidth - width);
|
||||
prev.setOriginalWidth(prev.getWidth());
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
|
||||
prevWidth = w.getWidth();
|
||||
|
||||
currOpacity -= upperLine ? 3 : 4; // Rough numbers, can't get exactly the same as Jagex because of rounding
|
||||
prev = w;
|
||||
}
|
||||
if (prev != null)
|
||||
{
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* 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.chatboxperformance;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.WidgetPositioned;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetPositionMode;
|
||||
import net.runelite.api.widgets.WidgetSizeMode;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chatbox performance",
|
||||
hidden = true
|
||||
)
|
||||
public class ChatboxPerformancePlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetPositioned(WidgetPositioned event)
|
||||
{
|
||||
if (!areWidgetsFixed())
|
||||
{
|
||||
fixChatbox();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areWidgetsFixed()
|
||||
{
|
||||
Widget widget = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND);
|
||||
if (widget == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Widget[] widgets = widget.getChildren();
|
||||
|
||||
if (widgets != null && widgets.length > 0)
|
||||
{
|
||||
Widget last = widgets[widgets.length - 1];
|
||||
return last != null && last.getOpacity() < 254;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void fixChatbox()
|
||||
{
|
||||
fixDarkBackground();
|
||||
fixWhiteLines(true);
|
||||
fixWhiteLines(false);
|
||||
}
|
||||
|
||||
private void fixDarkBackground()
|
||||
{
|
||||
int currOpacity = 256;
|
||||
int prevY = 0;
|
||||
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_BACKGROUND).getDynamicChildren();
|
||||
Widget prev = null;
|
||||
for (Widget w : children)
|
||||
{
|
||||
if (w.getType() != WidgetType.RECTANGLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev != null)
|
||||
{
|
||||
int relY = w.getRelativeY();
|
||||
prev.setHeightMode(WidgetSizeMode.ABSOLUTE);
|
||||
prev.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
prev.setRelativeY(prevY);
|
||||
prev.setOriginalY(prev.getRelativeY());
|
||||
prev.setHeight(relY - prevY);
|
||||
prev.setOriginalHeight(prev.getHeight());
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
|
||||
prevY = w.getRelativeY();
|
||||
currOpacity -= 3; // Rough number, can't get exactly the same as Jagex because of rounding
|
||||
prev = w;
|
||||
}
|
||||
if (prev != null)
|
||||
{
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
}
|
||||
|
||||
private void fixWhiteLines(boolean upperLine)
|
||||
{
|
||||
int currOpacity = 256;
|
||||
int prevWidth = 0;
|
||||
Widget[] children = client.getWidget(WidgetInfo.CHATBOX_TRANSPARENT_LINES).getDynamicChildren();
|
||||
Widget prev = null;
|
||||
for (Widget w : children)
|
||||
{
|
||||
if (w.getType() != WidgetType.RECTANGLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((w.getRelativeY() == 0 && !upperLine) ||
|
||||
(w.getRelativeY() != 0 && upperLine))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev != null)
|
||||
{
|
||||
int width = w.getWidth();
|
||||
prev.setWidthMode(WidgetSizeMode.ABSOLUTE);
|
||||
prev.setRelativeX(width);
|
||||
prev.setOriginalX(width);
|
||||
prev.setWidth(prevWidth - width);
|
||||
prev.setOriginalWidth(prev.getWidth());
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
|
||||
prevWidth = w.getWidth();
|
||||
|
||||
currOpacity -= upperLine ? 3 : 4; // Rough numbers, can't get exactly the same as Jagex because of rounding
|
||||
prev = w;
|
||||
}
|
||||
if (prev != null)
|
||||
{
|
||||
prev.setOpacity(currOpacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ public class ChatCommandsPlugin extends Plugin
|
||||
* response.
|
||||
*
|
||||
* @param chatMessage The chat message containing the command.
|
||||
* @param message The chat message
|
||||
* @param message The chat message
|
||||
*/
|
||||
private void itemPriceLookup(ChatMessage chatMessage, String message)
|
||||
{
|
||||
@@ -689,17 +689,17 @@ public class ChatCommandsPlugin extends Plugin
|
||||
int itemPrice = item.getPrice();
|
||||
|
||||
final ChatMessageBuilder builder = new ChatMessageBuilder();
|
||||
builder.append(ChatColorType.NORMAL);
|
||||
builder.append(ChatColorType.HIGHLIGHT);
|
||||
builder.append(item.getName());
|
||||
builder.append(ChatColorType.NORMAL);
|
||||
builder.append(": GE ");
|
||||
builder.append(ChatColorType.HIGHLIGHT);
|
||||
builder.append(StackFormatter.formatNumber(itemPrice));
|
||||
builder.append(ChatColorType.NORMAL);
|
||||
builder.append(": OSB ");
|
||||
builder.append(ChatColorType.HIGHLIGHT);
|
||||
builder.append(StackFormatter.formatNumber(osbresult.getOverall_average()));
|
||||
builder.append(ChatColorType.NORMAL);
|
||||
builder.append(ChatColorType.HIGHLIGHT);
|
||||
builder.append(item.getName());
|
||||
builder.append(ChatColorType.NORMAL);
|
||||
builder.append(": GE ");
|
||||
builder.append(ChatColorType.HIGHLIGHT);
|
||||
builder.append(StackFormatter.formatNumber(itemPrice));
|
||||
builder.append(ChatColorType.NORMAL);
|
||||
builder.append(": OSB ");
|
||||
builder.append(ChatColorType.HIGHLIGHT);
|
||||
builder.append(StackFormatter.formatNumber(osbresult.getOverall_average()));
|
||||
|
||||
ItemComposition itemComposition = itemManager.getItemComposition(itemId);
|
||||
if (itemComposition != null)
|
||||
@@ -726,7 +726,7 @@ public class ChatCommandsPlugin extends Plugin
|
||||
* response.
|
||||
*
|
||||
* @param chatMessage The chat message containing the command.
|
||||
* @param message The chat message
|
||||
* @param message The chat message
|
||||
*/
|
||||
private void playerSkillLookup(ChatMessage chatMessage, String message)
|
||||
{
|
||||
|
||||
@@ -1,262 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.chathistory;
|
||||
|
||||
import com.google.common.collect.EvictingQueue;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.Queue;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.VarClientStr;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
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.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chat History",
|
||||
description = "Retain your chat history when logging in/out or world hopping",
|
||||
tags = {"chat", "history", "retain", "cycle", "pm"}
|
||||
)
|
||||
public class ChatHistoryPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape.";
|
||||
private static final String CLEAR_HISTORY = "Clear history";
|
||||
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
|
||||
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
|
||||
private static final int FRIENDS_MAX_SIZE = 5;
|
||||
|
||||
private Queue<QueuedMessage> messageQueue;
|
||||
private Deque<String> friends;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ChatHistoryConfig config;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Provides
|
||||
ChatHistoryConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ChatHistoryConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
messageQueue = EvictingQueue.create(100);
|
||||
friends = new ArrayDeque<>(FRIENDS_MAX_SIZE + 1);
|
||||
keyManager.registerKeyListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
messageQueue.clear();
|
||||
messageQueue = null;
|
||||
friends.clear();
|
||||
friends = null;
|
||||
keyManager.unregisterKeyListener(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
// Start sending old messages right after the welcome message, as that is most reliable source
|
||||
// of information that chat history was reset
|
||||
if (chatMessage.getMessage().equals(WELCOME_MESSAGE))
|
||||
{
|
||||
if (!config.retainChatHistory())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QueuedMessage queuedMessage;
|
||||
|
||||
while ((queuedMessage = messageQueue.poll()) != null)
|
||||
{
|
||||
chatMessageManager.queue(queuedMessage);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (chatMessage.getType())
|
||||
{
|
||||
case PRIVATECHATOUT:
|
||||
case PRIVATECHAT:
|
||||
case MODPRIVATECHAT:
|
||||
final String name = Text.removeTags(chatMessage.getName());
|
||||
// Remove to ensure uniqueness & its place in history
|
||||
if (!friends.remove(name))
|
||||
{
|
||||
// If the friend didn't previously exist ensure deque capacity doesn't increase by adding them
|
||||
if (friends.size() >= FRIENDS_MAX_SIZE)
|
||||
{
|
||||
friends.remove();
|
||||
}
|
||||
}
|
||||
friends.add(name);
|
||||
// intentional fall-through
|
||||
case PUBLICCHAT:
|
||||
case MODCHAT:
|
||||
case FRIENDSCHAT:
|
||||
case CONSOLE:
|
||||
final QueuedMessage queuedMessage = QueuedMessage.builder()
|
||||
.type(chatMessage.getType())
|
||||
.name(chatMessage.getName())
|
||||
.sender(chatMessage.getSender())
|
||||
.value(nbsp(chatMessage.getMessage()))
|
||||
.runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage()))
|
||||
.timestamp(chatMessage.getTimestamp())
|
||||
.build();
|
||||
|
||||
if (!messageQueue.contains(queuedMessage))
|
||||
{
|
||||
messageQueue.offer(queuedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
String menuOption = event.getMenuOption();
|
||||
|
||||
if (menuOption.contains(CLEAR_HISTORY))
|
||||
{
|
||||
if (menuOption.startsWith(CLEAR_PRIVATE))
|
||||
{
|
||||
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PRIVATECHAT ||
|
||||
e.getType() == ChatMessageType.PRIVATECHATOUT || e.getType() == ChatMessageType.MODPRIVATECHAT);
|
||||
friends.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Small hack to prevent plugins checking for specific messages to match
|
||||
* @param message message
|
||||
* @return message with nbsp
|
||||
*/
|
||||
private static String nbsp(final String message)
|
||||
{
|
||||
if (message != null)
|
||||
{
|
||||
return message.replace(' ', '\u00A0');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() != CYCLE_HOTKEY || !config.pmTargetCycling())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.PRIVATE_MESSAGE.getType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
final String target = findPreviousFriend();
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String currentMessage = client.getVar(VarClientStr.INPUT_TEXT);
|
||||
|
||||
client.runScript(ScriptID.OPEN_PRIVATE_MESSAGE_INTERFACE, target);
|
||||
|
||||
client.setVar(VarClientStr.INPUT_TEXT, currentMessage);
|
||||
client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
private String findPreviousFriend()
|
||||
{
|
||||
final String currentTarget = client.getVar(VarClientStr.PRIVATE_MESSAGE_TARGET);
|
||||
if (currentTarget == null || friends.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Iterator<String> it = friends.descendingIterator(); it.hasNext(); )
|
||||
{
|
||||
String friend = it.next();
|
||||
if (friend.equals(currentTarget))
|
||||
{
|
||||
return it.hasNext() ? it.next() : friends.getLast();
|
||||
}
|
||||
}
|
||||
|
||||
return friends.getLast();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.chathistory;
|
||||
|
||||
import com.google.common.collect.EvictingQueue;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.Queue;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.VarClientStr;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
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.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chat History",
|
||||
description = "Retain your chat history when logging in/out or world hopping",
|
||||
tags = {"chat", "history", "retain", "cycle", "pm"}
|
||||
)
|
||||
public class ChatHistoryPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape.";
|
||||
private static final String CLEAR_HISTORY = "Clear history";
|
||||
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
|
||||
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
|
||||
private static final int FRIENDS_MAX_SIZE = 5;
|
||||
|
||||
private Queue<QueuedMessage> messageQueue;
|
||||
private Deque<String> friends;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ChatHistoryConfig config;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Provides
|
||||
ChatHistoryConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ChatHistoryConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
messageQueue = EvictingQueue.create(100);
|
||||
friends = new ArrayDeque<>(FRIENDS_MAX_SIZE + 1);
|
||||
keyManager.registerKeyListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
messageQueue.clear();
|
||||
messageQueue = null;
|
||||
friends.clear();
|
||||
friends = null;
|
||||
keyManager.unregisterKeyListener(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
// Start sending old messages right after the welcome message, as that is most reliable source
|
||||
// of information that chat history was reset
|
||||
if (chatMessage.getMessage().equals(WELCOME_MESSAGE))
|
||||
{
|
||||
if (!config.retainChatHistory())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QueuedMessage queuedMessage;
|
||||
|
||||
while ((queuedMessage = messageQueue.poll()) != null)
|
||||
{
|
||||
chatMessageManager.queue(queuedMessage);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (chatMessage.getType())
|
||||
{
|
||||
case PRIVATECHATOUT:
|
||||
case PRIVATECHAT:
|
||||
case MODPRIVATECHAT:
|
||||
final String name = Text.removeTags(chatMessage.getName());
|
||||
// Remove to ensure uniqueness & its place in history
|
||||
if (!friends.remove(name))
|
||||
{
|
||||
// If the friend didn't previously exist ensure deque capacity doesn't increase by adding them
|
||||
if (friends.size() >= FRIENDS_MAX_SIZE)
|
||||
{
|
||||
friends.remove();
|
||||
}
|
||||
}
|
||||
friends.add(name);
|
||||
// intentional fall-through
|
||||
case PUBLICCHAT:
|
||||
case MODCHAT:
|
||||
case FRIENDSCHAT:
|
||||
case CONSOLE:
|
||||
final QueuedMessage queuedMessage = QueuedMessage.builder()
|
||||
.type(chatMessage.getType())
|
||||
.name(chatMessage.getName())
|
||||
.sender(chatMessage.getSender())
|
||||
.value(nbsp(chatMessage.getMessage()))
|
||||
.runeLiteFormattedMessage(nbsp(chatMessage.getMessageNode().getRuneLiteFormatMessage()))
|
||||
.timestamp(chatMessage.getTimestamp())
|
||||
.build();
|
||||
|
||||
if (!messageQueue.contains(queuedMessage))
|
||||
{
|
||||
messageQueue.offer(queuedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
String menuOption = event.getMenuOption();
|
||||
|
||||
if (menuOption.contains(CLEAR_HISTORY))
|
||||
{
|
||||
if (menuOption.startsWith(CLEAR_PRIVATE))
|
||||
{
|
||||
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PRIVATECHAT ||
|
||||
e.getType() == ChatMessageType.PRIVATECHATOUT || e.getType() == ChatMessageType.MODPRIVATECHAT);
|
||||
friends.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Small hack to prevent plugins checking for specific messages to match
|
||||
*
|
||||
* @param message message
|
||||
* @return message with nbsp
|
||||
*/
|
||||
private static String nbsp(final String message)
|
||||
{
|
||||
if (message != null)
|
||||
{
|
||||
return message.replace(' ', '\u00A0');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() != CYCLE_HOTKEY || !config.pmTargetCycling())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.PRIVATE_MESSAGE.getType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
final String target = findPreviousFriend();
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String currentMessage = client.getVar(VarClientStr.INPUT_TEXT);
|
||||
|
||||
client.runScript(ScriptID.OPEN_PRIVATE_MESSAGE_INTERFACE, target);
|
||||
|
||||
client.setVar(VarClientStr.INPUT_TEXT, currentMessage);
|
||||
client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
private String findPreviousFriend()
|
||||
{
|
||||
final String currentTarget = client.getVar(VarClientStr.PRIVATE_MESSAGE_TARGET);
|
||||
if (currentTarget == null || friends.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Iterator<String> it = friends.descendingIterator(); it.hasNext(); )
|
||||
{
|
||||
String friend = it.next();
|
||||
if (friend.equals(currentTarget))
|
||||
{
|
||||
return it.hasNext() ? it.next() : friends.getLast();
|
||||
}
|
||||
}
|
||||
|
||||
return friends.getLast();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,231 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Hydrox6 <ikada@protonmail.ch>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.chatnotifications;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import static java.util.regex.Pattern.quote;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chat Notifications",
|
||||
description = "Highlight and notify you of chat messages",
|
||||
tags = {"duel", "messages", "notifications", "trade", "username"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class ChatNotificationsPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ChatNotificationsConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private RuneLiteProperties runeLiteProperties;
|
||||
|
||||
//Custom Highlights
|
||||
private Pattern usernameMatcher = null;
|
||||
private String usernameReplacer = "";
|
||||
private Pattern highlightMatcher = null;
|
||||
|
||||
@Provides
|
||||
ChatNotificationsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ChatNotificationsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
updateHighlights();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
switch (event.getGameState())
|
||||
{
|
||||
case LOGIN_SCREEN:
|
||||
case HOPPING:
|
||||
usernameMatcher = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("chatnotification"))
|
||||
{
|
||||
updateHighlights();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHighlights()
|
||||
{
|
||||
highlightMatcher = null;
|
||||
|
||||
if (!config.highlightWordsString().trim().equals(""))
|
||||
{
|
||||
List<String> items = Text.fromCSV(config.highlightWordsString());
|
||||
String joined = items.stream()
|
||||
.map(Pattern::quote)
|
||||
.collect(Collectors.joining("|"));
|
||||
highlightMatcher = Pattern.compile("\\b(" + joined + ")\\b", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
MessageNode messageNode = chatMessage.getMessageNode();
|
||||
String nodeValue = Text.removeTags(messageNode.getValue());
|
||||
boolean update = false;
|
||||
|
||||
switch (chatMessage.getType())
|
||||
{
|
||||
case TRADEREQ:
|
||||
if (chatMessage.getMessage().contains("wishes to trade with you.") && config.notifyOnTrade())
|
||||
{
|
||||
notifier.notify(chatMessage.getMessage());
|
||||
}
|
||||
break;
|
||||
case CHALREQ_TRADE:
|
||||
if (chatMessage.getMessage().contains("wishes to duel with you.") && config.notifyOnDuel())
|
||||
{
|
||||
notifier.notify(chatMessage.getMessage());
|
||||
}
|
||||
break;
|
||||
case CONSOLE:
|
||||
// Don't notify for notification messages
|
||||
if (chatMessage.getName().equals(runeLiteProperties.getTitle()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (usernameMatcher == null && client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
|
||||
{
|
||||
String username = client.getLocalPlayer().getName();
|
||||
usernameMatcher = Pattern.compile("\\b(" + quote(username) + ")\\b", Pattern.CASE_INSENSITIVE);
|
||||
usernameReplacer = "<col" + ChatColorType.HIGHLIGHT.name() + "><u>" + username + "</u><col" + ChatColorType.NORMAL.name() + ">";
|
||||
}
|
||||
|
||||
if (config.highlightOwnName() && usernameMatcher != null)
|
||||
{
|
||||
Matcher matcher = usernameMatcher.matcher(messageNode.getValue());
|
||||
if (matcher.find())
|
||||
{
|
||||
messageNode.setValue(matcher.replaceAll(usernameReplacer));
|
||||
update = true;
|
||||
|
||||
if (config.notifyOnOwnName())
|
||||
{
|
||||
sendNotification(chatMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightMatcher != null)
|
||||
{
|
||||
Matcher matcher = highlightMatcher.matcher(nodeValue);
|
||||
boolean found = false;
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
while (matcher.find())
|
||||
{
|
||||
String value = matcher.group();
|
||||
matcher.appendReplacement(stringBuffer, "<col" + ChatColorType.HIGHLIGHT + ">" + value + "<col" + ChatColorType.NORMAL + ">");
|
||||
update = true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
matcher.appendTail(stringBuffer);
|
||||
messageNode.setValue(stringBuffer.toString());
|
||||
|
||||
if (config.notifyOnHighlight())
|
||||
{
|
||||
sendNotification(chatMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
messageNode.setRuneLiteFormatMessage(messageNode.getValue());
|
||||
chatMessageManager.update(messageNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotification(ChatMessage message)
|
||||
{
|
||||
String name = Text.removeTags(message.getName());
|
||||
String sender = message.getSender();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if (!Strings.isNullOrEmpty(sender))
|
||||
{
|
||||
stringBuilder.append('[').append(sender).append("] ");
|
||||
}
|
||||
|
||||
if (!Strings.isNullOrEmpty(name))
|
||||
{
|
||||
stringBuilder.append(name).append(": ");
|
||||
}
|
||||
|
||||
stringBuilder.append(Text.removeTags(message.getMessage()));
|
||||
String notification = stringBuilder.toString();
|
||||
notifier.notify(notification);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Hydrox6 <ikada@protonmail.ch>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.chatnotifications;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import static java.util.regex.Pattern.quote;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chat Notifications",
|
||||
description = "Highlight and notify you of chat messages",
|
||||
tags = {"duel", "messages", "notifications", "trade", "username"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class ChatNotificationsPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ChatNotificationsConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private RuneLiteProperties runeLiteProperties;
|
||||
|
||||
//Custom Highlights
|
||||
private Pattern usernameMatcher = null;
|
||||
private String usernameReplacer = "";
|
||||
private Pattern highlightMatcher = null;
|
||||
|
||||
@Provides
|
||||
ChatNotificationsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ChatNotificationsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
updateHighlights();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
switch (event.getGameState())
|
||||
{
|
||||
case LOGIN_SCREEN:
|
||||
case HOPPING:
|
||||
usernameMatcher = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("chatnotification"))
|
||||
{
|
||||
updateHighlights();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHighlights()
|
||||
{
|
||||
highlightMatcher = null;
|
||||
|
||||
if (!config.highlightWordsString().trim().equals(""))
|
||||
{
|
||||
List<String> items = Text.fromCSV(config.highlightWordsString());
|
||||
String joined = items.stream()
|
||||
.map(Pattern::quote)
|
||||
.collect(Collectors.joining("|"));
|
||||
highlightMatcher = Pattern.compile("\\b(" + joined + ")\\b", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
MessageNode messageNode = chatMessage.getMessageNode();
|
||||
String nodeValue = Text.removeTags(messageNode.getValue());
|
||||
boolean update = false;
|
||||
|
||||
switch (chatMessage.getType())
|
||||
{
|
||||
case TRADEREQ:
|
||||
if (chatMessage.getMessage().contains("wishes to trade with you.") && config.notifyOnTrade())
|
||||
{
|
||||
notifier.notify(chatMessage.getMessage());
|
||||
}
|
||||
break;
|
||||
case CHALREQ_TRADE:
|
||||
if (chatMessage.getMessage().contains("wishes to duel with you.") && config.notifyOnDuel())
|
||||
{
|
||||
notifier.notify(chatMessage.getMessage());
|
||||
}
|
||||
break;
|
||||
case CONSOLE:
|
||||
// Don't notify for notification messages
|
||||
if (chatMessage.getName().equals(runeLiteProperties.getTitle()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (usernameMatcher == null && client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
|
||||
{
|
||||
String username = client.getLocalPlayer().getName();
|
||||
usernameMatcher = Pattern.compile("\\b(" + quote(username) + ")\\b", Pattern.CASE_INSENSITIVE);
|
||||
usernameReplacer = "<col" + ChatColorType.HIGHLIGHT.name() + "><u>" + username + "</u><col" + ChatColorType.NORMAL.name() + ">";
|
||||
}
|
||||
|
||||
if (config.highlightOwnName() && usernameMatcher != null)
|
||||
{
|
||||
Matcher matcher = usernameMatcher.matcher(messageNode.getValue());
|
||||
if (matcher.find())
|
||||
{
|
||||
messageNode.setValue(matcher.replaceAll(usernameReplacer));
|
||||
update = true;
|
||||
|
||||
if (config.notifyOnOwnName())
|
||||
{
|
||||
sendNotification(chatMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightMatcher != null)
|
||||
{
|
||||
Matcher matcher = highlightMatcher.matcher(nodeValue);
|
||||
boolean found = false;
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
while (matcher.find())
|
||||
{
|
||||
String value = matcher.group();
|
||||
matcher.appendReplacement(stringBuffer, "<col" + ChatColorType.HIGHLIGHT + ">" + value + "<col" + ChatColorType.NORMAL + ">");
|
||||
update = true;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
matcher.appendTail(stringBuffer);
|
||||
messageNode.setValue(stringBuffer.toString());
|
||||
|
||||
if (config.notifyOnHighlight())
|
||||
{
|
||||
sendNotification(chatMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
messageNode.setRuneLiteFormatMessage(messageNode.getValue());
|
||||
chatMessageManager.update(messageNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotification(ChatMessage message)
|
||||
{
|
||||
String name = Text.removeTags(message.getName());
|
||||
String sender = message.getSender();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if (!Strings.isNullOrEmpty(sender))
|
||||
{
|
||||
stringBuilder.append('[').append(sender).append("] ");
|
||||
}
|
||||
|
||||
if (!Strings.isNullOrEmpty(name))
|
||||
{
|
||||
stringBuilder.append(name).append(": ");
|
||||
}
|
||||
|
||||
stringBuilder.append(Text.removeTags(message.getMessage()));
|
||||
String notification = stringBuilder.toString();
|
||||
notifier.notify(notification);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,11 @@ import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatLineBuffer;
|
||||
@@ -49,9 +47,7 @@ import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Opcodes;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Script;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.VarClientStr;
|
||||
@@ -65,10 +61,7 @@ import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.PlayerDespawned;
|
||||
import net.runelite.api.events.PlayerSpawned;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.events.VarClientStrChanged;
|
||||
import net.runelite.api.events.WidgetMenuOptionClicked;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
@@ -78,8 +71,6 @@ import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.menus.WidgetMenuOption;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
|
||||
@@ -120,16 +111,13 @@ public class ClanChatPlugin extends Plugin
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private MenuManager menuManager;
|
||||
|
||||
private List<String> chats = new ArrayList<>();
|
||||
|
||||
|
||||
public static CopyOnWriteArrayList<Player> getClanMembers()
|
||||
{
|
||||
return (CopyOnWriteArrayList<Player>) clanMembers.clone();
|
||||
}
|
||||
|
||||
|
||||
private static CopyOnWriteArrayList<Player> clanMembers = new CopyOnWriteArrayList<>();
|
||||
private ClanChatIndicator clanMemberCounter;
|
||||
/**
|
||||
@@ -139,8 +127,6 @@ public class ClanChatPlugin extends Plugin
|
||||
private Map<String, ClanMemberActivity> activityBuffer = new HashMap<>();
|
||||
private int clanJoinedTick;
|
||||
|
||||
private ConcurrentHashMap<Widget, WidgetMenuOption> ccWidgetMap = new ConcurrentHashMap<Widget, WidgetMenuOption>();
|
||||
|
||||
@Provides
|
||||
ClanChatConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -561,13 +547,14 @@ public class ClanChatPlugin extends Plugin
|
||||
private void loadClanChats()
|
||||
{
|
||||
Widget clanChatList = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
|
||||
clanChatList.setScrollHeight( 14 * chats.size());
|
||||
clanChatList.revalidateScroll();
|
||||
if (clanChatList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clanChatList.setScrollHeight(14 * chats.size());
|
||||
clanChatList.revalidateScroll();
|
||||
|
||||
int y = 2;
|
||||
clanChatList.setChildren(null);
|
||||
for (String chat : Lists.reverse(chats))
|
||||
|
||||
@@ -7,7 +7,6 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -49,7 +48,8 @@ public class ClanManModeOverlay extends Overlay
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
if (config.getClanAttackableColor().equals(color) && config.ShowBold()) {
|
||||
if (config.getClanAttackableColor().equals(color) && config.ShowBold())
|
||||
{
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
|
||||
@@ -70,14 +70,16 @@ public class ClanManModePlugin extends Plugin
|
||||
Map<String, Integer> clan = new HashMap<>();
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(ClanManModeOverlay);
|
||||
overlayManager.add(ClanManModeTileOverlay);
|
||||
overlayManager.add(ClanManModeMinimapOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(ClanManModeOverlay);
|
||||
overlayManager.remove(ClanManModeTileOverlay);
|
||||
overlayManager.remove(ClanManModeMinimapOverlay);
|
||||
@@ -90,17 +92,21 @@ public class ClanManModePlugin extends Plugin
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged) {
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) {
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING)
|
||||
{
|
||||
ticks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event) {
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
ticks++;
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
if (!clan.containsKey(localPlayer.getName())) {
|
||||
if (!clan.containsKey(localPlayer.getName()))
|
||||
{
|
||||
clan.put(localPlayer.getName(), localPlayer.getCombatLevel());
|
||||
}
|
||||
WorldPoint a = localPlayer.getWorldLocation();
|
||||
@@ -108,30 +114,38 @@ public class ClanManModePlugin extends Plugin
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
inwildy = client.getVar(Varbits.IN_WILDERNESS);
|
||||
if (clan.size() > 0) {
|
||||
if (clan.size() > 0)
|
||||
{
|
||||
clanmin = Collections.min(clan.values());
|
||||
clanmax = Collections.max(clan.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
if (!config.hideAtkOpt()) {
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (!config.hideAtkOpt())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
|
||||
if (option.equals("attack")) {
|
||||
if (option.equals("attack"))
|
||||
{
|
||||
final Pattern ppattern = Pattern.compile("<col=ffffff>(.+?)<col=");
|
||||
final Matcher pmatch = ppattern.matcher(event.getTarget());
|
||||
|
||||
if (pmatch.find() && pmatch.matches()) {
|
||||
if (pmatch.group(1) != null) {
|
||||
if (clan.containsKey(pmatch.group(1).replace(" ", " "))) {
|
||||
if (pmatch.find() && pmatch.matches())
|
||||
{
|
||||
if (pmatch.group(1) != null)
|
||||
{
|
||||
if (clan.containsKey(pmatch.group(1).replace(" ", " ")))
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
entries = ArrayUtils.removeElement(entries, entries[entries.length - 1]);
|
||||
client.setMenuEntries(entries);
|
||||
|
||||
@@ -39,52 +39,70 @@ public class ClanManModeService
|
||||
int selfmax = localPlayer.getCombatLevel() + plugin.wildernessLevel;
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
if (player == null || player.getName() == null) {
|
||||
if (player == null || player.getName() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player == localPlayer) {
|
||||
if (player == localPlayer)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isClanMember = player.isClanMember();
|
||||
Actor interacting = player.getInteracting();
|
||||
Player interactor = null;
|
||||
if (interacting != null && !(interacting instanceof NPC)) {
|
||||
if (interacting != null && !(interacting instanceof NPC))
|
||||
{
|
||||
interactor = ((Player) interacting);
|
||||
}
|
||||
|
||||
if (config.showAttackers()) {
|
||||
if (interactor != null) {
|
||||
if (interactor.getName().equals(localName)) {
|
||||
if (config.showAttackers())
|
||||
{
|
||||
if (interactor != null)
|
||||
{
|
||||
if (interactor.getName().equals(localName))
|
||||
{
|
||||
consumer.accept(player, config.getAttackerColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.inwildy == 1) {
|
||||
if (isClanMember) {
|
||||
if (!plugin.clan.containsKey(player.getName())) {
|
||||
if (plugin.inwildy == 1)
|
||||
{
|
||||
if (isClanMember)
|
||||
{
|
||||
if (!plugin.clan.containsKey(player.getName()))
|
||||
{
|
||||
plugin.clan.put(player.getName(), player.getCombatLevel());
|
||||
}
|
||||
if (config.highlightAttacked()) {
|
||||
if (interactor != null) {
|
||||
if (!interactors.containsKey(interactor.getName())) {
|
||||
if (config.highlightAttacked())
|
||||
{
|
||||
if (interactor != null)
|
||||
{
|
||||
if (!interactors.containsKey(interactor.getName()))
|
||||
{
|
||||
WorldPoint a = interactor.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
int wildydiff = plugin.wildernessLevel - wildernessLevel;
|
||||
if (wildydiff < 0) {
|
||||
if (wildydiff < 0)
|
||||
{
|
||||
wildydiff = 0;
|
||||
}
|
||||
if (config.CalcSelfCB()) {
|
||||
if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember()) {
|
||||
if (config.CalcSelfCB())
|
||||
{
|
||||
if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember())
|
||||
{
|
||||
interactors.put(interactor.getName(), player.getName());
|
||||
consumer.accept(interactor, config.getClanAttackableColor());
|
||||
}
|
||||
} else {
|
||||
if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember())
|
||||
{
|
||||
interactors.put(interactor.getName(), player.getName());
|
||||
consumer.accept(interactor, config.getClanAttackableColor());
|
||||
}
|
||||
@@ -92,43 +110,61 @@ public class ClanManModeService
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (config.PersistentClan()) {
|
||||
if (plugin.clan.containsKey(player.getName())) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config.PersistentClan())
|
||||
{
|
||||
if (plugin.clan.containsKey(player.getName()))
|
||||
{
|
||||
consumer.accept(player, config.getClanMemberColor());
|
||||
}
|
||||
}
|
||||
if (config.highlightAttacked()) {
|
||||
if (interactors.containsKey(player.getName())) {
|
||||
if (config.highlightAttacked())
|
||||
{
|
||||
if (interactors.containsKey(player.getName()))
|
||||
{
|
||||
String attackername = interactors.get(player.getName());
|
||||
boolean found = false;
|
||||
for (Player attacker : client.getPlayers()) {
|
||||
if (attacker == null || attacker.getName() == null) {
|
||||
for (Player attacker : client.getPlayers())
|
||||
{
|
||||
if (attacker == null || attacker.getName() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (attacker.getName().equals(attackername)) {
|
||||
if (attacker.getName().equals(attackername))
|
||||
{
|
||||
found = true;
|
||||
Actor ainteract = attacker.getInteracting();
|
||||
if (ainteract != null) {
|
||||
if (ainteract.getName().equals(player.getName())) {
|
||||
if (ainteract != null)
|
||||
{
|
||||
if (ainteract.getName().equals(player.getName()))
|
||||
{
|
||||
consumer.accept(player, config.getClanAttackableColor());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (!found)
|
||||
{
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (config.highlightAttackable()) {
|
||||
if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName())) {
|
||||
if (config.highlightAttackable())
|
||||
{
|
||||
if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WorldPoint a = player.getWorldLocation();
|
||||
@@ -136,15 +172,21 @@ public class ClanManModeService
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
int wildydiff = plugin.wildernessLevel - wildernessLevel;
|
||||
if (wildydiff < 0) {
|
||||
if (wildydiff < 0)
|
||||
{
|
||||
wildydiff = 0;
|
||||
}
|
||||
if (config.CalcSelfCB()) {
|
||||
if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin) {
|
||||
if (config.CalcSelfCB())
|
||||
{
|
||||
if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin)
|
||||
{
|
||||
consumer.accept(player, config.getAttackableColor());
|
||||
}
|
||||
} else {
|
||||
if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk)
|
||||
{
|
||||
consumer.accept(player, config.getAttackableColor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,7 +749,7 @@ public class ClueScrollPlugin extends Plugin
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
|
||||
void scrollToWidget(WidgetInfo list, WidgetInfo scrollbar, Widget ... toHighlight)
|
||||
void scrollToWidget(WidgetInfo list, WidgetInfo scrollbar, Widget... toHighlight)
|
||||
{
|
||||
final Widget parent = client.getWidget(list);
|
||||
int averageCentralY = 0;
|
||||
|
||||
@@ -267,12 +267,12 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
@Override
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[] {npc};
|
||||
return new String[]{npc};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getObjectIds()
|
||||
{
|
||||
return new int[] {objectId};
|
||||
return new int[]{objectId};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,6 @@ public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScr
|
||||
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[] {npc};
|
||||
return new String[]{npc};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,56 @@ import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import static net.runelite.api.NullObjectID.NULL_1293;
|
||||
import net.runelite.api.ObjectComposition;
|
||||
import static net.runelite.api.ObjectID.*;
|
||||
import static net.runelite.api.ObjectID.BOOKCASE_12539;
|
||||
import static net.runelite.api.ObjectID.BOOKCASE_380;
|
||||
import static net.runelite.api.ObjectID.BOOKCASE_394;
|
||||
import static net.runelite.api.ObjectID.BOOKCASE_9523;
|
||||
import static net.runelite.api.ObjectID.BOXES;
|
||||
import static net.runelite.api.ObjectID.BOXES_360;
|
||||
import static net.runelite.api.ObjectID.BOXES_361;
|
||||
import static net.runelite.api.ObjectID.BOXES_3686;
|
||||
import static net.runelite.api.ObjectID.BOXES_5111;
|
||||
import static net.runelite.api.ObjectID.BOXES_6176;
|
||||
import static net.runelite.api.ObjectID.BUCKET_9568;
|
||||
import static net.runelite.api.ObjectID.BUSH_2357;
|
||||
import static net.runelite.api.ObjectID.CLOSED_CHEST_25592;
|
||||
import static net.runelite.api.ObjectID.CLOSED_CHEST_375;
|
||||
import static net.runelite.api.ObjectID.CLOSED_CHEST_5108;
|
||||
import static net.runelite.api.ObjectID.COFFIN;
|
||||
import static net.runelite.api.ObjectID.CRATES_11600;
|
||||
import static net.runelite.api.ObjectID.CRATES_24088;
|
||||
import static net.runelite.api.ObjectID.CRATE_11485;
|
||||
import static net.runelite.api.ObjectID.CRATE_12963;
|
||||
import static net.runelite.api.ObjectID.CRATE_18204;
|
||||
import static net.runelite.api.ObjectID.CRATE_18506;
|
||||
import static net.runelite.api.ObjectID.CRATE_18889;
|
||||
import static net.runelite.api.ObjectID.CRATE_24344;
|
||||
import static net.runelite.api.ObjectID.CRATE_25775;
|
||||
import static net.runelite.api.ObjectID.CRATE_26635;
|
||||
import static net.runelite.api.ObjectID.CRATE_27532;
|
||||
import static net.runelite.api.ObjectID.CRATE_27533;
|
||||
import static net.runelite.api.ObjectID.CRATE_354;
|
||||
import static net.runelite.api.ObjectID.CRATE_355;
|
||||
import static net.runelite.api.ObjectID.CRATE_356;
|
||||
import static net.runelite.api.ObjectID.CRATE_357;
|
||||
import static net.runelite.api.ObjectID.CRATE_358;
|
||||
import static net.runelite.api.ObjectID.CRATE_366;
|
||||
import static net.runelite.api.ObjectID.CRATE_5106;
|
||||
import static net.runelite.api.ObjectID.CRATE_5107;
|
||||
import static net.runelite.api.ObjectID.CRATE_5113;
|
||||
import static net.runelite.api.ObjectID.CRATE_9534;
|
||||
import static net.runelite.api.ObjectID.DRAWERS;
|
||||
import static net.runelite.api.ObjectID.DRAWERS_25766;
|
||||
import static net.runelite.api.ObjectID.DRAWERS_350;
|
||||
import static net.runelite.api.ObjectID.DRAWERS_352;
|
||||
import static net.runelite.api.ObjectID.DRAWERS_5618;
|
||||
import static net.runelite.api.ObjectID.DRAWERS_7194;
|
||||
import static net.runelite.api.ObjectID.HAYSTACK;
|
||||
import static net.runelite.api.ObjectID.JUNA;
|
||||
import static net.runelite.api.ObjectID.MINE_CART_6045;
|
||||
import static net.runelite.api.ObjectID.STONES_26633;
|
||||
import static net.runelite.api.ObjectID.WARDROBE_5622;
|
||||
import static net.runelite.api.ObjectID.WHEELBARROW_9625;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
@@ -116,7 +165,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("Probably filled with wizards socks.", "Wizard", DRAWERS_350, new WorldPoint(3116, 9562, 0), "Search the drawers in the basement of the Wizard's Tower south of Draynor Village. Kill one of the Wizards for the key. Fairy ring DIS"),
|
||||
new CrypticClue("Even the seers say this clue goes right over their heads.", CRATE_26635, new WorldPoint(2707, 3488, 2), "Search the crate on the Seers Agility Course in Seers Village"),
|
||||
new CrypticClue("Speak to a Wyse man.", "Wyson the gardener", new WorldPoint(3026, 3378, 0), "Talk to Wyson the gardener at Falador Park."),
|
||||
new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", "Monk" , CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."),
|
||||
new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", "Monk", CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."),
|
||||
new CrypticClue("Talk to Ambassador Spanfipple in the White Knights Castle.", "Ambassador Spanfipple", new WorldPoint(2979, 3340, 0), "Ambassador Spanfipple can be found roaming on the first floor of the White Knights Castle."),
|
||||
new CrypticClue("Mine was the strangest birth under the sun. I left the crimson sack, yet life had not begun. Entered the world, and yet was seen by none.", new WorldPoint(2832, 9586, 0), "Inside Karamja Volcano, dig directly underneath the Red spiders' eggs respawn."),
|
||||
new CrypticClue("Search for a crate in Varrock Castle.", CRATE_5113, new WorldPoint(3224, 3492, 0), "Search the crate in the corner of the kitchen in Varrock Castle."),
|
||||
@@ -196,13 +245,13 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("Search a bookcase in Lumbridge swamp.", BOOKCASE_9523, new WorldPoint(3146, 3177, 0), "Located in Father Urhney's house."),
|
||||
new CrypticClue("Surround my bones in fire, ontop the wooden pyre. Finally lay me to rest, before my one last test.", null, "Kill a confused/lost barbarian to receive mangled bones. Construct and burn a pyre ship. Kill the ferocious barbarian spirit that spawns to receive a clue casket."),
|
||||
new CrypticClue("Fiendish cooks probably won't dig the dirty dishes.", new WorldPoint(3043, 4974, 1), "Dig by the fire in the Rogues' Den."),
|
||||
new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", "Key Master", new WorldPoint(1310, 1251, 0), "Speak to the Key Master in Cerberus' Lair."),
|
||||
new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", "Key Master", new WorldPoint(1310, 1251, 0), "Speak to the Key Master in Cerberus' Lair."),
|
||||
new CrypticClue("Search the boxes in one of the tents in Al Kharid.", BOXES_361, new WorldPoint(3308, 3206, 0), "Search the boxes in the tent east of the Silk trader."),
|
||||
new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", "Piles", new WorldPoint(3186, 3936, 0), "Speak to Piles in the Wilderness Resource Area. An entry fee of 7,500 coins is required, or less if Wilderness Diaries have been completed."),
|
||||
new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", "Piles", new WorldPoint(3186, 3936, 0), "Speak to Piles in the Wilderness Resource Area. An entry fee of 7,500 coins is required, or less if Wilderness Diaries have been completed."),
|
||||
new CrypticClue("Search the drawers on the first floor of a building overlooking Ardougne's Market.", DRAWERS_352, new WorldPoint(2657, 3322, 1), "Climb the ladder in the house north of the market."),
|
||||
new CrypticClue("'A bag belt only?', he asked his balding brothers.", "Abbot Langley", new WorldPoint(3058, 3487, 0), "Talk-to Abbot Langley in Monastery west of Edgeville"),
|
||||
new CrypticClue("Search the drawers upstairs in Falador's shield shop.", DRAWERS, new WorldPoint(2971, 3386, 1), "Cassie's Shield Shop at the northern Falador entrance."),
|
||||
new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350 , new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."),
|
||||
new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350, new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."),
|
||||
new CrypticClue("Dig near some giant mushrooms, behind the Grand Tree.", new WorldPoint(2458, 3504, 0), "Dig near the red mushrooms northwest of the Grand Tree."),
|
||||
new CrypticClue("Pentagrams and demons, burnt bones and remains, I wonder what the blood contains.", new WorldPoint(3297, 3890, 0), "Dig under the blood rune spawn next the the Demonic Ruins."),
|
||||
new CrypticClue("Search the drawers above Varrock's shops.", DRAWERS_7194, new WorldPoint(3206, 3419, 1), "Located upstairs in Thessalia's Fine Clothes shop in Varrock."),
|
||||
@@ -276,7 +325,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("Ghommal wishes to be impressed by how strong your equipment is.", "Ghommal", new WorldPoint(2878, 3546, 0), "Speak to Ghommal at the Warriors' Guild with a total Melee Strength bonus of over 100."),
|
||||
new CrypticClue("Shhhh!", "Logosia", new WorldPoint(1633, 3808, 0), "Speak to Logosia in the Arceuus Library's ground floor."),
|
||||
new CrypticClue("Salty peter.", "Konoo", new WorldPoint(1703, 3524, 0), "Talk to Konoo who is digging saltpetre in Hosidius, south of the bank."),
|
||||
new CrypticClue("Talk to Zeke in Al Kharid.", "Zeke", new WorldPoint(3287, 3190, 0), "Zeke is the owner of the scimitar shop in Al Kharid."),
|
||||
new CrypticClue("Talk to Zeke in Al Kharid.", "Zeke", new WorldPoint(3287, 3190, 0), "Zeke is the owner of the scimitar shop in Al Kharid."),
|
||||
new CrypticClue("Guthix left his mark in a fiery lake, dig at the tip of it.", new WorldPoint(3069, 3935, 0), "Dig at the tip of the lava lake that is shaped like a Guthixian symbol, west of the Mage Arena."),
|
||||
new CrypticClue("Search the drawers in the upstairs of a house in Catherby.", DRAWERS_350, new WorldPoint(2809, 3451, 1), "Perdu's house in Catherby."),
|
||||
new CrypticClue("Search a crate in the Haymaker's arms.", CRATE_27532, new WorldPoint(1720, 3652, 1), "Search the crate in the north-east corner of The Haymaker's Arms tavern east of Kourend Castle."),
|
||||
@@ -294,9 +343,9 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("Dig in the centre of a great kingdom of 5 cities.", new WorldPoint(1639, 3673, 0), "Dig in front of the large statue in the centre of Great Kourend."),
|
||||
new CrypticClue("Hopefully this set of armour will help you to keep surviving.", "Sir Vyvin", new WorldPoint(2982, 3336, 2), "Speak to Sir Vyvin while wearing a white platebody, and platelegs."),
|
||||
new CrypticClue("The beasts retreat, for their Queen is gone; the song of this town still plays on. Dig near the birthplace of a blade, be careful not to melt your spade.", new WorldPoint(2342, 3677, 0), "Dig in front of the small furnace in the Piscatoris Fishing Colony."),
|
||||
new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", "Biblia", new WorldPoint(1633, 3825, 2), "Speak to Biblia on the Arceuus Library's top floor."),
|
||||
new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", "Biblia", new WorldPoint(1633, 3825, 2), "Speak to Biblia on the Arceuus Library's top floor."),
|
||||
new CrypticClue("I would make a chemistry joke, but I'm afraid I wouldn't get a reaction.", "Chemist", new WorldPoint(2932, 3212, 0), "Talk to the Chemist in Rimmington"),
|
||||
new CrypticClue("Show this to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Hazelmere is found upstairs on the island located just east of Yanille."),
|
||||
new CrypticClue("Show this to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Hazelmere is found upstairs on the island located just east of Yanille."),
|
||||
new CrypticClue("Does one really need a fire to stay warm here?", new WorldPoint(3816, 3810, 0), "Dig next to the fire near the Volcanic Mine entrance."),
|
||||
new CrypticClue("Search the open crate found in a small farmhouse in Hosidius. Cabbages grow outside.", CRATE_27533, new WorldPoint(1687, 3628, 0), "The house is north-east of the general store in Hosidius."),
|
||||
new CrypticClue("Dig under Ithoi's cabin.", new WorldPoint(2529, 2838, 0), "Dig under Ithoi's cabin in the Corsair Cove."),
|
||||
@@ -428,7 +477,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
for (TileObject gameObject : plugin.getObjectsToMark())
|
||||
{
|
||||
OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition,
|
||||
CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR);
|
||||
CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR);
|
||||
|
||||
OverlayUtil.renderImageLocation(plugin.getClient(), graphics, gameObject.getLocalLocation(), plugin.getClueScrollImage(), IMAGE_Z_OFFSET);
|
||||
}
|
||||
@@ -452,12 +501,12 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
@Override
|
||||
public int[] getObjectIds()
|
||||
{
|
||||
return new int[] {objectId};
|
||||
return new int[]{objectId};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[] {npc};
|
||||
return new String[]{npc};
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -184,7 +184,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
|
||||
@Override
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[] {FALO_THE_BARD};
|
||||
return new String[]{FALO_THE_BARD};
|
||||
}
|
||||
|
||||
public static FaloTheBardClue forText(String text)
|
||||
|
||||
@@ -1,411 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Eadgars Ruse <https://github.com/Eadgars-Ruse>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@Getter
|
||||
public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll
|
||||
{
|
||||
private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)");
|
||||
private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\.");
|
||||
private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*");
|
||||
private static final HotColdClue CLUE =
|
||||
new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.",
|
||||
"Jorral",
|
||||
"Speak to Jorral to receive a strange device.");
|
||||
|
||||
// list of potential places to dig
|
||||
private List<HotColdLocation> digLocations = new ArrayList<>();
|
||||
private final String text;
|
||||
private final String npc;
|
||||
private final String solution;
|
||||
private WorldPoint location;
|
||||
private WorldPoint lastWorldPoint;
|
||||
|
||||
public static HotColdClue forText(String text)
|
||||
{
|
||||
if (CLUE.text.equalsIgnoreCase(text))
|
||||
{
|
||||
return CLUE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private HotColdClue(String text, String npc, String solution)
|
||||
{
|
||||
this.text = text;
|
||||
this.npc = npc;
|
||||
this.solution = solution;
|
||||
setRequiresSpade(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldPoint[] getLocations()
|
||||
{
|
||||
return Lists.transform(digLocations, HotColdLocation::getWorldPoint).toArray(new WorldPoint[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Hot/Cold Clue")
|
||||
.build());
|
||||
panelComponent.setPreferredSize(new Dimension(200, 0));
|
||||
|
||||
// strange device has not been tested yet, show how to get it
|
||||
if (lastWorldPoint == null && location == null)
|
||||
{
|
||||
if (getNpc() != null)
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("NPC:")
|
||||
.build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(getNpc())
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Solution:")
|
||||
.build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(getSolution())
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
}
|
||||
// strange device has been tested, show possible locations for final dig spot
|
||||
else
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Possible areas:")
|
||||
.build());
|
||||
Map<HotColdArea, Integer> locationCounts = new HashMap<>();
|
||||
|
||||
for (HotColdLocation hotColdLocation : digLocations)
|
||||
{
|
||||
HotColdArea hotColdArea = hotColdLocation.getHotColdArea();
|
||||
|
||||
if (locationCounts.containsKey(hotColdArea))
|
||||
{
|
||||
locationCounts.put(hotColdArea, locationCounts.get(hotColdArea) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
locationCounts.put(hotColdArea, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (digLocations.size() > 10)
|
||||
{
|
||||
for (HotColdArea area : locationCounts.keySet())
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(area.getName())
|
||||
.right(Integer.toString(locationCounts.get(area)))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (HotColdArea s : locationCounts.keySet())
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(s.getName() + ":")
|
||||
.build());
|
||||
|
||||
for (HotColdLocation hotColdLocation : digLocations)
|
||||
{
|
||||
if (hotColdLocation.getHotColdArea() == s)
|
||||
{
|
||||
Rectangle2D r = hotColdLocation.getRect();
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("- " + hotColdLocation.getArea())
|
||||
.leftColor(Color.LIGHT_GRAY)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
|
||||
{
|
||||
// when final location has been found
|
||||
if (this.location != null)
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation());
|
||||
|
||||
if (localLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// when strange device hasn't been activated yet, show Jorral
|
||||
if (lastWorldPoint == null)
|
||||
{
|
||||
// Mark NPC
|
||||
if (plugin.getNpcsToMark() != null)
|
||||
{
|
||||
for (NPC npc : plugin.getNpcsToMark())
|
||||
{
|
||||
OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// once the number of possible dig locations is below 10, show the dig spots
|
||||
if (digLocations.size() < 10)
|
||||
{
|
||||
// Mark potential dig locations
|
||||
for (HotColdLocation hotColdLocation : digLocations)
|
||||
{
|
||||
WorldPoint wp = hotColdLocation.getWorldPoint();
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), wp.getX(), wp.getY());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean update(final String message, final ClueScrollPlugin plugin)
|
||||
{
|
||||
if (!message.startsWith("The device is"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message);
|
||||
Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message);
|
||||
Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message);
|
||||
|
||||
// the order that these pattern matchers are checked is important
|
||||
if (m1.find())
|
||||
{
|
||||
// final location for hot cold clue has been found
|
||||
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (localWorld != null)
|
||||
{
|
||||
markFinalSpot(localWorld);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (m2.find())
|
||||
{
|
||||
String temperature = m2.group(1);
|
||||
String difference = m2.group(2);
|
||||
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (localWorld != null)
|
||||
{
|
||||
updatePossibleArea(localWorld, temperature, difference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (m3.find())
|
||||
{
|
||||
String temperature = m3.group(1);
|
||||
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (localWorld != null)
|
||||
{
|
||||
updatePossibleArea(localWorld, temperature, "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
this.lastWorldPoint = null;
|
||||
digLocations.clear();
|
||||
}
|
||||
|
||||
private void updatePossibleArea(WorldPoint currentWp, String temperature, String difference)
|
||||
{
|
||||
this.location = null;
|
||||
|
||||
if (digLocations.isEmpty())
|
||||
{
|
||||
digLocations.addAll(Arrays.asList(HotColdLocation.values()));
|
||||
}
|
||||
|
||||
int maxSquaresAway = 5000;
|
||||
int minSquaresAway = 0;
|
||||
|
||||
switch (temperature)
|
||||
{
|
||||
// when the strange device reads a temperature, that means that the center of the final dig location
|
||||
// is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance)
|
||||
case "ice cold":
|
||||
maxSquaresAway = 5000;
|
||||
minSquaresAway = 500;
|
||||
break;
|
||||
case "very cold":
|
||||
maxSquaresAway = 499;
|
||||
minSquaresAway = 200;
|
||||
break;
|
||||
case "cold":
|
||||
maxSquaresAway = 199;
|
||||
minSquaresAway = 150;
|
||||
break;
|
||||
case "warm":
|
||||
maxSquaresAway = 149;
|
||||
minSquaresAway = 100;
|
||||
break;
|
||||
case "hot":
|
||||
maxSquaresAway = 99;
|
||||
minSquaresAway = 70;
|
||||
break;
|
||||
case "very hot":
|
||||
maxSquaresAway = 69;
|
||||
minSquaresAway = 30;
|
||||
break;
|
||||
case "incredibly hot":
|
||||
maxSquaresAway = 29;
|
||||
minSquaresAway = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
// rectangle r1 encompasses all of the points that are within the max possible distance from the player
|
||||
Point p1 = new Point(currentWp.getX() - maxSquaresAway, currentWp.getY() - maxSquaresAway);
|
||||
Rectangle r1 = new Rectangle((int) p1.getX(), (int) p1.getY(), 2 * maxSquaresAway + 1, 2 * maxSquaresAway + 1);
|
||||
// rectangle r2 encompasses all of the points that are within the min possible distance from the player
|
||||
Point p2 = new Point(currentWp.getX() - minSquaresAway, currentWp.getY() - minSquaresAway);
|
||||
Rectangle r2 = new Rectangle((int) p2.getX(), (int) p2.getY(), 2 * minSquaresAway + 1, 2 * minSquaresAway + 1);
|
||||
|
||||
// eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range
|
||||
digLocations.removeIf(entry -> r2.contains(entry.getRect()) || !r1.intersects(entry.getRect()));
|
||||
|
||||
// if a previous world point has been recorded, we can consider the warmer/colder result from the strange device
|
||||
if (lastWorldPoint != null)
|
||||
{
|
||||
switch (difference)
|
||||
{
|
||||
case "but colder than":
|
||||
// eliminate spots that are absolutely warmer
|
||||
digLocations.removeIf(entry -> isFirstPointCloserRect(currentWp, lastWorldPoint, entry.getRect()));
|
||||
break;
|
||||
case "and warmer than":
|
||||
// eliminate spots that are absolutely colder
|
||||
digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, currentWp, entry.getRect()));
|
||||
break;
|
||||
case "and the same temperature as":
|
||||
// I couldn't figure out a clean implementation for this case
|
||||
// not necessary for quickly determining final location
|
||||
}
|
||||
}
|
||||
|
||||
lastWorldPoint = currentWp;
|
||||
}
|
||||
|
||||
private boolean isFirstPointCloserRect(WorldPoint firstWp, WorldPoint secondWp, Rectangle2D r)
|
||||
{
|
||||
WorldPoint p1 = new WorldPoint((int) r.getMaxX(), (int) r.getMaxY(), 0);
|
||||
|
||||
if (!isFirstPointCloser(firstWp, secondWp, p1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint p2 = new WorldPoint((int) r.getMaxX(), (int) r.getMinY(), 0);
|
||||
|
||||
if (!isFirstPointCloser(firstWp, secondWp, p2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint p3 = new WorldPoint((int) r.getMinX(), (int)r.getMaxY(), 0);
|
||||
|
||||
if (!isFirstPointCloser(firstWp, secondWp, p3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint p4 = new WorldPoint((int) r.getMinX(), (int) r.getMinY(), 0);
|
||||
return (isFirstPointCloser(firstWp, secondWp, p4));
|
||||
}
|
||||
|
||||
private boolean isFirstPointCloser(WorldPoint firstWp, WorldPoint secondWp, WorldPoint wp)
|
||||
{
|
||||
int firstDistance = firstWp.distanceTo2D(wp);
|
||||
int secondDistance = secondWp.distanceTo2D(wp);
|
||||
return (firstDistance < secondDistance);
|
||||
}
|
||||
|
||||
private void markFinalSpot(WorldPoint wp)
|
||||
{
|
||||
this.location = wp;
|
||||
reset();
|
||||
}
|
||||
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[] {npc};
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Eadgars Ruse <https://github.com/Eadgars-Ruse>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@Getter
|
||||
public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll
|
||||
{
|
||||
private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)");
|
||||
private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\.");
|
||||
private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*");
|
||||
private static final HotColdClue CLUE =
|
||||
new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.",
|
||||
"Jorral",
|
||||
"Speak to Jorral to receive a strange device.");
|
||||
|
||||
// list of potential places to dig
|
||||
private List<HotColdLocation> digLocations = new ArrayList<>();
|
||||
private final String text;
|
||||
private final String npc;
|
||||
private final String solution;
|
||||
private WorldPoint location;
|
||||
private WorldPoint lastWorldPoint;
|
||||
|
||||
public static HotColdClue forText(String text)
|
||||
{
|
||||
if (CLUE.text.equalsIgnoreCase(text))
|
||||
{
|
||||
return CLUE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private HotColdClue(String text, String npc, String solution)
|
||||
{
|
||||
this.text = text;
|
||||
this.npc = npc;
|
||||
this.solution = solution;
|
||||
setRequiresSpade(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldPoint[] getLocations()
|
||||
{
|
||||
return Lists.transform(digLocations, HotColdLocation::getWorldPoint).toArray(new WorldPoint[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Hot/Cold Clue")
|
||||
.build());
|
||||
panelComponent.setPreferredSize(new Dimension(200, 0));
|
||||
|
||||
// strange device has not been tested yet, show how to get it
|
||||
if (lastWorldPoint == null && location == null)
|
||||
{
|
||||
if (getNpc() != null)
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("NPC:")
|
||||
.build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(getNpc())
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Solution:")
|
||||
.build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(getSolution())
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
}
|
||||
// strange device has been tested, show possible locations for final dig spot
|
||||
else
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Possible areas:")
|
||||
.build());
|
||||
Map<HotColdArea, Integer> locationCounts = new HashMap<>();
|
||||
|
||||
for (HotColdLocation hotColdLocation : digLocations)
|
||||
{
|
||||
HotColdArea hotColdArea = hotColdLocation.getHotColdArea();
|
||||
|
||||
if (locationCounts.containsKey(hotColdArea))
|
||||
{
|
||||
locationCounts.put(hotColdArea, locationCounts.get(hotColdArea) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
locationCounts.put(hotColdArea, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (digLocations.size() > 10)
|
||||
{
|
||||
for (HotColdArea area : locationCounts.keySet())
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(area.getName())
|
||||
.right(Integer.toString(locationCounts.get(area)))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (HotColdArea s : locationCounts.keySet())
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(s.getName() + ":")
|
||||
.build());
|
||||
|
||||
for (HotColdLocation hotColdLocation : digLocations)
|
||||
{
|
||||
if (hotColdLocation.getHotColdArea() == s)
|
||||
{
|
||||
Rectangle2D r = hotColdLocation.getRect();
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("- " + hotColdLocation.getArea())
|
||||
.leftColor(Color.LIGHT_GRAY)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
|
||||
{
|
||||
// when final location has been found
|
||||
if (this.location != null)
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation());
|
||||
|
||||
if (localLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// when strange device hasn't been activated yet, show Jorral
|
||||
if (lastWorldPoint == null)
|
||||
{
|
||||
// Mark NPC
|
||||
if (plugin.getNpcsToMark() != null)
|
||||
{
|
||||
for (NPC npc : plugin.getNpcsToMark())
|
||||
{
|
||||
OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// once the number of possible dig locations is below 10, show the dig spots
|
||||
if (digLocations.size() < 10)
|
||||
{
|
||||
// Mark potential dig locations
|
||||
for (HotColdLocation hotColdLocation : digLocations)
|
||||
{
|
||||
WorldPoint wp = hotColdLocation.getWorldPoint();
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), wp.getX(), wp.getY());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean update(final String message, final ClueScrollPlugin plugin)
|
||||
{
|
||||
if (!message.startsWith("The device is"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message);
|
||||
Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message);
|
||||
Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message);
|
||||
|
||||
// the order that these pattern matchers are checked is important
|
||||
if (m1.find())
|
||||
{
|
||||
// final location for hot cold clue has been found
|
||||
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (localWorld != null)
|
||||
{
|
||||
markFinalSpot(localWorld);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (m2.find())
|
||||
{
|
||||
String temperature = m2.group(1);
|
||||
String difference = m2.group(2);
|
||||
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (localWorld != null)
|
||||
{
|
||||
updatePossibleArea(localWorld, temperature, difference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (m3.find())
|
||||
{
|
||||
String temperature = m3.group(1);
|
||||
WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (localWorld != null)
|
||||
{
|
||||
updatePossibleArea(localWorld, temperature, "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
this.lastWorldPoint = null;
|
||||
digLocations.clear();
|
||||
}
|
||||
|
||||
private void updatePossibleArea(WorldPoint currentWp, String temperature, String difference)
|
||||
{
|
||||
this.location = null;
|
||||
|
||||
if (digLocations.isEmpty())
|
||||
{
|
||||
digLocations.addAll(Arrays.asList(HotColdLocation.values()));
|
||||
}
|
||||
|
||||
int maxSquaresAway = 5000;
|
||||
int minSquaresAway = 0;
|
||||
|
||||
switch (temperature)
|
||||
{
|
||||
// when the strange device reads a temperature, that means that the center of the final dig location
|
||||
// is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance)
|
||||
case "ice cold":
|
||||
maxSquaresAway = 5000;
|
||||
minSquaresAway = 500;
|
||||
break;
|
||||
case "very cold":
|
||||
maxSquaresAway = 499;
|
||||
minSquaresAway = 200;
|
||||
break;
|
||||
case "cold":
|
||||
maxSquaresAway = 199;
|
||||
minSquaresAway = 150;
|
||||
break;
|
||||
case "warm":
|
||||
maxSquaresAway = 149;
|
||||
minSquaresAway = 100;
|
||||
break;
|
||||
case "hot":
|
||||
maxSquaresAway = 99;
|
||||
minSquaresAway = 70;
|
||||
break;
|
||||
case "very hot":
|
||||
maxSquaresAway = 69;
|
||||
minSquaresAway = 30;
|
||||
break;
|
||||
case "incredibly hot":
|
||||
maxSquaresAway = 29;
|
||||
minSquaresAway = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
// rectangle r1 encompasses all of the points that are within the max possible distance from the player
|
||||
Point p1 = new Point(currentWp.getX() - maxSquaresAway, currentWp.getY() - maxSquaresAway);
|
||||
Rectangle r1 = new Rectangle((int) p1.getX(), (int) p1.getY(), 2 * maxSquaresAway + 1, 2 * maxSquaresAway + 1);
|
||||
// rectangle r2 encompasses all of the points that are within the min possible distance from the player
|
||||
Point p2 = new Point(currentWp.getX() - minSquaresAway, currentWp.getY() - minSquaresAway);
|
||||
Rectangle r2 = new Rectangle((int) p2.getX(), (int) p2.getY(), 2 * minSquaresAway + 1, 2 * minSquaresAway + 1);
|
||||
|
||||
// eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range
|
||||
digLocations.removeIf(entry -> r2.contains(entry.getRect()) || !r1.intersects(entry.getRect()));
|
||||
|
||||
// if a previous world point has been recorded, we can consider the warmer/colder result from the strange device
|
||||
if (lastWorldPoint != null)
|
||||
{
|
||||
switch (difference)
|
||||
{
|
||||
case "but colder than":
|
||||
// eliminate spots that are absolutely warmer
|
||||
digLocations.removeIf(entry -> isFirstPointCloserRect(currentWp, lastWorldPoint, entry.getRect()));
|
||||
break;
|
||||
case "and warmer than":
|
||||
// eliminate spots that are absolutely colder
|
||||
digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, currentWp, entry.getRect()));
|
||||
break;
|
||||
case "and the same temperature as":
|
||||
// I couldn't figure out a clean implementation for this case
|
||||
// not necessary for quickly determining final location
|
||||
}
|
||||
}
|
||||
|
||||
lastWorldPoint = currentWp;
|
||||
}
|
||||
|
||||
private boolean isFirstPointCloserRect(WorldPoint firstWp, WorldPoint secondWp, Rectangle2D r)
|
||||
{
|
||||
WorldPoint p1 = new WorldPoint((int) r.getMaxX(), (int) r.getMaxY(), 0);
|
||||
|
||||
if (!isFirstPointCloser(firstWp, secondWp, p1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint p2 = new WorldPoint((int) r.getMaxX(), (int) r.getMinY(), 0);
|
||||
|
||||
if (!isFirstPointCloser(firstWp, secondWp, p2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint p3 = new WorldPoint((int) r.getMinX(), (int) r.getMaxY(), 0);
|
||||
|
||||
if (!isFirstPointCloser(firstWp, secondWp, p3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint p4 = new WorldPoint((int) r.getMinX(), (int) r.getMinY(), 0);
|
||||
return (isFirstPointCloser(firstWp, secondWp, p4));
|
||||
}
|
||||
|
||||
private boolean isFirstPointCloser(WorldPoint firstWp, WorldPoint secondWp, WorldPoint wp)
|
||||
{
|
||||
int firstDistance = firstWp.distanceTo2D(wp);
|
||||
int secondDistance = secondWp.distanceTo2D(wp);
|
||||
return (firstDistance < secondDistance);
|
||||
}
|
||||
|
||||
private void markFinalSpot(WorldPoint wp)
|
||||
{
|
||||
this.location = wp;
|
||||
reset();
|
||||
}
|
||||
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[]{npc};
|
||||
}
|
||||
}
|
||||
@@ -1,209 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import static net.runelite.api.ItemID.*;
|
||||
import net.runelite.api.ObjectComposition;
|
||||
import static net.runelite.api.ObjectID.CRATE_18506;
|
||||
import static net.runelite.api.ObjectID.CRATE_2620;
|
||||
import static net.runelite.api.ObjectID.CRATE_354;
|
||||
import static net.runelite.api.ObjectID.CRATE_357;
|
||||
import static net.runelite.api.ObjectID.CRATE_6616;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@Getter
|
||||
public class MapClue extends ClueScroll implements ObjectClueScroll
|
||||
{
|
||||
private static final Set<MapClue> CLUES = ImmutableSet.of(
|
||||
new MapClue(CLUE_SCROLL_EASY_12179, new WorldPoint(3300, 3291, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_2713, new WorldPoint(3166, 3361, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_2716, new WorldPoint(3290, 3374, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_2719, new WorldPoint(3043, 3398, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_3516, new WorldPoint(2612, 3482, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_3518, new WorldPoint(3110, 3152, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_7236, new WorldPoint(2970, 3415, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_2827, new WorldPoint(3091, 3227, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3596, new WorldPoint(2907, 3295, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3598, new WorldPoint(2658, 3488, 0), CRATE_357),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3599, new WorldPoint(2651, 3231, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3601, new WorldPoint(2565, 3248, 0), CRATE_354),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3602, new WorldPoint(2924, 3210, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7286, new WorldPoint(2536, 3865, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7288, new WorldPoint(3434, 3265, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7290, new WorldPoint(2454, 3230, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7292, new WorldPoint(2578, 3597, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7294, new WorldPoint(2666, 3562, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD, new WorldPoint(3309, 3503, 0), CRATE_2620),
|
||||
new MapClue(CLUE_SCROLL_HARD_2729, new WorldPoint(3190, 3963, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_3520, new WorldPoint(2615, 3078, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_3522, new WorldPoint(2488, 3308, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_3524, new WorldPoint(2457, 3182, 0), CRATE_18506),
|
||||
new MapClue(CLUE_SCROLL_HARD_3525, new WorldPoint(3026, 3628, 0), CRATE_354),
|
||||
new MapClue(CLUE_SCROLL_HARD_7239, new WorldPoint(3021, 3912, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_7241, new WorldPoint(2722, 3338, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_12130, new WorldPoint(2449, 3130, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19782, new WorldPoint(2953, 9523, 1), "In the Mogre Camp, near Port Khazard. You require a Diving Apparatus and a Fishbowl Helmet"),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19783, new WorldPoint(2202, 3062, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19784, new WorldPoint(1815, 3852, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19785, new WorldPoint(3538, 3208, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19786, new WorldPoint(2703, 2716, 0), CRATE_6616)
|
||||
);
|
||||
|
||||
private final int itemId;
|
||||
private final WorldPoint location;
|
||||
private final int objectId;
|
||||
private final String description;
|
||||
|
||||
private MapClue(int itemId, WorldPoint location)
|
||||
{
|
||||
this(itemId, location, -1);
|
||||
}
|
||||
|
||||
private MapClue(int itemId, WorldPoint location, int objectId)
|
||||
{
|
||||
this(itemId, location, objectId, null);
|
||||
}
|
||||
|
||||
private MapClue(int itemId, WorldPoint location, String description)
|
||||
{
|
||||
this(itemId, location, -1, description);
|
||||
}
|
||||
|
||||
private MapClue(int itemId, WorldPoint location, int objectId, String description)
|
||||
{
|
||||
this.itemId = itemId;
|
||||
this.location = location;
|
||||
this.objectId = objectId;
|
||||
this.description = description;
|
||||
setRequiresSpade(objectId == -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Map Clue").build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Click the clue scroll along the edge of your world map to see your destination.")
|
||||
.build());
|
||||
|
||||
if (objectId != -1)
|
||||
{
|
||||
ObjectComposition objectToClick = plugin.getClient().getObjectDefinition(getObjectId());
|
||||
|
||||
String objectName = "N/A";
|
||||
|
||||
if (objectToClick != null)
|
||||
{
|
||||
objectName = objectToClick.getName();
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Travel to the destination and click the " + objectName + ".")
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Travel to the destination and dig on the marked tile.")
|
||||
.build());
|
||||
}
|
||||
|
||||
if (description != null)
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder().build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(description)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark game object
|
||||
if (objectId != -1)
|
||||
{
|
||||
net.runelite.api.Point mousePosition = plugin.getClient().getMouseCanvasPosition();
|
||||
|
||||
if (plugin.getObjectsToMark() != null)
|
||||
{
|
||||
for (TileObject gameObject : plugin.getObjectsToMark())
|
||||
{
|
||||
OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition,
|
||||
CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR);
|
||||
|
||||
OverlayUtil.renderImageLocation(plugin.getClient(), graphics, gameObject.getLocalLocation(), plugin.getClueScrollImage(), IMAGE_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Mark tile
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE);
|
||||
}
|
||||
}
|
||||
|
||||
public static MapClue forItemId(int itemId)
|
||||
{
|
||||
for (MapClue clue : CLUES)
|
||||
{
|
||||
if (clue.itemId == itemId)
|
||||
{
|
||||
return clue;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int[] getObjectIds()
|
||||
{
|
||||
return new int[] {objectId};
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_12179;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_2713;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_2716;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_2719;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_3516;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_3518;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_EASY_7236;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_ELITE_12130;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_ELITE_19782;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_ELITE_19783;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_ELITE_19784;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_ELITE_19785;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_ELITE_19786;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_2729;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_3520;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_3522;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_3524;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_3525;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_7239;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_HARD_7241;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_2827;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_3596;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_3598;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_3599;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_3601;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_3602;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_7286;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_7288;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_7290;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_7292;
|
||||
import static net.runelite.api.ItemID.CLUE_SCROLL_MEDIUM_7294;
|
||||
import net.runelite.api.ObjectComposition;
|
||||
import static net.runelite.api.ObjectID.CRATE_18506;
|
||||
import static net.runelite.api.ObjectID.CRATE_2620;
|
||||
import static net.runelite.api.ObjectID.CRATE_354;
|
||||
import static net.runelite.api.ObjectID.CRATE_357;
|
||||
import static net.runelite.api.ObjectID.CRATE_6616;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@Getter
|
||||
public class MapClue extends ClueScroll implements ObjectClueScroll
|
||||
{
|
||||
private static final Set<MapClue> CLUES = ImmutableSet.of(
|
||||
new MapClue(CLUE_SCROLL_EASY_12179, new WorldPoint(3300, 3291, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_2713, new WorldPoint(3166, 3361, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_2716, new WorldPoint(3290, 3374, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_2719, new WorldPoint(3043, 3398, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_3516, new WorldPoint(2612, 3482, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_3518, new WorldPoint(3110, 3152, 0)),
|
||||
new MapClue(CLUE_SCROLL_EASY_7236, new WorldPoint(2970, 3415, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_2827, new WorldPoint(3091, 3227, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3596, new WorldPoint(2907, 3295, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3598, new WorldPoint(2658, 3488, 0), CRATE_357),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3599, new WorldPoint(2651, 3231, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3601, new WorldPoint(2565, 3248, 0), CRATE_354),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_3602, new WorldPoint(2924, 3210, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7286, new WorldPoint(2536, 3865, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7288, new WorldPoint(3434, 3265, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7290, new WorldPoint(2454, 3230, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7292, new WorldPoint(2578, 3597, 0)),
|
||||
new MapClue(CLUE_SCROLL_MEDIUM_7294, new WorldPoint(2666, 3562, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD, new WorldPoint(3309, 3503, 0), CRATE_2620),
|
||||
new MapClue(CLUE_SCROLL_HARD_2729, new WorldPoint(3190, 3963, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_3520, new WorldPoint(2615, 3078, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_3522, new WorldPoint(2488, 3308, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_3524, new WorldPoint(2457, 3182, 0), CRATE_18506),
|
||||
new MapClue(CLUE_SCROLL_HARD_3525, new WorldPoint(3026, 3628, 0), CRATE_354),
|
||||
new MapClue(CLUE_SCROLL_HARD_7239, new WorldPoint(3021, 3912, 0)),
|
||||
new MapClue(CLUE_SCROLL_HARD_7241, new WorldPoint(2722, 3338, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_12130, new WorldPoint(2449, 3130, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19782, new WorldPoint(2953, 9523, 1), "In the Mogre Camp, near Port Khazard. You require a Diving Apparatus and a Fishbowl Helmet"),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19783, new WorldPoint(2202, 3062, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19784, new WorldPoint(1815, 3852, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19785, new WorldPoint(3538, 3208, 0)),
|
||||
new MapClue(CLUE_SCROLL_ELITE_19786, new WorldPoint(2703, 2716, 0), CRATE_6616)
|
||||
);
|
||||
|
||||
private final int itemId;
|
||||
private final WorldPoint location;
|
||||
private final int objectId;
|
||||
private final String description;
|
||||
|
||||
private MapClue(int itemId, WorldPoint location)
|
||||
{
|
||||
this(itemId, location, -1);
|
||||
}
|
||||
|
||||
private MapClue(int itemId, WorldPoint location, int objectId)
|
||||
{
|
||||
this(itemId, location, objectId, null);
|
||||
}
|
||||
|
||||
private MapClue(int itemId, WorldPoint location, String description)
|
||||
{
|
||||
this(itemId, location, -1, description);
|
||||
}
|
||||
|
||||
private MapClue(int itemId, WorldPoint location, int objectId, String description)
|
||||
{
|
||||
this.itemId = itemId;
|
||||
this.location = location;
|
||||
this.objectId = objectId;
|
||||
this.description = description;
|
||||
setRequiresSpade(objectId == -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Map Clue").build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Click the clue scroll along the edge of your world map to see your destination.")
|
||||
.build());
|
||||
|
||||
if (objectId != -1)
|
||||
{
|
||||
ObjectComposition objectToClick = plugin.getClient().getObjectDefinition(getObjectId());
|
||||
|
||||
String objectName = "N/A";
|
||||
|
||||
if (objectToClick != null)
|
||||
{
|
||||
objectName = objectToClick.getName();
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Travel to the destination and click the " + objectName + ".")
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Travel to the destination and dig on the marked tile.")
|
||||
.build());
|
||||
}
|
||||
|
||||
if (description != null)
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder().build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(description)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark game object
|
||||
if (objectId != -1)
|
||||
{
|
||||
net.runelite.api.Point mousePosition = plugin.getClient().getMouseCanvasPosition();
|
||||
|
||||
if (plugin.getObjectsToMark() != null)
|
||||
{
|
||||
for (TileObject gameObject : plugin.getObjectsToMark())
|
||||
{
|
||||
OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition,
|
||||
CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR);
|
||||
|
||||
OverlayUtil.renderImageLocation(plugin.getClient(), graphics, gameObject.getLocalLocation(), plugin.getClueScrollImage(), IMAGE_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Mark tile
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localLocation, plugin.getSpadeImage(), Color.ORANGE);
|
||||
}
|
||||
}
|
||||
|
||||
public static MapClue forItemId(int itemId)
|
||||
{
|
||||
for (MapClue clue : CLUES)
|
||||
{
|
||||
if (clue.itemId == itemId)
|
||||
{
|
||||
return clue;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int[] getObjectIds()
|
||||
{
|
||||
return new int[]{objectId};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,107 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
public class MusicClue extends ClueScroll implements NpcClueScroll
|
||||
{
|
||||
private static final WorldPoint LOCATION = new WorldPoint(2990, 3384, 0);
|
||||
private static final String CECILIA = "Cecilia";
|
||||
private static final Pattern SONG_PATTERN = Pattern.compile("<col=ffffff>([A-Za-z !&',.]+)</col>");
|
||||
|
||||
private final String song;
|
||||
|
||||
@Override
|
||||
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Music Clue").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("NPC:").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(CECILIA)
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Falador Park")
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Song:").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(song)
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
|
||||
{
|
||||
if (!LOCATION.isInScene(plugin.getClient()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (NPC npc : plugin.getNpcsToMark())
|
||||
{
|
||||
OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[] {CECILIA};
|
||||
}
|
||||
|
||||
public static MusicClue forText(String text)
|
||||
{
|
||||
final Matcher m = SONG_PATTERN.matcher(text);
|
||||
if (m.find())
|
||||
{
|
||||
final String song = m.group(1);
|
||||
return new MusicClue(song);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019, Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
public class MusicClue extends ClueScroll implements NpcClueScroll
|
||||
{
|
||||
private static final WorldPoint LOCATION = new WorldPoint(2990, 3384, 0);
|
||||
private static final String CECILIA = "Cecilia";
|
||||
private static final Pattern SONG_PATTERN = Pattern.compile("<col=ffffff>([A-Za-z !&',.]+)</col>");
|
||||
|
||||
private final String song;
|
||||
|
||||
@Override
|
||||
public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Music Clue").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("NPC:").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(CECILIA)
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Area:").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Falador Park")
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Song:").build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left(song)
|
||||
.leftColor(TITLED_CONTENT_COLOR)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin)
|
||||
{
|
||||
if (!LOCATION.isInScene(plugin.getClient()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (NPC npc : plugin.getNpcsToMark())
|
||||
{
|
||||
OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNpcs()
|
||||
{
|
||||
return new String[]{CECILIA};
|
||||
}
|
||||
|
||||
public static MusicClue forText(String text)
|
||||
{
|
||||
final Matcher m = SONG_PATTERN.matcher(text);
|
||||
if (m.find())
|
||||
{
|
||||
final String song = m.group(1);
|
||||
return new MusicClue(song);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues.emote;
|
||||
|
||||
import lombok.Getter;
|
||||
import static net.runelite.api.SpriteID.*;
|
||||
|
||||
@Getter
|
||||
public enum Emote
|
||||
{
|
||||
BULL_ROARER("Bull Roarer", -1),
|
||||
YES("Yes", EMOTE_YES),
|
||||
NO("No", EMOTE_NO),
|
||||
THINK("Think", EMOTE_THINK),
|
||||
BOW("Bow", EMOTE_BOW),
|
||||
ANGRY("Angry", EMOTE_ANGRY),
|
||||
CRY("Cry", EMOTE_CRY),
|
||||
LAUGH("Laugh", EMOTE_LAUGH),
|
||||
CHEER("Cheer", EMOTE_CHEER),
|
||||
WAVE("Wave", EMOTE_WAVE),
|
||||
BECKON("Beckon", EMOTE_BECKON),
|
||||
DANCE("Dance", EMOTE_DANCE),
|
||||
CLAP("Clap", EMOTE_CLAP),
|
||||
PANIC("Panic", EMOTE_PANIC),
|
||||
JIG("Jig", EMOTE_JIG),
|
||||
SPIN("Spin", EMOTE_SPIN),
|
||||
HEADBANG("Headbang", EMOTE_HEADBANG),
|
||||
JUMP_FOR_JOY("Jump for Joy", EMOTE_JUMP_FOR_JOY),
|
||||
RASPBERRY("Raspberry", EMOTE_RASPBERRY),
|
||||
YAWN("Yawn", EMOTE_YAWN),
|
||||
SALUTE("Salute", EMOTE_SALUTE),
|
||||
SHRUG("Shrug", EMOTE_SHRUG),
|
||||
BLOW_KISS("Blow Kiss", EMOTE_BLOW_KISS),
|
||||
GOBLIN_SALUTE("Goblin Salute", EMOTE_GOBLIN_SALUTE),
|
||||
SLAP_HEAD("Slap Head", EMOTE_SLAP_HEAD),
|
||||
STOMP("Stomp", EMOTE_STOMP),
|
||||
FLAP("Flap", EMOTE_FLAP),
|
||||
PUSH_UP("Push up", EMOTE_PUSH_UP);
|
||||
|
||||
private String name;
|
||||
private int spriteId;
|
||||
|
||||
Emote(String name, int spriteId)
|
||||
{
|
||||
this.name = name;
|
||||
this.spriteId = spriteId;
|
||||
}
|
||||
|
||||
public boolean hasSprite()
|
||||
{
|
||||
return spriteId != -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cluescrolls.clues.emote;
|
||||
|
||||
import lombok.Getter;
|
||||
import static net.runelite.api.SpriteID.EMOTE_ANGRY;
|
||||
import static net.runelite.api.SpriteID.EMOTE_BECKON;
|
||||
import static net.runelite.api.SpriteID.EMOTE_BLOW_KISS;
|
||||
import static net.runelite.api.SpriteID.EMOTE_BOW;
|
||||
import static net.runelite.api.SpriteID.EMOTE_CHEER;
|
||||
import static net.runelite.api.SpriteID.EMOTE_CLAP;
|
||||
import static net.runelite.api.SpriteID.EMOTE_CRY;
|
||||
import static net.runelite.api.SpriteID.EMOTE_DANCE;
|
||||
import static net.runelite.api.SpriteID.EMOTE_FLAP;
|
||||
import static net.runelite.api.SpriteID.EMOTE_GOBLIN_SALUTE;
|
||||
import static net.runelite.api.SpriteID.EMOTE_HEADBANG;
|
||||
import static net.runelite.api.SpriteID.EMOTE_JIG;
|
||||
import static net.runelite.api.SpriteID.EMOTE_JUMP_FOR_JOY;
|
||||
import static net.runelite.api.SpriteID.EMOTE_LAUGH;
|
||||
import static net.runelite.api.SpriteID.EMOTE_NO;
|
||||
import static net.runelite.api.SpriteID.EMOTE_PANIC;
|
||||
import static net.runelite.api.SpriteID.EMOTE_PUSH_UP;
|
||||
import static net.runelite.api.SpriteID.EMOTE_RASPBERRY;
|
||||
import static net.runelite.api.SpriteID.EMOTE_SALUTE;
|
||||
import static net.runelite.api.SpriteID.EMOTE_SHRUG;
|
||||
import static net.runelite.api.SpriteID.EMOTE_SLAP_HEAD;
|
||||
import static net.runelite.api.SpriteID.EMOTE_SPIN;
|
||||
import static net.runelite.api.SpriteID.EMOTE_STOMP;
|
||||
import static net.runelite.api.SpriteID.EMOTE_THINK;
|
||||
import static net.runelite.api.SpriteID.EMOTE_WAVE;
|
||||
import static net.runelite.api.SpriteID.EMOTE_YAWN;
|
||||
import static net.runelite.api.SpriteID.EMOTE_YES;
|
||||
|
||||
@Getter
|
||||
public enum Emote
|
||||
{
|
||||
BULL_ROARER("Bull Roarer", -1),
|
||||
YES("Yes", EMOTE_YES),
|
||||
NO("No", EMOTE_NO),
|
||||
THINK("Think", EMOTE_THINK),
|
||||
BOW("Bow", EMOTE_BOW),
|
||||
ANGRY("Angry", EMOTE_ANGRY),
|
||||
CRY("Cry", EMOTE_CRY),
|
||||
LAUGH("Laugh", EMOTE_LAUGH),
|
||||
CHEER("Cheer", EMOTE_CHEER),
|
||||
WAVE("Wave", EMOTE_WAVE),
|
||||
BECKON("Beckon", EMOTE_BECKON),
|
||||
DANCE("Dance", EMOTE_DANCE),
|
||||
CLAP("Clap", EMOTE_CLAP),
|
||||
PANIC("Panic", EMOTE_PANIC),
|
||||
JIG("Jig", EMOTE_JIG),
|
||||
SPIN("Spin", EMOTE_SPIN),
|
||||
HEADBANG("Headbang", EMOTE_HEADBANG),
|
||||
JUMP_FOR_JOY("Jump for Joy", EMOTE_JUMP_FOR_JOY),
|
||||
RASPBERRY("Raspberry", EMOTE_RASPBERRY),
|
||||
YAWN("Yawn", EMOTE_YAWN),
|
||||
SALUTE("Salute", EMOTE_SALUTE),
|
||||
SHRUG("Shrug", EMOTE_SHRUG),
|
||||
BLOW_KISS("Blow Kiss", EMOTE_BLOW_KISS),
|
||||
GOBLIN_SALUTE("Goblin Salute", EMOTE_GOBLIN_SALUTE),
|
||||
SLAP_HEAD("Slap Head", EMOTE_SLAP_HEAD),
|
||||
STOMP("Stomp", EMOTE_STOMP),
|
||||
FLAP("Flap", EMOTE_FLAP),
|
||||
PUSH_UP("Push up", EMOTE_PUSH_UP);
|
||||
|
||||
private String name;
|
||||
private int spriteId;
|
||||
|
||||
Emote(String name, int spriteId)
|
||||
{
|
||||
this.name = name;
|
||||
this.spriteId = spriteId;
|
||||
}
|
||||
|
||||
public boolean hasSprite()
|
||||
{
|
||||
return spriteId != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
package net.runelite.client.plugins.combatlevel;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.Skill;
|
||||
@@ -34,11 +39,6 @@ import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
||||
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import javax.inject.Inject;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
class CombatLevelOverlay extends Overlay
|
||||
{
|
||||
@@ -143,10 +143,11 @@ class CombatLevelOverlay extends Overlay
|
||||
/**
|
||||
* Calculate skill levels required for increasing combat level, meant
|
||||
* for all combat skills besides prayer, ranged, and magic.
|
||||
* @param start initial value
|
||||
* @param end ending value (combat level + 1)
|
||||
* @param multiple how much adding one skill level will change combat
|
||||
* @return levels required for a specific skill to level up combat
|
||||
*
|
||||
* @param start initial value
|
||||
* @param end ending value (combat level + 1)
|
||||
* @param multiple how much adding one skill level will change combat
|
||||
* @return levels required for a specific skill to level up combat
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static int calcLevels(double start, int end, double multiple)
|
||||
@@ -158,8 +159,9 @@ class CombatLevelOverlay extends Overlay
|
||||
* Calculate skill levels for increasing combat level, meant ONLY for the Prayer skill.
|
||||
* <p>
|
||||
* Note: Prayer is a special case, only leveling up upon even level numbers. This is accounted
|
||||
* for in this function.
|
||||
* for in this function.
|
||||
* </p>
|
||||
*
|
||||
* @param start current combat level
|
||||
* @param end ending value (combat level + 1)
|
||||
* @param prayerLevel the player's current prayer level
|
||||
@@ -191,10 +193,11 @@ class CombatLevelOverlay extends Overlay
|
||||
/**
|
||||
* Calculate skill levels required for increasing combat level, meant
|
||||
* ONLY for Ranged and Magic skills.
|
||||
* @param start either the current ranged or magic level
|
||||
* @param end ending value (combat level + 1)
|
||||
* @param dhp defence, hitpoints, and prayer; this is the initial calculated "base" value
|
||||
* @return levels required for a specific skill to level up combat
|
||||
*
|
||||
* @param start either the current ranged or magic level
|
||||
* @param end ending value (combat level + 1)
|
||||
* @param dhp defence, hitpoints, and prayer; this is the initial calculated "base" value
|
||||
* @return levels required for a specific skill to level up combat
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static int calcLevelsRM(double start, int end, double dhp)
|
||||
|
||||
@@ -1,244 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* Copyright (c) 2019, Jordan Atwood <nightfirecat@protonmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.combatlevel;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Combat Level",
|
||||
description = "Show a more accurate combat level in Combat Options panel and other combat level functions",
|
||||
tags = {"wilderness", "attack", "range"}
|
||||
)
|
||||
public class CombatLevelPlugin extends Plugin
|
||||
{
|
||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###");
|
||||
private static final String CONFIG_GROUP = "combatlevel";
|
||||
private static final String ATTACK_RANGE_CONFIG_KEY = "wildernessAttackLevelRange";
|
||||
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+)$");
|
||||
private static final int SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y = 6;
|
||||
private static final int WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y = 3;
|
||||
private static final int MIN_COMBAT_LEVEL = 3;
|
||||
|
||||
private int originalWildernessLevelTextPosition = -1;
|
||||
private int originalSkullContainerPosition = -1;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private CombatLevelConfig config;
|
||||
|
||||
@Inject
|
||||
private CombatLevelOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Provides
|
||||
CombatLevelConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(CombatLevelConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
|
||||
if (config.wildernessAttackLevelRange())
|
||||
{
|
||||
appendAttackLevelRangeText();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
Widget combatLevelWidget = client.getWidget(WidgetInfo.COMBAT_LEVEL);
|
||||
|
||||
if (combatLevelWidget != null)
|
||||
{
|
||||
String widgetText = combatLevelWidget.getText();
|
||||
|
||||
if (widgetText.contains("."))
|
||||
{
|
||||
combatLevelWidget.setText(widgetText.substring(0, widgetText.indexOf(".")));
|
||||
}
|
||||
}
|
||||
|
||||
shutDownAttackLevelRange();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget combatLevelWidget = client.getWidget(WidgetInfo.COMBAT_LEVEL);
|
||||
if (combatLevelWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double combatLevelPrecise = Experience.getCombatLevelPrecise(
|
||||
client.getRealSkillLevel(Skill.ATTACK),
|
||||
client.getRealSkillLevel(Skill.STRENGTH),
|
||||
client.getRealSkillLevel(Skill.DEFENCE),
|
||||
client.getRealSkillLevel(Skill.HITPOINTS),
|
||||
client.getRealSkillLevel(Skill.MAGIC),
|
||||
client.getRealSkillLevel(Skill.RANGED),
|
||||
client.getRealSkillLevel(Skill.PRAYER)
|
||||
);
|
||||
|
||||
combatLevelWidget.setText("Combat Lvl: " + DECIMAL_FORMAT.format(combatLevelPrecise));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!CONFIG_GROUP.equals(event.getGroup()) || !ATTACK_RANGE_CONFIG_KEY.equals(event.getKey()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.wildernessAttackLevelRange())
|
||||
{
|
||||
appendAttackLevelRangeText();
|
||||
}
|
||||
else
|
||||
{
|
||||
shutDownAttackLevelRange();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (config.wildernessAttackLevelRange()
|
||||
&& "wildernessWidgetTextSet".equals(event.getEventName()))
|
||||
{
|
||||
appendAttackLevelRangeText();
|
||||
}
|
||||
}
|
||||
|
||||
private void appendAttackLevelRangeText()
|
||||
{
|
||||
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
if (wildernessLevelWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String wildernessLevelText = wildernessLevelWidget.getText();
|
||||
final Matcher m = WILDERNESS_LEVEL_PATTERN.matcher(wildernessLevelText);
|
||||
if (!m.matches()
|
||||
|| WorldType.isPvpWorld(client.getWorldType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER);
|
||||
if (originalWildernessLevelTextPosition == -1)
|
||||
{
|
||||
originalWildernessLevelTextPosition = wildernessLevelWidget.getOriginalY();
|
||||
}
|
||||
if (originalSkullContainerPosition == -1)
|
||||
{
|
||||
originalSkullContainerPosition = skullContainer.getRelativeY();
|
||||
}
|
||||
|
||||
final int wildernessLevel = Integer.parseInt(m.group(1));
|
||||
final int combatLevel = client.getLocalPlayer().getCombatLevel();
|
||||
|
||||
wildernessLevelWidget.setText(wildernessLevelText + "<br>" + combatAttackRange(combatLevel, wildernessLevel));
|
||||
wildernessLevelWidget.setOriginalY(WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y);
|
||||
skullContainer.setOriginalY(SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y);
|
||||
|
||||
clientThread.invoke(wildernessLevelWidget::revalidate);
|
||||
clientThread.invoke(skullContainer::revalidate);
|
||||
}
|
||||
|
||||
private void shutDownAttackLevelRange()
|
||||
{
|
||||
if (WorldType.isPvpWorld(client.getWorldType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
if (wildernessLevelWidget != null)
|
||||
{
|
||||
String wildernessLevelText = wildernessLevelWidget.getText();
|
||||
if (wildernessLevelText.contains("<br>"))
|
||||
{
|
||||
wildernessLevelWidget.setText(wildernessLevelText.substring(0, wildernessLevelText.indexOf("<br>")));
|
||||
}
|
||||
wildernessLevelWidget.setOriginalY(originalWildernessLevelTextPosition);
|
||||
clientThread.invoke(wildernessLevelWidget::revalidate);
|
||||
}
|
||||
originalWildernessLevelTextPosition = -1;
|
||||
|
||||
final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER);
|
||||
if (skullContainer != null)
|
||||
{
|
||||
skullContainer.setOriginalY(originalSkullContainerPosition);
|
||||
clientThread.invoke(skullContainer::revalidate);
|
||||
}
|
||||
originalSkullContainerPosition = -1;
|
||||
}
|
||||
|
||||
private static String combatAttackRange(final int combatLevel, final int wildernessLevel)
|
||||
{
|
||||
return Math.max(MIN_COMBAT_LEVEL, combatLevel - wildernessLevel) + "-" + Math.min(Experience.MAX_COMBAT_LEVEL, combatLevel + wildernessLevel);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* Copyright (c) 2019, Jordan Atwood <nightfirecat@protonmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.combatlevel;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Combat Level",
|
||||
description = "Show a more accurate combat level in Combat Options panel and other combat level functions",
|
||||
tags = {"wilderness", "attack", "range"}
|
||||
)
|
||||
public class CombatLevelPlugin extends Plugin
|
||||
{
|
||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###");
|
||||
private static final String CONFIG_GROUP = "combatlevel";
|
||||
private static final String ATTACK_RANGE_CONFIG_KEY = "wildernessAttackLevelRange";
|
||||
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+)$");
|
||||
private static final int SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y = 6;
|
||||
private static final int WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y = 3;
|
||||
private static final int MIN_COMBAT_LEVEL = 3;
|
||||
|
||||
private int originalWildernessLevelTextPosition = -1;
|
||||
private int originalSkullContainerPosition = -1;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private CombatLevelConfig config;
|
||||
|
||||
@Inject
|
||||
private CombatLevelOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Provides
|
||||
CombatLevelConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(CombatLevelConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
|
||||
if (config.wildernessAttackLevelRange())
|
||||
{
|
||||
appendAttackLevelRangeText();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
Widget combatLevelWidget = client.getWidget(WidgetInfo.COMBAT_LEVEL);
|
||||
|
||||
if (combatLevelWidget != null)
|
||||
{
|
||||
String widgetText = combatLevelWidget.getText();
|
||||
|
||||
if (widgetText.contains("."))
|
||||
{
|
||||
combatLevelWidget.setText(widgetText.substring(0, widgetText.indexOf(".")));
|
||||
}
|
||||
}
|
||||
|
||||
shutDownAttackLevelRange();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget combatLevelWidget = client.getWidget(WidgetInfo.COMBAT_LEVEL);
|
||||
if (combatLevelWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double combatLevelPrecise = Experience.getCombatLevelPrecise(
|
||||
client.getRealSkillLevel(Skill.ATTACK),
|
||||
client.getRealSkillLevel(Skill.STRENGTH),
|
||||
client.getRealSkillLevel(Skill.DEFENCE),
|
||||
client.getRealSkillLevel(Skill.HITPOINTS),
|
||||
client.getRealSkillLevel(Skill.MAGIC),
|
||||
client.getRealSkillLevel(Skill.RANGED),
|
||||
client.getRealSkillLevel(Skill.PRAYER)
|
||||
);
|
||||
|
||||
combatLevelWidget.setText("Combat Lvl: " + DECIMAL_FORMAT.format(combatLevelPrecise));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!CONFIG_GROUP.equals(event.getGroup()) || !ATTACK_RANGE_CONFIG_KEY.equals(event.getKey()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.wildernessAttackLevelRange())
|
||||
{
|
||||
appendAttackLevelRangeText();
|
||||
}
|
||||
else
|
||||
{
|
||||
shutDownAttackLevelRange();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (config.wildernessAttackLevelRange()
|
||||
&& "wildernessWidgetTextSet".equals(event.getEventName()))
|
||||
{
|
||||
appendAttackLevelRangeText();
|
||||
}
|
||||
}
|
||||
|
||||
private void appendAttackLevelRangeText()
|
||||
{
|
||||
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
if (wildernessLevelWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String wildernessLevelText = wildernessLevelWidget.getText();
|
||||
final Matcher m = WILDERNESS_LEVEL_PATTERN.matcher(wildernessLevelText);
|
||||
if (!m.matches()
|
||||
|| WorldType.isPvpWorld(client.getWorldType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER);
|
||||
if (originalWildernessLevelTextPosition == -1)
|
||||
{
|
||||
originalWildernessLevelTextPosition = wildernessLevelWidget.getOriginalY();
|
||||
}
|
||||
if (originalSkullContainerPosition == -1)
|
||||
{
|
||||
originalSkullContainerPosition = skullContainer.getRelativeY();
|
||||
}
|
||||
|
||||
final int wildernessLevel = Integer.parseInt(m.group(1));
|
||||
final int combatLevel = client.getLocalPlayer().getCombatLevel();
|
||||
|
||||
wildernessLevelWidget.setText(wildernessLevelText + "<br>" + combatAttackRange(combatLevel, wildernessLevel));
|
||||
wildernessLevelWidget.setOriginalY(WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y);
|
||||
skullContainer.setOriginalY(SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y);
|
||||
|
||||
clientThread.invoke(wildernessLevelWidget::revalidate);
|
||||
clientThread.invoke(skullContainer::revalidate);
|
||||
}
|
||||
|
||||
private void shutDownAttackLevelRange()
|
||||
{
|
||||
if (WorldType.isPvpWorld(client.getWorldType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
if (wildernessLevelWidget != null)
|
||||
{
|
||||
String wildernessLevelText = wildernessLevelWidget.getText();
|
||||
if (wildernessLevelText.contains("<br>"))
|
||||
{
|
||||
wildernessLevelWidget.setText(wildernessLevelText.substring(0, wildernessLevelText.indexOf("<br>")));
|
||||
}
|
||||
wildernessLevelWidget.setOriginalY(originalWildernessLevelTextPosition);
|
||||
clientThread.invoke(wildernessLevelWidget::revalidate);
|
||||
}
|
||||
originalWildernessLevelTextPosition = -1;
|
||||
|
||||
final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER);
|
||||
if (skullContainer != null)
|
||||
{
|
||||
skullContainer.setOriginalY(originalSkullContainerPosition);
|
||||
clientThread.invoke(skullContainer::revalidate);
|
||||
}
|
||||
originalSkullContainerPosition = -1;
|
||||
}
|
||||
|
||||
private static String combatAttackRange(final int combatLevel, final int wildernessLevel)
|
||||
{
|
||||
return Math.max(MIN_COMBAT_LEVEL, combatLevel - wildernessLevel) + "-" + Math.min(Experience.MAX_COMBAT_LEVEL, combatLevel + wildernessLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginInstantiationException;
|
||||
import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.plugins.pluginsorter.PluginSorterPlugin;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.DynamicGridLayout;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
@@ -197,8 +196,8 @@ public class ConfigPanel extends PluginPanel
|
||||
|
||||
// set RuneLite config on top, as it should always have been
|
||||
final PluginListItem runeLite = new PluginListItem(this, configManager, runeLiteConfig,
|
||||
configManager.getConfigDescriptor(runeLiteConfig),
|
||||
RUNELITE_PLUGIN, "RuneLite client settings", "client");
|
||||
configManager.getConfigDescriptor(runeLiteConfig),
|
||||
RUNELITE_PLUGIN, "RuneLite client settings", "client");
|
||||
runeLite.setPinned(pinnedPlugins.contains(RUNELITE_PLUGIN));
|
||||
runeLite.nameLabel.setForeground(Color.WHITE);
|
||||
pluginList.add(runeLite);
|
||||
@@ -279,13 +278,13 @@ public class ConfigPanel extends PluginPanel
|
||||
// populate pluginList with all vanilla RL plugins
|
||||
List<PluginListItem> vanillaPlugins = new ArrayList<>();
|
||||
pluginManager.getPlugins().stream()
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PVM))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PVP))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.UTILITY))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PLUGIN_ORGANIZER))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.EXTERNAL))
|
||||
.forEach(plugin ->
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PVM))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PVP))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.UTILITY))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PLUGIN_ORGANIZER))
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.EXTERNAL))
|
||||
.forEach(plugin ->
|
||||
{
|
||||
final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
||||
final Config config = pluginManager.getPluginConfigProxy(plugin);
|
||||
@@ -295,11 +294,11 @@ public class ConfigPanel extends PluginPanel
|
||||
listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
|
||||
vanillaPlugins.add(listItem);
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
final PluginListItem chatColor = new PluginListItem(this, configManager, chatColorConfig,
|
||||
configManager.getConfigDescriptor(chatColorConfig),
|
||||
CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages");
|
||||
configManager.getConfigDescriptor(chatColorConfig),
|
||||
CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages");
|
||||
chatColor.setPinned(pinnedPlugins.contains(CHAT_COLOR_PLUGIN));
|
||||
chatColor.nameLabel.setForeground(Color.WHITE);
|
||||
vanillaPlugins.add(chatColor);
|
||||
@@ -404,7 +403,9 @@ public class ConfigPanel extends PluginPanel
|
||||
topPanel.add(topPanelBackButton, BorderLayout.WEST);
|
||||
|
||||
if (!listItem.getName().equals("RuneLitePlus"))
|
||||
topPanel.add(listItem.createToggleButton(), BorderLayout.EAST);
|
||||
{
|
||||
topPanel.add(listItem.createToggleButton(), BorderLayout.EAST);
|
||||
}
|
||||
|
||||
String name = listItem.getName();
|
||||
JLabel title = new JLabel(name);
|
||||
@@ -520,7 +521,7 @@ public class ConfigPanel extends PluginPanel
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
RuneliteColorPicker colorPicker = new RuneliteColorPicker(SwingUtilities.windowForComponent(ConfigPanel.this),
|
||||
colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null);
|
||||
colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null);
|
||||
colorPicker.setLocation(getLocationOnScreen());
|
||||
colorPicker.setOnColorChange(c ->
|
||||
{
|
||||
@@ -566,7 +567,7 @@ public class ConfigPanel extends PluginPanel
|
||||
heightSpinnerTextField.setColumns(4);
|
||||
|
||||
ChangeListener listener = e ->
|
||||
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue());
|
||||
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue());
|
||||
|
||||
widthSpinner.addChangeListener(listener);
|
||||
heightSpinner.addChangeListener(listener);
|
||||
@@ -611,8 +612,8 @@ public class ConfigPanel extends PluginPanel
|
||||
if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class)
|
||||
{
|
||||
Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(),
|
||||
cid.getItem().keyName(),
|
||||
(Class<? extends Keybind>) cid.getType());
|
||||
cid.getItem().keyName(),
|
||||
(Class<? extends Keybind>) cid.getType());
|
||||
|
||||
HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class);
|
||||
|
||||
@@ -635,8 +636,8 @@ public class ConfigPanel extends PluginPanel
|
||||
resetButton.addActionListener((e) ->
|
||||
{
|
||||
final int result = JOptionPane.showOptionDialog(resetButton, "Are you sure you want to reset this plugin's configuration?",
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
|
||||
if (result == JOptionPane.YES_OPTION)
|
||||
{
|
||||
@@ -663,8 +664,8 @@ public class ConfigPanel extends PluginPanel
|
||||
if (!Strings.isNullOrEmpty(configItem.warning()))
|
||||
{
|
||||
final int result = JOptionPane.showOptionDialog(component, configItem.warning(),
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
|
||||
if (result != JOptionPane.YES_OPTION)
|
||||
{
|
||||
@@ -758,9 +759,9 @@ public class ConfigPanel extends PluginPanel
|
||||
void savePinnedPlugins()
|
||||
{
|
||||
final String value = pluginList.stream()
|
||||
.filter(PluginListItem::isPinned)
|
||||
.map(PluginListItem::getName)
|
||||
.collect(Collectors.joining(","));
|
||||
.filter(PluginListItem::isPinned)
|
||||
.map(PluginListItem::getName)
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
configManager.setConfiguration(RUNELITE_GROUP_NAME, PINNED_PLUGINS_CONFIG_KEY, value);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package net.runelite.client.plugins.config;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -33,7 +32,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
@@ -41,13 +39,11 @@ import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigDescriptor;
|
||||
import net.runelite.client.config.ConfigItemDescriptor;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.IconButton;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import org.apache.commons.text.similarity.JaroWinklerDistance;
|
||||
|
||||
@@ -105,17 +101,17 @@ public class PluginListItem extends JPanel
|
||||
ON_STAR = new ImageIcon(onStar);
|
||||
CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100));
|
||||
BufferedImage offSwitcherImage = ImageUtil.flipImage(
|
||||
ImageUtil.grayscaleOffset(
|
||||
ImageUtil.grayscaleImage(onSwitcher),
|
||||
0.61f
|
||||
),
|
||||
true,
|
||||
false
|
||||
ImageUtil.grayscaleOffset(
|
||||
ImageUtil.grayscaleImage(onSwitcher),
|
||||
0.61f
|
||||
),
|
||||
true,
|
||||
false
|
||||
);
|
||||
OFF_SWITCHER = new ImageIcon(offSwitcherImage);
|
||||
BufferedImage offStar = ImageUtil.grayscaleOffset(
|
||||
ImageUtil.grayscaleImage(onStar),
|
||||
0.77f
|
||||
ImageUtil.grayscaleImage(onStar),
|
||||
0.77f
|
||||
);
|
||||
OFF_STAR = new ImageIcon(offStar);
|
||||
}
|
||||
@@ -130,7 +126,7 @@ public class PluginListItem extends JPanel
|
||||
@Nullable Config config, @Nullable ConfigDescriptor configDescriptor)
|
||||
{
|
||||
this(configPanel, configManager, plugin, config, configDescriptor,
|
||||
descriptor.name(), descriptor.description(), descriptor.tags());
|
||||
descriptor.name(), descriptor.description(), descriptor.tags());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,27 +175,28 @@ public class PluginListItem extends JPanel
|
||||
});
|
||||
|
||||
|
||||
final JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new GridLayout(1, 2));
|
||||
add(buttonPanel, BorderLayout.LINE_END);
|
||||
final JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new GridLayout(1, 2));
|
||||
add(buttonPanel, BorderLayout.LINE_END);
|
||||
|
||||
configButton.setPreferredSize(new Dimension(25, 0));
|
||||
configButton.setVisible(false);
|
||||
buttonPanel.add(configButton);
|
||||
configButton.setPreferredSize(new Dimension(25, 0));
|
||||
configButton.setVisible(false);
|
||||
buttonPanel.add(configButton);
|
||||
|
||||
// add a listener to configButton only if there are config items to show
|
||||
if (config != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden()))
|
||||
// add a listener to configButton only if there are config items to show
|
||||
if (config != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden()))
|
||||
{
|
||||
configButton.addActionListener(e ->
|
||||
{
|
||||
configButton.addActionListener(e ->
|
||||
{
|
||||
configButton.setIcon(CONFIG_ICON);
|
||||
configPanel.openGroupConfigPanel(PluginListItem.this, config, configDescriptor);
|
||||
});
|
||||
configButton.setIcon(CONFIG_ICON);
|
||||
configPanel.openGroupConfigPanel(PluginListItem.this, config, configDescriptor);
|
||||
});
|
||||
|
||||
configButton.setVisible(true);
|
||||
configButton.setToolTipText("Edit plugin configuration");
|
||||
}
|
||||
if (!name.equals("RuneLitePlus")) {
|
||||
configButton.setVisible(true);
|
||||
configButton.setToolTipText("Edit plugin configuration");
|
||||
}
|
||||
if (!name.equals("RuneLitePlus"))
|
||||
{
|
||||
toggleButton.setPreferredSize(new Dimension(25, 0));
|
||||
attachToggleButtonListener(toggleButton);
|
||||
buttonPanel.add(toggleButton);
|
||||
@@ -261,6 +258,7 @@ public class PluginListItem extends JPanel
|
||||
|
||||
/**
|
||||
* Checks if all the search terms in the given list matches at least one keyword.
|
||||
*
|
||||
* @return true if all search terms matches at least one keyword, or false if otherwise.
|
||||
*/
|
||||
boolean matchesSearchTerms(String[] searchTerms)
|
||||
@@ -268,7 +266,7 @@ public class PluginListItem extends JPanel
|
||||
for (String term : searchTerms)
|
||||
{
|
||||
if (keywords.stream().noneMatch((t) -> t.contains(term) ||
|
||||
DISTANCE.apply(t, term) > 0.9))
|
||||
DISTANCE.apply(t, term) > 0.9))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ public class DailyTasksPlugin extends Plugin
|
||||
max += BONEMEAL_PER_DIARY;
|
||||
}
|
||||
}
|
||||
if (dailyReset || collected < max)
|
||||
if (dailyReset || collected < max)
|
||||
{
|
||||
sendChatMessage(BONEMEAL_MESSAGE);
|
||||
}
|
||||
|
||||
@@ -1,152 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.defaultworld;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.WorldUtil;
|
||||
import net.runelite.http.api.worlds.World;
|
||||
import net.runelite.http.api.worlds.WorldClient;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Default World",
|
||||
description = "Enable a default world to be selected when launching the client",
|
||||
tags = {"home"}
|
||||
)
|
||||
@Slf4j
|
||||
public class DefaultWorldPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private DefaultWorldConfig config;
|
||||
|
||||
private final WorldClient worldClient = new WorldClient();
|
||||
private int worldCache;
|
||||
private boolean worldChangeRequired;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
worldChangeRequired = true;
|
||||
applyWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
worldChangeRequired = true;
|
||||
changeWorld(worldCache);
|
||||
}
|
||||
|
||||
@Provides
|
||||
DefaultWorldConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(DefaultWorldConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionOpen(SessionOpen event)
|
||||
{
|
||||
worldChangeRequired = true;
|
||||
applyWorld();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
applyWorld();
|
||||
}
|
||||
|
||||
private void changeWorld(int newWorld)
|
||||
{
|
||||
if (!worldChangeRequired || client.getGameState() != GameState.LOGIN_SCREEN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
worldChangeRequired = false;
|
||||
int correctedWorld = newWorld < 300 ? newWorld + 300 : newWorld;
|
||||
|
||||
// Old School RuneScape worlds start on 301 so don't even bother trying to find lower id ones
|
||||
// and also do not try to set world if we are already on it
|
||||
if (correctedWorld <= 300 || client.getWorld() == correctedWorld)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final WorldResult worldResult = worldClient.lookupWorlds();
|
||||
final World world = worldResult.findWorld(correctedWorld);
|
||||
|
||||
if (world != null)
|
||||
{
|
||||
final net.runelite.api.World rsWorld = client.createWorld();
|
||||
rsWorld.setActivity(world.getActivity());
|
||||
rsWorld.setAddress(world.getAddress());
|
||||
rsWorld.setId(world.getId());
|
||||
rsWorld.setPlayerCount(world.getPlayers());
|
||||
rsWorld.setLocation(world.getLocation());
|
||||
rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
|
||||
|
||||
client.changeWorld(rsWorld);
|
||||
log.debug("Applied new world {}", correctedWorld);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn("World {} not found.", correctedWorld);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Error looking up world {}. Error: {}", correctedWorld, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyWorld()
|
||||
{
|
||||
if (worldCache == 0)
|
||||
{
|
||||
worldCache = client.getWorld();
|
||||
log.debug("Stored old world {}", worldCache);
|
||||
}
|
||||
|
||||
final int newWorld = config.getWorld();
|
||||
changeWorld(newWorld);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.defaultworld;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.WorldUtil;
|
||||
import net.runelite.http.api.worlds.World;
|
||||
import net.runelite.http.api.worlds.WorldClient;
|
||||
import net.runelite.http.api.worlds.WorldResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Default World",
|
||||
description = "Enable a default world to be selected when launching the client",
|
||||
tags = {"home"}
|
||||
)
|
||||
@Slf4j
|
||||
public class DefaultWorldPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private DefaultWorldConfig config;
|
||||
|
||||
private final WorldClient worldClient = new WorldClient();
|
||||
private int worldCache;
|
||||
private boolean worldChangeRequired;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
worldChangeRequired = true;
|
||||
applyWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
worldChangeRequired = true;
|
||||
changeWorld(worldCache);
|
||||
}
|
||||
|
||||
@Provides
|
||||
DefaultWorldConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(DefaultWorldConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionOpen(SessionOpen event)
|
||||
{
|
||||
worldChangeRequired = true;
|
||||
applyWorld();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
applyWorld();
|
||||
}
|
||||
|
||||
private void changeWorld(int newWorld)
|
||||
{
|
||||
if (!worldChangeRequired || client.getGameState() != GameState.LOGIN_SCREEN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
worldChangeRequired = false;
|
||||
int correctedWorld = newWorld < 300 ? newWorld + 300 : newWorld;
|
||||
|
||||
// Old School RuneScape worlds start on 301 so don't even bother trying to find lower id ones
|
||||
// and also do not try to set world if we are already on it
|
||||
if (correctedWorld <= 300 || client.getWorld() == correctedWorld)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final WorldResult worldResult = worldClient.lookupWorlds();
|
||||
final World world = worldResult.findWorld(correctedWorld);
|
||||
|
||||
if (world != null)
|
||||
{
|
||||
final net.runelite.api.World rsWorld = client.createWorld();
|
||||
rsWorld.setActivity(world.getActivity());
|
||||
rsWorld.setAddress(world.getAddress());
|
||||
rsWorld.setId(world.getId());
|
||||
rsWorld.setPlayerCount(world.getPlayers());
|
||||
rsWorld.setLocation(world.getLocation());
|
||||
rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes()));
|
||||
|
||||
client.changeWorld(rsWorld);
|
||||
log.debug("Applied new world {}", correctedWorld);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn("World {} not found.", correctedWorld);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Error looking up world {}. Error: {}", correctedWorld, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyWorld()
|
||||
{
|
||||
if (worldCache == 0)
|
||||
{
|
||||
worldCache = client.getWorld();
|
||||
log.debug("Stored old world {}", worldCache);
|
||||
}
|
||||
|
||||
final int newWorld = config.getWorld();
|
||||
changeWorld(newWorld);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,154 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* 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.demonicgorilla;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
public class DemonicGorillaOverlay extends Overlay
|
||||
{
|
||||
private static final Color COLOR_ICON_BACKGROUND = new Color(0, 0, 0, 128);
|
||||
private static final Color COLOR_ICON_BORDER = new Color(0, 0, 0, 255);
|
||||
private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255);
|
||||
private static final int OVERLAY_ICON_DISTANCE = 50;
|
||||
private static final int OVERLAY_ICON_MARGIN = 8;
|
||||
|
||||
private Client client;
|
||||
private DemonicGorillaPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private SkillIconManager iconManager;
|
||||
|
||||
@Inject
|
||||
public DemonicGorillaOverlay(Client client, DemonicGorillaPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
private BufferedImage getIcon(DemonicGorilla.AttackStyle attackStyle)
|
||||
{
|
||||
switch (attackStyle)
|
||||
{
|
||||
case MELEE: return iconManager.getSkillImage(Skill.ATTACK);
|
||||
case RANGED: return iconManager.getSkillImage(Skill.RANGED);
|
||||
case MAGIC: return iconManager.getSkillImage(Skill.MAGIC);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (DemonicGorilla gorilla : plugin.getGorillas().values())
|
||||
{
|
||||
if (gorilla.getNpc().getInteracting() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint lp = gorilla.getNpc().getLocalLocation();
|
||||
if (lp != null)
|
||||
{
|
||||
Point point = Perspective.localToCanvas(client, lp, client.getPlane(),
|
||||
gorilla.getNpc().getLogicalHeight() + 16);
|
||||
if (point != null)
|
||||
{
|
||||
point = new Point(point.getX(), point.getY());
|
||||
|
||||
List<DemonicGorilla.AttackStyle> attackStyles = gorilla.getNextPosibleAttackStyles();
|
||||
List<BufferedImage> icons = new ArrayList<>();
|
||||
int totalWidth = (attackStyles.size() - 1) * OVERLAY_ICON_MARGIN;
|
||||
for (DemonicGorilla.AttackStyle attackStyle : attackStyles)
|
||||
{
|
||||
BufferedImage icon = getIcon(attackStyle);
|
||||
icons.add(icon);
|
||||
totalWidth += icon.getWidth();
|
||||
}
|
||||
|
||||
int bgPadding = 4;
|
||||
int currentPosX = 0;
|
||||
for (BufferedImage icon : icons)
|
||||
{
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.setColor(COLOR_ICON_BACKGROUND);
|
||||
graphics.fillOval(
|
||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||
icon.getWidth() + bgPadding * 2,
|
||||
icon.getHeight() + bgPadding * 2);
|
||||
|
||||
graphics.setColor(COLOR_ICON_BORDER);
|
||||
graphics.drawOval(
|
||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||
icon.getWidth() + bgPadding * 2,
|
||||
icon.getHeight() + bgPadding * 2);
|
||||
|
||||
graphics.drawImage(
|
||||
icon,
|
||||
point.getX() - totalWidth / 2 + currentPosX,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
|
||||
null);
|
||||
|
||||
graphics.setColor(COLOR_ICON_BORDER_FILL);
|
||||
Arc2D.Double arc = new Arc2D.Double(
|
||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||
icon.getWidth() + bgPadding * 2,
|
||||
icon.getHeight() + bgPadding * 2,
|
||||
90.0,
|
||||
-360.0 * (DemonicGorilla.ATTACKS_PER_SWITCH -
|
||||
gorilla.getAttacksUntilSwitch()) / DemonicGorilla.ATTACKS_PER_SWITCH,
|
||||
Arc2D.OPEN);
|
||||
graphics.draw(arc);
|
||||
|
||||
currentPosX += icon.getWidth() + OVERLAY_ICON_MARGIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* 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.demonicgorilla;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
public class DemonicGorillaOverlay extends Overlay
|
||||
{
|
||||
private static final Color COLOR_ICON_BACKGROUND = new Color(0, 0, 0, 128);
|
||||
private static final Color COLOR_ICON_BORDER = new Color(0, 0, 0, 255);
|
||||
private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255);
|
||||
private static final int OVERLAY_ICON_DISTANCE = 50;
|
||||
private static final int OVERLAY_ICON_MARGIN = 8;
|
||||
|
||||
private Client client;
|
||||
private DemonicGorillaPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private SkillIconManager iconManager;
|
||||
|
||||
@Inject
|
||||
public DemonicGorillaOverlay(Client client, DemonicGorillaPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
private BufferedImage getIcon(DemonicGorilla.AttackStyle attackStyle)
|
||||
{
|
||||
switch (attackStyle)
|
||||
{
|
||||
case MELEE:
|
||||
return iconManager.getSkillImage(Skill.ATTACK);
|
||||
case RANGED:
|
||||
return iconManager.getSkillImage(Skill.RANGED);
|
||||
case MAGIC:
|
||||
return iconManager.getSkillImage(Skill.MAGIC);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (DemonicGorilla gorilla : plugin.getGorillas().values())
|
||||
{
|
||||
if (gorilla.getNpc().getInteracting() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint lp = gorilla.getNpc().getLocalLocation();
|
||||
if (lp != null)
|
||||
{
|
||||
Point point = Perspective.localToCanvas(client, lp, client.getPlane(),
|
||||
gorilla.getNpc().getLogicalHeight() + 16);
|
||||
if (point != null)
|
||||
{
|
||||
point = new Point(point.getX(), point.getY());
|
||||
|
||||
List<DemonicGorilla.AttackStyle> attackStyles = gorilla.getNextPosibleAttackStyles();
|
||||
List<BufferedImage> icons = new ArrayList<>();
|
||||
int totalWidth = (attackStyles.size() - 1) * OVERLAY_ICON_MARGIN;
|
||||
for (DemonicGorilla.AttackStyle attackStyle : attackStyles)
|
||||
{
|
||||
BufferedImage icon = getIcon(attackStyle);
|
||||
icons.add(icon);
|
||||
totalWidth += icon.getWidth();
|
||||
}
|
||||
|
||||
int bgPadding = 4;
|
||||
int currentPosX = 0;
|
||||
for (BufferedImage icon : icons)
|
||||
{
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.setColor(COLOR_ICON_BACKGROUND);
|
||||
graphics.fillOval(
|
||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||
icon.getWidth() + bgPadding * 2,
|
||||
icon.getHeight() + bgPadding * 2);
|
||||
|
||||
graphics.setColor(COLOR_ICON_BORDER);
|
||||
graphics.drawOval(
|
||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||
icon.getWidth() + bgPadding * 2,
|
||||
icon.getHeight() + bgPadding * 2);
|
||||
|
||||
graphics.drawImage(
|
||||
icon,
|
||||
point.getX() - totalWidth / 2 + currentPosX,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
|
||||
null);
|
||||
|
||||
graphics.setColor(COLOR_ICON_BORDER_FILL);
|
||||
Arc2D.Double arc = new Arc2D.Double(
|
||||
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
|
||||
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
|
||||
icon.getWidth() + bgPadding * 2,
|
||||
icon.getHeight() + bgPadding * 2,
|
||||
90.0,
|
||||
-360.0 * (DemonicGorilla.ATTACKS_PER_SWITCH -
|
||||
gorilla.getAttacksUntilSwitch()) / DemonicGorilla.ATTACKS_PER_SWITCH,
|
||||
Arc2D.OPEN);
|
||||
graphics.draw(arc);
|
||||
|
||||
currentPosX += icon.getWidth() + OVERLAY_ICON_MARGIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,98 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Matthew Steglinski <https://github.com/sainttx>
|
||||
* 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.devtools;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
public class CameraOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final DevToolsPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
CameraOverlay(Client client, DevToolsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
panelComponent.setPreferredSize(new Dimension(150, 0));
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.getCameraPosition().isActive())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Camera")
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("X")
|
||||
.right("" + client.getCameraX())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Y")
|
||||
.right("" + client.getCameraY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Z")
|
||||
.right("" + client.getCameraZ())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Pitch")
|
||||
.right("" + client.getCameraPitch())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Yaw")
|
||||
.right("" + client.getCameraYaw())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Scale")
|
||||
.right("" + client.getScale())
|
||||
.build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Matthew Steglinski <https://github.com/sainttx>
|
||||
* 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.devtools;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
public class CameraOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final DevToolsPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
CameraOverlay(Client client, DevToolsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
panelComponent.setPreferredSize(new Dimension(150, 0));
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.getCameraPosition().isActive())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Camera")
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("X")
|
||||
.right("" + client.getCameraX())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Y")
|
||||
.right("" + client.getCameraY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Z")
|
||||
.right("" + client.getCameraZ())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Pitch")
|
||||
.right("" + client.getCameraPitch())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Yaw")
|
||||
.right("" + client.getCameraYaw())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Scale")
|
||||
.right("" + client.getScale())
|
||||
.build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,11 +118,11 @@ class DevToolsPanel extends PluginPanel
|
||||
varInspector.open();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
container.add(plugin.getLogMenuActions());
|
||||
plugin.getLogMenuActions().addActionListener((ev) ->
|
||||
{
|
||||
if(plugin.getLogMenuActions().isActive())
|
||||
if (plugin.getLogMenuActions().isActive())
|
||||
{
|
||||
client.setPrintMenuActions(false);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class DevToolsPlugin extends Plugin
|
||||
{
|
||||
private static final List<MenuAction> EXAMINE_MENU_ACTIONS = ImmutableList.of(MenuAction.EXAMINE_ITEM,
|
||||
MenuAction.EXAMINE_ITEM_GROUND, MenuAction.EXAMINE_NPC, MenuAction.EXAMINE_OBJECT);
|
||||
MenuAction.EXAMINE_ITEM_GROUND, MenuAction.EXAMINE_NPC, MenuAction.EXAMINE_OBJECT);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
@@ -119,7 +119,7 @@ public class DevToolsPlugin extends Plugin
|
||||
private DevToolsButton validMovement;
|
||||
private DevToolsButton lineOfSight;
|
||||
private DevToolsButton cameraPosition;
|
||||
private DevToolsButton worldMapLocation ;
|
||||
private DevToolsButton worldMapLocation;
|
||||
private DevToolsButton tileLocation;
|
||||
private DevToolsButton interacting;
|
||||
private DevToolsButton examine;
|
||||
@@ -174,7 +174,7 @@ public class DevToolsPlugin extends Plugin
|
||||
overlayManager.add(cameraOverlay);
|
||||
overlayManager.add(worldMapLocationOverlay);
|
||||
overlayManager.add(mapRegionOverlay);
|
||||
|
||||
|
||||
logMenuActions = new DevToolsButton("Menu Actions");
|
||||
|
||||
final DevToolsPanel panel = injector.getInstance(DevToolsPanel.class);
|
||||
|
||||
@@ -1,122 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <https://github.com/sethtroll>
|
||||
* 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.devtools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class LocationOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final DevToolsPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
LocationOverlay(Client client, DevToolsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
panelComponent.setPreferredSize(new Dimension(150, 0));
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.getLocation().isActive())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
WorldPoint localWorld = client.getLocalPlayer().getWorldLocation();
|
||||
LocalPoint localPoint = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
int regionID = localWorld.getRegionID();
|
||||
|
||||
if (client.isInInstancedRegion())
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Instance")
|
||||
.build());
|
||||
|
||||
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
||||
int z = client.getPlane();
|
||||
int chunkData = instanceTemplateChunks[z][localPoint.getSceneX() / CHUNK_SIZE][localPoint.getSceneY() / CHUNK_SIZE];
|
||||
|
||||
int rotation = chunkData >> 1 & 0x3;
|
||||
int chunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
||||
int chunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Chunk " + localPoint.getSceneX() / CHUNK_SIZE + "," + localPoint.getSceneY() / CHUNK_SIZE)
|
||||
.right(rotation + " " + chunkX + " " + chunkY)
|
||||
.build());
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Base")
|
||||
.right(client.getBaseX() + ", " + client.getBaseY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Local")
|
||||
.right(localPoint.getX() + ", " + localPoint.getY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Scene")
|
||||
.right(localPoint.getSceneX() + ", " + localPoint.getSceneY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Tile")
|
||||
.right(localWorld.getX() + ", " + localWorld.getY() + ", " + client.getPlane())
|
||||
.build());
|
||||
|
||||
for (int i = 0; i < client.getMapRegions().length; i++)
|
||||
{
|
||||
int region = client.getMapRegions()[i];
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left((i == 0) ? "Map regions" : " ")
|
||||
.right(String.valueOf(region))
|
||||
.rightColor((region == regionID) ? Color.GREEN : Color.WHITE)
|
||||
.build());
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <https://github.com/sethtroll>
|
||||
* 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.devtools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class LocationOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final DevToolsPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
LocationOverlay(Client client, DevToolsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
panelComponent.setPreferredSize(new Dimension(150, 0));
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.getLocation().isActive())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
WorldPoint localWorld = client.getLocalPlayer().getWorldLocation();
|
||||
LocalPoint localPoint = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
int regionID = localWorld.getRegionID();
|
||||
|
||||
if (client.isInInstancedRegion())
|
||||
{
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Instance")
|
||||
.build());
|
||||
|
||||
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
||||
int z = client.getPlane();
|
||||
int chunkData = instanceTemplateChunks[z][localPoint.getSceneX() / CHUNK_SIZE][localPoint.getSceneY() / CHUNK_SIZE];
|
||||
|
||||
int rotation = chunkData >> 1 & 0x3;
|
||||
int chunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
||||
int chunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Chunk " + localPoint.getSceneX() / CHUNK_SIZE + "," + localPoint.getSceneY() / CHUNK_SIZE)
|
||||
.right(rotation + " " + chunkX + " " + chunkY)
|
||||
.build());
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Base")
|
||||
.right(client.getBaseX() + ", " + client.getBaseY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Local")
|
||||
.right(localPoint.getX() + ", " + localPoint.getY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Scene")
|
||||
.right(localPoint.getSceneX() + ", " + localPoint.getSceneY())
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Tile")
|
||||
.right(localWorld.getX() + ", " + localWorld.getY() + ", " + client.getPlane())
|
||||
.build());
|
||||
|
||||
for (int i = 0; i < client.getMapRegions().length; i++)
|
||||
{
|
||||
int region = client.getMapRegions()[i];
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left((i == 0) ? "Map regions" : " ")
|
||||
.right(String.valueOf(region))
|
||||
.rightColor((region == regionID) ? Color.GREEN : Color.WHITE)
|
||||
.build());
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,106 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Morgan Lewis <https://github.com/MESLewis>
|
||||
* 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.devtools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.RenderOverview;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
|
||||
|
||||
public class WorldMapLocationOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final WorldMapOverlay worldMapOverlay;
|
||||
private final DevToolsPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private WorldMapLocationOverlay(Client client, WorldMapOverlay worldMapOverlay, DevToolsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.worldMapOverlay = worldMapOverlay;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
setLayer(OverlayLayer.ABOVE_MAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.getWorldMapLocation().isActive())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
RenderOverview ro = client.getRenderOverview();
|
||||
Widget worldMapWidget = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
|
||||
if (ro == null || worldMapWidget == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Rectangle worldMapRectangle = worldMapWidget.getBounds();
|
||||
|
||||
graphics.setClip(worldMapRectangle);
|
||||
graphics.setColor(Color.CYAN);
|
||||
|
||||
WorldPoint mapCenterPoint = new WorldPoint(ro.getWorldMapPosition().getX(), ro.getWorldMapPosition().getY(), 0);
|
||||
Point middle = worldMapOverlay.mapWorldPointToGraphicsPoint(mapCenterPoint);
|
||||
|
||||
if (middle == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
graphics.drawLine(middle.getX(), worldMapRectangle.y, middle.getX(), worldMapRectangle.y + worldMapRectangle.height);
|
||||
graphics.drawLine(worldMapRectangle.x, middle.getY(), worldMapRectangle.x + worldMapRectangle.width, middle.getY());
|
||||
|
||||
String output = "Center: " + mapCenterPoint.getX() + ", " + mapCenterPoint.getY();
|
||||
graphics.setColor(Color.white);
|
||||
FontMetrics fm = graphics.getFontMetrics();
|
||||
int height = fm.getHeight();
|
||||
int width = fm.stringWidth(output);
|
||||
graphics.fillRect((int)worldMapRectangle.getX(), (int)worldMapRectangle.getY() + worldMapRectangle.height - height, (int)worldMapRectangle.getX() + width, (int)worldMapRectangle.getY() + worldMapRectangle.height);
|
||||
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawString(output, (int) worldMapRectangle.getX(), (int) worldMapRectangle.getY() + worldMapRectangle.height);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Morgan Lewis <https://github.com/MESLewis>
|
||||
* 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.devtools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.RenderOverview;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay;
|
||||
|
||||
public class WorldMapLocationOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final WorldMapOverlay worldMapOverlay;
|
||||
private final DevToolsPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private WorldMapLocationOverlay(Client client, WorldMapOverlay worldMapOverlay, DevToolsPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.worldMapOverlay = worldMapOverlay;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
setLayer(OverlayLayer.ABOVE_MAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.getWorldMapLocation().isActive())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
RenderOverview ro = client.getRenderOverview();
|
||||
Widget worldMapWidget = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
|
||||
if (ro == null || worldMapWidget == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Rectangle worldMapRectangle = worldMapWidget.getBounds();
|
||||
|
||||
graphics.setClip(worldMapRectangle);
|
||||
graphics.setColor(Color.CYAN);
|
||||
|
||||
WorldPoint mapCenterPoint = new WorldPoint(ro.getWorldMapPosition().getX(), ro.getWorldMapPosition().getY(), 0);
|
||||
Point middle = worldMapOverlay.mapWorldPointToGraphicsPoint(mapCenterPoint);
|
||||
|
||||
if (middle == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
graphics.drawLine(middle.getX(), worldMapRectangle.y, middle.getX(), worldMapRectangle.y + worldMapRectangle.height);
|
||||
graphics.drawLine(worldMapRectangle.x, middle.getY(), worldMapRectangle.x + worldMapRectangle.width, middle.getY());
|
||||
|
||||
String output = "Center: " + mapCenterPoint.getX() + ", " + mapCenterPoint.getY();
|
||||
graphics.setColor(Color.white);
|
||||
FontMetrics fm = graphics.getFontMetrics();
|
||||
int height = fm.getHeight();
|
||||
int width = fm.stringWidth(output);
|
||||
graphics.fillRect((int) worldMapRectangle.getX(), (int) worldMapRectangle.getY() + worldMapRectangle.height - height, (int) worldMapRectangle.getX() + width, (int) worldMapRectangle.getY() + worldMapRectangle.height);
|
||||
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawString(output, (int) worldMapRectangle.getX(), (int) worldMapRectangle.getY() + worldMapRectangle.height);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,68 +86,68 @@ enum DiscordGameEventType
|
||||
BOSS_ZULRAH("Zulrah", DiscordAreaType.BOSSES, 9007),
|
||||
|
||||
// Cities
|
||||
CITY_AL_KHARID("Al Kharid" , DiscordAreaType.CITIES, 13105, 13106),
|
||||
CITY_APE_ATOLL("Ape Atoll" , DiscordAreaType.CITIES, 10795, 11051, 10974, 11050),
|
||||
CITY_ARCEUUS_HOUSE("Arceuus" , DiscordAreaType.CITIES, 6459, 6715, 6458, 6714),
|
||||
CITY_ARDOUGNE("Ardougne" , DiscordAreaType.CITIES, 10548, 10547, 10292, 10291, 10036, 10035, 9780, 9779),
|
||||
CITY_BARBARIAN_VILLAGE("Barbarian Village" , DiscordAreaType.CITIES, 12341),
|
||||
CITY_BANDIT_CAMP("Bandit Camp" , DiscordAreaType.CITIES, 12591),
|
||||
CITY_BEDABIN_CAMP("Bedabin Camp" , DiscordAreaType.CITIES, 12590),
|
||||
CITY_BRIMHAVEN("Brimhaven" , DiscordAreaType.CITIES, 11057, 11058),
|
||||
CITY_BURGH_DE_ROTT("Burgh de Rott" , DiscordAreaType.CITIES, 13874, 13873, 14130, 14129),
|
||||
CITY_BURTHORPE("Burthorpe" , DiscordAreaType.CITIES, 11319, 11575),
|
||||
CITY_CANIFIS("Canifis" , DiscordAreaType.CITIES, 13878),
|
||||
CITY_CATHERBY("Catherby" , DiscordAreaType.CITIES, 11317, 11318, 11061),
|
||||
CITY_CORSAIR_CAVE("Corsair Cove" , DiscordAreaType.CITIES, 10028, 10284),
|
||||
CITY_DORGESH_KAAN("Dorgesh-Kaan" , DiscordAreaType.CITIES, 10835, 10834),
|
||||
CITY_DRAYNOR("Draynor" , DiscordAreaType.CITIES, 12338),
|
||||
CITY_EDGEVILLE("Edgeville" , DiscordAreaType.CITIES, 12342),
|
||||
CITY_ENTRANA("Entrana" , DiscordAreaType.CITIES, 11060, 11316),
|
||||
CITY_FALADOR("Falador" , DiscordAreaType.CITIES, 11828, 11572, 11571, 11827, 12084),
|
||||
CITY_GOBLIN_VILLAGE("Goblin Village" , DiscordAreaType.CITIES, 11830),
|
||||
CITY_GUTANOTH("Gu'Tanoth" , DiscordAreaType.CITIES, 10031),
|
||||
CITY_HOSIDIUS_HOUSE("Hosidius" , DiscordAreaType.CITIES, 6713, 6712, 6455, 6711, 6710, 6965, 6966, 7222, 7223, 6967),
|
||||
CITY_JATISZO("Jatizso" , DiscordAreaType.CITIES, 9531),
|
||||
CITY_JIGGIG("Jiggig" , DiscordAreaType.CITIES, 9775),
|
||||
CITY_KARAMJA("Karamja" , DiscordAreaType.CITIES, 11569, 11568, 11567, 11566, 11313, 11312, 11311),
|
||||
CITY_KELDAGRIM("Keldagrim" , DiscordAreaType.CITIES, 11423, 11422, 11679, 11678),
|
||||
CITY_LLETYA("Lletya" , DiscordAreaType.CITIES, 9265),
|
||||
CITY_LOVAKENGJ_HOUSE("Lovakengj" , DiscordAreaType.CITIES, 5692, 5948, 5691, 5947, 6203, 6202, 5690, 5946),
|
||||
CITY_LUMBRIDGE("Lumbridge" , DiscordAreaType.CITIES, 12850),
|
||||
CITY_LUNAR_ISLE("Lunar Isle" , DiscordAreaType.CITIES, 8253, 8252, 8509, 8508),
|
||||
CITY_MEIYERDITCH("Meiyerditch" , DiscordAreaType.CITIES, 14132, 14388, 14387, 14386, 14385),
|
||||
CITY_MISCELLANIA("Miscellania" , DiscordAreaType.CITIES, 10044, 10300),
|
||||
CITY_MOS_LE_HARMLESS("Mos Le'Harmless" , DiscordAreaType.CITIES, 14638),
|
||||
CITY_MORTTON("Mort'ton" , DiscordAreaType.CITIES, 13875),
|
||||
CITY_MOR_UI_REK("Mor UI Rek" , DiscordAreaType.CITIES, 9808, 9807, 10064, 10063),
|
||||
CITY_AL_KHARID("Al Kharid", DiscordAreaType.CITIES, 13105, 13106),
|
||||
CITY_APE_ATOLL("Ape Atoll", DiscordAreaType.CITIES, 10795, 11051, 10974, 11050),
|
||||
CITY_ARCEUUS_HOUSE("Arceuus", DiscordAreaType.CITIES, 6459, 6715, 6458, 6714),
|
||||
CITY_ARDOUGNE("Ardougne", DiscordAreaType.CITIES, 10548, 10547, 10292, 10291, 10036, 10035, 9780, 9779),
|
||||
CITY_BARBARIAN_VILLAGE("Barbarian Village", DiscordAreaType.CITIES, 12341),
|
||||
CITY_BANDIT_CAMP("Bandit Camp", DiscordAreaType.CITIES, 12591),
|
||||
CITY_BEDABIN_CAMP("Bedabin Camp", DiscordAreaType.CITIES, 12590),
|
||||
CITY_BRIMHAVEN("Brimhaven", DiscordAreaType.CITIES, 11057, 11058),
|
||||
CITY_BURGH_DE_ROTT("Burgh de Rott", DiscordAreaType.CITIES, 13874, 13873, 14130, 14129),
|
||||
CITY_BURTHORPE("Burthorpe", DiscordAreaType.CITIES, 11319, 11575),
|
||||
CITY_CANIFIS("Canifis", DiscordAreaType.CITIES, 13878),
|
||||
CITY_CATHERBY("Catherby", DiscordAreaType.CITIES, 11317, 11318, 11061),
|
||||
CITY_CORSAIR_CAVE("Corsair Cove", DiscordAreaType.CITIES, 10028, 10284),
|
||||
CITY_DORGESH_KAAN("Dorgesh-Kaan", DiscordAreaType.CITIES, 10835, 10834),
|
||||
CITY_DRAYNOR("Draynor", DiscordAreaType.CITIES, 12338),
|
||||
CITY_EDGEVILLE("Edgeville", DiscordAreaType.CITIES, 12342),
|
||||
CITY_ENTRANA("Entrana", DiscordAreaType.CITIES, 11060, 11316),
|
||||
CITY_FALADOR("Falador", DiscordAreaType.CITIES, 11828, 11572, 11571, 11827, 12084),
|
||||
CITY_GOBLIN_VILLAGE("Goblin Village", DiscordAreaType.CITIES, 11830),
|
||||
CITY_GUTANOTH("Gu'Tanoth", DiscordAreaType.CITIES, 10031),
|
||||
CITY_HOSIDIUS_HOUSE("Hosidius", DiscordAreaType.CITIES, 6713, 6712, 6455, 6711, 6710, 6965, 6966, 7222, 7223, 6967),
|
||||
CITY_JATISZO("Jatizso", DiscordAreaType.CITIES, 9531),
|
||||
CITY_JIGGIG("Jiggig", DiscordAreaType.CITIES, 9775),
|
||||
CITY_KARAMJA("Karamja", DiscordAreaType.CITIES, 11569, 11568, 11567, 11566, 11313, 11312, 11311),
|
||||
CITY_KELDAGRIM("Keldagrim", DiscordAreaType.CITIES, 11423, 11422, 11679, 11678),
|
||||
CITY_LLETYA("Lletya", DiscordAreaType.CITIES, 9265),
|
||||
CITY_LOVAKENGJ_HOUSE("Lovakengj", DiscordAreaType.CITIES, 5692, 5948, 5691, 5947, 6203, 6202, 5690, 5946),
|
||||
CITY_LUMBRIDGE("Lumbridge", DiscordAreaType.CITIES, 12850),
|
||||
CITY_LUNAR_ISLE("Lunar Isle", DiscordAreaType.CITIES, 8253, 8252, 8509, 8508),
|
||||
CITY_MEIYERDITCH("Meiyerditch", DiscordAreaType.CITIES, 14132, 14388, 14387, 14386, 14385),
|
||||
CITY_MISCELLANIA("Miscellania", DiscordAreaType.CITIES, 10044, 10300),
|
||||
CITY_MOS_LE_HARMLESS("Mos Le'Harmless", DiscordAreaType.CITIES, 14638),
|
||||
CITY_MORTTON("Mort'ton", DiscordAreaType.CITIES, 13875),
|
||||
CITY_MOR_UI_REK("Mor UI Rek", DiscordAreaType.CITIES, 9808, 9807, 10064, 10063),
|
||||
CITY_MOUNT_KARUULM("Mount Karuulm", DiscordAreaType.CITIES, 5179, 4923, 5180),
|
||||
CITY_NARDAH("Nardah" , DiscordAreaType.CITIES, 13613),
|
||||
CITY_NEITIZNOT("Neitiznot" , DiscordAreaType.CITIES, 9275),
|
||||
CITY_PISCATORIS("Piscatoris" , DiscordAreaType.CITIES, 9273),
|
||||
CITY_POLLNIVNEACH("Pollnivneach" , DiscordAreaType.CITIES, 13358),
|
||||
CITY_PORT_KHAZARD("Port Khazard" , DiscordAreaType.CITIES, 10545),
|
||||
CITY_PORT_PHASMATYS("Port Phasmatys" , DiscordAreaType.CITIES, 14646),
|
||||
CITY_PORT_SARIM("Port Sarim" , DiscordAreaType.CITIES, 12082),
|
||||
CITY_PISCARILIUS_HOUSE("Port Piscarilius" , DiscordAreaType.CITIES, 6971, 7227, 6970, 7226),
|
||||
CITY_RELLEKKA("Rellekka" , DiscordAreaType.CITIES, 10553),
|
||||
CITY_RIMMINGTON("Rimmington" , DiscordAreaType.CITIES, 11826, 11570),
|
||||
CITY_SEERS_VILLAGE("Seers' Village" , DiscordAreaType.CITIES, 10806),
|
||||
CITY_SHAYZIEN_HOUSE("Shayzien" , DiscordAreaType.CITIES, 5944, 5943, 6200, 6199, 5688),
|
||||
CITY_SHILO_VILLAGE("Shilo Village" , DiscordAreaType.CITIES, 11310),
|
||||
CITY_SOPHANEM("Sophanem" , DiscordAreaType.CITIES, 13099),
|
||||
CITY_TAI_BWO_WANNAI("Tai Bwo Wannai" , DiscordAreaType.CITIES, 11056, 11055),
|
||||
CITY_TAVERLEY("Taverley" , DiscordAreaType.CITIES, 11574, 11573),
|
||||
CITY_TREE_GNOME_STRONGHOLD("Tree Gnome Stronghold" , DiscordAreaType.CITIES, 9782, 9781),
|
||||
CITY_TREE_GNOME_VILLAGE("Tree Gnome Village" , DiscordAreaType.CITIES, 10033),
|
||||
CITY_TROLL_STRONGHOLD("Troll Stronghold" , DiscordAreaType.CITIES, 11321),
|
||||
CITY_TYRAS_CAMP("Tyras Camp" , DiscordAreaType.CITIES, 8753, 8752),
|
||||
CITY_UZER("Uzer" , DiscordAreaType.CITIES, 13872),
|
||||
CITY_VARROCK("Varrock" , DiscordAreaType.CITIES, 12596, 12597, 12598, 12852, 12853, 12854, 13108, 13109, 13110),
|
||||
CITY_WITCHHAVEN("Witchaven" , DiscordAreaType.CITIES, 10803),
|
||||
CITY_NARDAH("Nardah", DiscordAreaType.CITIES, 13613),
|
||||
CITY_NEITIZNOT("Neitiznot", DiscordAreaType.CITIES, 9275),
|
||||
CITY_PISCATORIS("Piscatoris", DiscordAreaType.CITIES, 9273),
|
||||
CITY_POLLNIVNEACH("Pollnivneach", DiscordAreaType.CITIES, 13358),
|
||||
CITY_PORT_KHAZARD("Port Khazard", DiscordAreaType.CITIES, 10545),
|
||||
CITY_PORT_PHASMATYS("Port Phasmatys", DiscordAreaType.CITIES, 14646),
|
||||
CITY_PORT_SARIM("Port Sarim", DiscordAreaType.CITIES, 12082),
|
||||
CITY_PISCARILIUS_HOUSE("Port Piscarilius", DiscordAreaType.CITIES, 6971, 7227, 6970, 7226),
|
||||
CITY_RELLEKKA("Rellekka", DiscordAreaType.CITIES, 10553),
|
||||
CITY_RIMMINGTON("Rimmington", DiscordAreaType.CITIES, 11826, 11570),
|
||||
CITY_SEERS_VILLAGE("Seers' Village", DiscordAreaType.CITIES, 10806),
|
||||
CITY_SHAYZIEN_HOUSE("Shayzien", DiscordAreaType.CITIES, 5944, 5943, 6200, 6199, 5688),
|
||||
CITY_SHILO_VILLAGE("Shilo Village", DiscordAreaType.CITIES, 11310),
|
||||
CITY_SOPHANEM("Sophanem", DiscordAreaType.CITIES, 13099),
|
||||
CITY_TAI_BWO_WANNAI("Tai Bwo Wannai", DiscordAreaType.CITIES, 11056, 11055),
|
||||
CITY_TAVERLEY("Taverley", DiscordAreaType.CITIES, 11574, 11573),
|
||||
CITY_TREE_GNOME_STRONGHOLD("Tree Gnome Stronghold", DiscordAreaType.CITIES, 9782, 9781),
|
||||
CITY_TREE_GNOME_VILLAGE("Tree Gnome Village", DiscordAreaType.CITIES, 10033),
|
||||
CITY_TROLL_STRONGHOLD("Troll Stronghold", DiscordAreaType.CITIES, 11321),
|
||||
CITY_TYRAS_CAMP("Tyras Camp", DiscordAreaType.CITIES, 8753, 8752),
|
||||
CITY_UZER("Uzer", DiscordAreaType.CITIES, 13872),
|
||||
CITY_VARROCK("Varrock", DiscordAreaType.CITIES, 12596, 12597, 12598, 12852, 12853, 12854, 13108, 13109, 13110),
|
||||
CITY_WITCHHAVEN("Witchaven", DiscordAreaType.CITIES, 10803),
|
||||
CITY_WOODCUTTING_GUILD("Woodcutting Guild", DiscordAreaType.CITIES, 6454, 6198, 6298),
|
||||
CITY_YANILLE("Yanille" , DiscordAreaType.CITIES, 10288, 10032),
|
||||
CITY_ZANARIS("Zanaris" , DiscordAreaType.CITIES, 9285, 9541, 9540, 9797),
|
||||
CITY_ZULANDRA("Zul-Andra" , DiscordAreaType.CITIES, 8751),
|
||||
CITY_YANILLE("Yanille", DiscordAreaType.CITIES, 10288, 10032),
|
||||
CITY_ZANARIS("Zanaris", DiscordAreaType.CITIES, 9285, 9541, 9540, 9797),
|
||||
CITY_ZULANDRA("Zul-Andra", DiscordAreaType.CITIES, 8751),
|
||||
|
||||
// Dungeons
|
||||
DUNGEON_ABANDONED_MINE("Abandoned Mine", DiscordAreaType.DUNGEONS, 13718, 11079, 11078, 11077, 10823, 10822, 10821),
|
||||
@@ -358,29 +358,52 @@ enum DiscordGameEventType
|
||||
{
|
||||
switch (skill)
|
||||
{
|
||||
case ATTACK: return TRAINING_ATTACK;
|
||||
case DEFENCE: return TRAINING_DEFENCE;
|
||||
case STRENGTH: return TRAINING_STRENGTH;
|
||||
case RANGED: return TRAINING_RANGED;
|
||||
case PRAYER: return TRAINING_PRAYER;
|
||||
case MAGIC: return TRAINING_MAGIC;
|
||||
case COOKING: return TRAINING_COOKING;
|
||||
case WOODCUTTING: return TRAINING_WOODCUTTING;
|
||||
case FLETCHING: return TRAINING_FLETCHING;
|
||||
case FISHING: return TRAINING_FISHING;
|
||||
case FIREMAKING: return TRAINING_FIREMAKING;
|
||||
case CRAFTING: return TRAINING_CRAFTING;
|
||||
case SMITHING: return TRAINING_SMITHING;
|
||||
case MINING: return TRAINING_MINING;
|
||||
case HERBLORE: return TRAINING_HERBLORE;
|
||||
case AGILITY: return TRAINING_AGILITY;
|
||||
case THIEVING: return TRAINING_THIEVING;
|
||||
case SLAYER: return TRAINING_SLAYER;
|
||||
case FARMING: return TRAINING_FARMING;
|
||||
case RUNECRAFT: return TRAINING_RUNECRAFT;
|
||||
case HUNTER: return TRAINING_HUNTER;
|
||||
case CONSTRUCTION: return TRAINING_CONSTRUCTION;
|
||||
default: return null;
|
||||
case ATTACK:
|
||||
return TRAINING_ATTACK;
|
||||
case DEFENCE:
|
||||
return TRAINING_DEFENCE;
|
||||
case STRENGTH:
|
||||
return TRAINING_STRENGTH;
|
||||
case RANGED:
|
||||
return TRAINING_RANGED;
|
||||
case PRAYER:
|
||||
return TRAINING_PRAYER;
|
||||
case MAGIC:
|
||||
return TRAINING_MAGIC;
|
||||
case COOKING:
|
||||
return TRAINING_COOKING;
|
||||
case WOODCUTTING:
|
||||
return TRAINING_WOODCUTTING;
|
||||
case FLETCHING:
|
||||
return TRAINING_FLETCHING;
|
||||
case FISHING:
|
||||
return TRAINING_FISHING;
|
||||
case FIREMAKING:
|
||||
return TRAINING_FIREMAKING;
|
||||
case CRAFTING:
|
||||
return TRAINING_CRAFTING;
|
||||
case SMITHING:
|
||||
return TRAINING_SMITHING;
|
||||
case MINING:
|
||||
return TRAINING_MINING;
|
||||
case HERBLORE:
|
||||
return TRAINING_HERBLORE;
|
||||
case AGILITY:
|
||||
return TRAINING_AGILITY;
|
||||
case THIEVING:
|
||||
return TRAINING_THIEVING;
|
||||
case SLAYER:
|
||||
return TRAINING_SLAYER;
|
||||
case FARMING:
|
||||
return TRAINING_FARMING;
|
||||
case RUNECRAFT:
|
||||
return TRAINING_RUNECRAFT;
|
||||
case HUNTER:
|
||||
return TRAINING_HUNTER;
|
||||
case CONSTRUCTION:
|
||||
return TRAINING_CONSTRUCTION;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -417,10 +417,14 @@ public class DiscordPlugin extends Plugin
|
||||
|
||||
switch (event.getDiscordAreaType())
|
||||
{
|
||||
case BOSSES: return config.showBossActivity();
|
||||
case CITIES: return config.showCityActivity();
|
||||
case DUNGEONS: return config.showDungeonActivity();
|
||||
case MINIGAMES: return config.showMinigameActivity();
|
||||
case BOSSES:
|
||||
return config.showBossActivity();
|
||||
case CITIES:
|
||||
return config.showCityActivity();
|
||||
case DUNGEONS:
|
||||
return config.showDungeonActivity();
|
||||
case MINIGAMES:
|
||||
return config.showMinigameActivity();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,42 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum DuelingRingMode {
|
||||
DUEL_ARENA("Duel Arena"),
|
||||
CASTLE_WARS("Castle Wars"),
|
||||
CLAN_WARS("Clan Wars");
|
||||
|
||||
private final String name;
|
||||
|
||||
DuelingRingMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum DuelingRingMode
|
||||
{
|
||||
DUEL_ARENA("Duel Arena"),
|
||||
CASTLE_WARS("Castle Wars"),
|
||||
CLAN_WARS("Clan Wars");
|
||||
|
||||
private final String name;
|
||||
|
||||
DuelingRingMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,13 @@
|
||||
package net.runelite.client.plugins.easyscape;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuAction;
|
||||
import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
|
||||
import static net.runelite.api.MenuAction.WALK;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
@@ -43,322 +46,390 @@ import net.runelite.client.plugins.PluginType;
|
||||
import static net.runelite.client.util.MenuUtil.swap;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import javax.inject.Inject;
|
||||
import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
|
||||
import static net.runelite.api.MenuAction.WALK;
|
||||
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Easyscape",
|
||||
description = "Easyscape.",
|
||||
tags = {"Easyscape"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.UTILITY
|
||||
name = "Easyscape",
|
||||
description = "Easyscape.",
|
||||
tags = {"Easyscape"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class EasyscapePlugin extends Plugin {
|
||||
public class EasyscapePlugin extends Plugin
|
||||
{
|
||||
|
||||
private static final int PURO_PURO_REGION_ID = 10307;
|
||||
private static final int HOUSE_REGION_ID = 7513;
|
||||
private static final int PURO_PURO_REGION_ID = 10307;
|
||||
private static final int HOUSE_REGION_ID = 7513;
|
||||
|
||||
private MenuEntry[] entries;
|
||||
private MenuEntry[] entries;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EasyscapePluginConfig config;
|
||||
@Inject
|
||||
private EasyscapePluginConfig config;
|
||||
|
||||
@Provides
|
||||
EasyscapePluginConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(EasyscapePluginConfig.class);
|
||||
}
|
||||
@Provides
|
||||
EasyscapePluginConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(EasyscapePluginConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp() {
|
||||
log.debug("Easyscape Started.");
|
||||
}
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
log.debug("Easyscape Started.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() {
|
||||
log.debug("Easyscape Stopped.");
|
||||
}
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
log.debug("Easyscape Stopped.");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN);
|
||||
Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
Widget loginScreenOne = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN);
|
||||
Widget loginScreenTwo = client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN_MESSAGE_OF_THE_DAY);
|
||||
|
||||
if (loginScreenOne != null || loginScreenTwo != null) {
|
||||
return;
|
||||
}
|
||||
if (loginScreenOne != null || loginScreenTwo != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
final String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
final String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
entries = client.getMenuEntries();
|
||||
entries = client.getMenuEntries();
|
||||
|
||||
if (config.getRemoveExamine()) {
|
||||
for (int i = entries.length - 1; i >= 0; i--) {
|
||||
if (entries[i].getOption().equals("Examine")) {
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
if (config.getRemoveExamine())
|
||||
{
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
{
|
||||
if (entries[i].getOption().equals("Examine"))
|
||||
{
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
if (config.getRemoveObjects() && !config.getRemovedObjects().equals("")) {
|
||||
for (String removed : config.getRemovedObjects().split(",")) {
|
||||
removed = removed.trim();
|
||||
if (target.contains("->")) {
|
||||
String trimmed = target.split("->")[1].trim();
|
||||
if (trimmed.length() >= removed.length() && trimmed.substring(0, removed.length()).equalsIgnoreCase(removed)) {
|
||||
delete(event.getIdentifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (target.length() >= removed.length() && target.substring(0, removed.length()).equalsIgnoreCase(removed)) {
|
||||
delete(event.getIdentifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.getRemoveObjects() && !config.getRemovedObjects().equals(""))
|
||||
{
|
||||
for (String removed : config.getRemovedObjects().split(","))
|
||||
{
|
||||
removed = removed.trim();
|
||||
if (target.contains("->"))
|
||||
{
|
||||
String trimmed = target.split("->")[1].trim();
|
||||
if (trimmed.length() >= removed.length() && trimmed.substring(0, removed.length()).equalsIgnoreCase(removed))
|
||||
{
|
||||
delete(event.getIdentifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (target.length() >= removed.length() && target.substring(0, removed.length()).equalsIgnoreCase(removed))
|
||||
{
|
||||
delete(event.getIdentifier());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapPuro() && isPuroPuro()) {
|
||||
if (event.getType() == WALK.getId()) {
|
||||
MenuEntry menuEntry = entries[entries.length - 1];
|
||||
menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
else if (option.equalsIgnoreCase("examine")) {
|
||||
swap(client, "push-through", option, target);
|
||||
}
|
||||
else if (option.equalsIgnoreCase("use")) {
|
||||
swap(client, "escape", option, target);
|
||||
}
|
||||
}
|
||||
if (config.getSwapPuro() && isPuroPuro())
|
||||
{
|
||||
if (event.getType() == WALK.getId())
|
||||
{
|
||||
MenuEntry menuEntry = entries[entries.length - 1];
|
||||
menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
else if (option.equalsIgnoreCase("examine"))
|
||||
{
|
||||
swap(client, "push-through", option, target);
|
||||
}
|
||||
else if (option.equalsIgnoreCase("use"))
|
||||
{
|
||||
swap(client, "escape", option, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getEasyConstruction() && !config.getConstructionItems().equals("")) {
|
||||
if (event.getType() == WALK.getId()) {
|
||||
MenuEntry menuEntry = entries[entries.length - 1];
|
||||
menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
if (config.getEasyConstruction() && !config.getConstructionItems().equals(""))
|
||||
{
|
||||
if (event.getType() == WALK.getId())
|
||||
{
|
||||
MenuEntry menuEntry = entries[entries.length - 1];
|
||||
menuEntry.setType(MenuAction.WALK.getId() + MENU_ACTION_DEPRIORITIZE_OFFSET);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
swap(client, "Build", option, target);
|
||||
swap(client, "Build", option, target);
|
||||
|
||||
for (int i = entries.length - 1; i >= 0; i--) {
|
||||
for (String item : config.getConstructionItems().split(",")) {
|
||||
if (item.trim().equalsIgnoreCase(Text.removeTags(entries[i].getTarget()))) {
|
||||
if (!entries[i].getOption().equalsIgnoreCase("remove")) {
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
{
|
||||
for (String item : config.getConstructionItems().split(","))
|
||||
{
|
||||
if (item.trim().equalsIgnoreCase(Text.removeTags(entries[i].getTarget())))
|
||||
{
|
||||
if (!entries[i].getOption().equalsIgnoreCase("remove"))
|
||||
{
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
if (config.getSwapShop() && !config.getSwappedItems().equals("")) {
|
||||
for (String item : config.getSwappedItems().split(",")) {
|
||||
if (target.equalsIgnoreCase(item.trim())) {
|
||||
swap(client, "Buy 50", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.getSwapShop() && !config.getSwappedItems().equals(""))
|
||||
{
|
||||
for (String item : config.getSwappedItems().split(","))
|
||||
{
|
||||
if (target.equalsIgnoreCase(item.trim()))
|
||||
{
|
||||
swap(client, "Buy 50", option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapSmithing()) {
|
||||
if (option.equalsIgnoreCase("Smith 1")) {
|
||||
swap(client, "Smith All", option, target);
|
||||
} else if (option.equalsIgnoreCase("Smith 1 Set")) {
|
||||
swap(client, "Smith All Sets", option, target);
|
||||
}
|
||||
}
|
||||
if (config.getSwapSmithing())
|
||||
{
|
||||
if (option.equalsIgnoreCase("Smith 1"))
|
||||
{
|
||||
swap(client, "Smith All", option, target);
|
||||
}
|
||||
else if (option.equalsIgnoreCase("Smith 1 Set"))
|
||||
{
|
||||
swap(client, "Smith All Sets", option, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getSwapTanning() && option.equalsIgnoreCase("Tan 1")) {
|
||||
swap(client, "Tan All", option, target);
|
||||
}
|
||||
if (config.getSwapTanning() && option.equalsIgnoreCase("Tan 1"))
|
||||
{
|
||||
swap(client, "Tan All", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapCrafting() && option.equalsIgnoreCase("Make-1")) {
|
||||
swap(client, "Make-All", option, target);
|
||||
}
|
||||
if (config.getSwapCrafting() && option.equalsIgnoreCase("Make-1"))
|
||||
{
|
||||
swap(client, "Make-All", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapSawmill() && target.equalsIgnoreCase("Sawmill operator")) {
|
||||
swap(client, "Buy-plank", option, target);
|
||||
}
|
||||
if (config.getSwapSawmill() && target.equalsIgnoreCase("Sawmill operator"))
|
||||
{
|
||||
swap(client, "Buy-plank", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapSawmillPlanks() && option.equalsIgnoreCase("Buy 1")) {
|
||||
swap(client, "Buy All", option, target);
|
||||
}
|
||||
if (config.getSwapSawmillPlanks() && option.equalsIgnoreCase("Buy 1"))
|
||||
{
|
||||
swap(client, "Buy All", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapStairs() && option.equalsIgnoreCase("Climb Stairs")) {
|
||||
swap(client, "Climb Up Stairs", option, target);
|
||||
}
|
||||
if (config.getSwapStairs() && option.equalsIgnoreCase("Climb Stairs"))
|
||||
{
|
||||
swap(client, "Climb Up Stairs", option, target);
|
||||
}
|
||||
|
||||
if (option.equalsIgnoreCase("Clear-All") && target.equalsIgnoreCase("Bank Filler")) {
|
||||
swap(client, "Clear", option, target);
|
||||
}
|
||||
if (option.equalsIgnoreCase("Clear-All") && target.equalsIgnoreCase("Bank Filler"))
|
||||
{
|
||||
swap(client, "Clear", option, target);
|
||||
}
|
||||
|
||||
if (target.toLowerCase().contains("ardougne cloak") && config.getSwapArdougneCape()) {
|
||||
swap(client, "Kandarin Monastery", option, target);
|
||||
swap(client, "Monastery Teleport", option, target);
|
||||
}
|
||||
if (target.toLowerCase().contains("ardougne cloak") && config.getSwapArdougneCape())
|
||||
{
|
||||
swap(client, "Kandarin Monastery", option, target);
|
||||
swap(client, "Monastery Teleport", option, target);
|
||||
}
|
||||
|
||||
if (config.getSwapEssencePouch()) {
|
||||
if (isEssencePouch(target)) {
|
||||
Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
|
||||
switch (config.getEssenceMode()) {
|
||||
case RUNECRAFTING:
|
||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) {
|
||||
swap(client, "Empty", option, target);
|
||||
} else {
|
||||
swap(client, "Fill", option, target);
|
||||
}
|
||||
break;
|
||||
case ESSENCE_MINING:
|
||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden()) {
|
||||
swap(client, "Fill", option, target);
|
||||
} else {
|
||||
swap(client, "Empty", option, target);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.getSwapEssencePouch())
|
||||
{
|
||||
if (isEssencePouch(target))
|
||||
{
|
||||
Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
|
||||
switch (config.getEssenceMode())
|
||||
{
|
||||
case RUNECRAFTING:
|
||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden())
|
||||
{
|
||||
swap(client, "Empty", option, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
swap(client, "Fill", option, target);
|
||||
}
|
||||
break;
|
||||
case ESSENCE_MINING:
|
||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden())
|
||||
{
|
||||
swap(client, "Fill", option, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
swap(client, "Empty", option, target);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getGamesNecklace()) {
|
||||
if (target.toLowerCase().contains("games necklace")) {
|
||||
switch (config.getGamesNecklaceMode()) {
|
||||
case BURTHORPE:
|
||||
swap(client, GamesNecklaceMode.BURTHORPE.toString(), option, target);
|
||||
break;
|
||||
case BARBARIAN_OUTPOST:
|
||||
swap(client, GamesNecklaceMode.BARBARIAN_OUTPOST.toString(), option, target);
|
||||
break;
|
||||
case CORPOREAL_BEAST:
|
||||
swap(client, GamesNecklaceMode.CORPOREAL_BEAST.toString(), option, target);
|
||||
break;
|
||||
case TEARS_OF_GUTHIX:
|
||||
swap(client, GamesNecklaceMode.TEARS_OF_GUTHIX.toString(), option, target);
|
||||
break;
|
||||
case WINTERTODT:
|
||||
swap(client, GamesNecklaceMode.WINTERTODT.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.getGamesNecklace())
|
||||
{
|
||||
if (target.toLowerCase().contains("games necklace"))
|
||||
{
|
||||
switch (config.getGamesNecklaceMode())
|
||||
{
|
||||
case BURTHORPE:
|
||||
swap(client, GamesNecklaceMode.BURTHORPE.toString(), option, target);
|
||||
break;
|
||||
case BARBARIAN_OUTPOST:
|
||||
swap(client, GamesNecklaceMode.BARBARIAN_OUTPOST.toString(), option, target);
|
||||
break;
|
||||
case CORPOREAL_BEAST:
|
||||
swap(client, GamesNecklaceMode.CORPOREAL_BEAST.toString(), option, target);
|
||||
break;
|
||||
case TEARS_OF_GUTHIX:
|
||||
swap(client, GamesNecklaceMode.TEARS_OF_GUTHIX.toString(), option, target);
|
||||
break;
|
||||
case WINTERTODT:
|
||||
swap(client, GamesNecklaceMode.WINTERTODT.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getDuelingRing()) {
|
||||
if (target.toLowerCase().contains("ring of dueling")) {
|
||||
switch (config.getDuelingRingMode()) {
|
||||
case DUEL_ARENA:
|
||||
swap(client, DuelingRingMode.DUEL_ARENA.toString(), option, target);
|
||||
break;
|
||||
case CASTLE_WARS:
|
||||
swap(client, DuelingRingMode.CASTLE_WARS.toString(), option, target);
|
||||
break;
|
||||
case CLAN_WARS:
|
||||
swap(client, DuelingRingMode.CLAN_WARS.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.getDuelingRing())
|
||||
{
|
||||
if (target.toLowerCase().contains("ring of dueling"))
|
||||
{
|
||||
switch (config.getDuelingRingMode())
|
||||
{
|
||||
case DUEL_ARENA:
|
||||
swap(client, DuelingRingMode.DUEL_ARENA.toString(), option, target);
|
||||
break;
|
||||
case CASTLE_WARS:
|
||||
swap(client, DuelingRingMode.CASTLE_WARS.toString(), option, target);
|
||||
break;
|
||||
case CLAN_WARS:
|
||||
swap(client, DuelingRingMode.CLAN_WARS.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getWealthRing()) {
|
||||
if (target.toLowerCase().contains("ring of wealth")) {
|
||||
switch (config.getWealthRingMode()) {
|
||||
case MISCELLANIA:
|
||||
swap(client, WealthRingMode.MISCELLANIA.toString(), option, target);
|
||||
break;
|
||||
case GRAND_EXCHANGE:
|
||||
swap(client, WealthRingMode.GRAND_EXCHANGE.toString(), option, target);
|
||||
break;
|
||||
case FALADOR:
|
||||
swap(client, WealthRingMode.FALADOR.toString(), option, target);
|
||||
break;
|
||||
if (config.getWealthRing())
|
||||
{
|
||||
if (target.toLowerCase().contains("ring of wealth"))
|
||||
{
|
||||
switch (config.getWealthRingMode())
|
||||
{
|
||||
case MISCELLANIA:
|
||||
swap(client, WealthRingMode.MISCELLANIA.toString(), option, target);
|
||||
break;
|
||||
case GRAND_EXCHANGE:
|
||||
swap(client, WealthRingMode.GRAND_EXCHANGE.toString(), option, target);
|
||||
break;
|
||||
case FALADOR:
|
||||
swap(client, WealthRingMode.FALADOR.toString(), option, target);
|
||||
break;
|
||||
case DONDAKAN:
|
||||
swap(client, WealthRingMode.DONDAKAN.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
swap(client, WealthRingMode.DONDAKAN.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getGlory()) {
|
||||
if (target.toLowerCase().contains("amulet of glory") || target.toLowerCase().contains("amulet of eternal glory")) {
|
||||
switch (config.getGloryMode()) {
|
||||
case EDGEVILLE:
|
||||
swap(client, GloryMode.EDGEVILLE.toString(), option, target);
|
||||
break;
|
||||
case KARAMJA:
|
||||
swap(client, GloryMode.KARAMJA.toString(), option, target);
|
||||
break;
|
||||
case DRAYNOR_VILLAGE:
|
||||
swap(client, GloryMode.DRAYNOR_VILLAGE.toString(), option, target);
|
||||
break;
|
||||
case AL_KHARID:
|
||||
swap(client, GloryMode.AL_KHARID.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.getGlory())
|
||||
{
|
||||
if (target.toLowerCase().contains("amulet of glory") || target.toLowerCase().contains("amulet of eternal glory"))
|
||||
{
|
||||
switch (config.getGloryMode())
|
||||
{
|
||||
case EDGEVILLE:
|
||||
swap(client, GloryMode.EDGEVILLE.toString(), option, target);
|
||||
break;
|
||||
case KARAMJA:
|
||||
swap(client, GloryMode.KARAMJA.toString(), option, target);
|
||||
break;
|
||||
case DRAYNOR_VILLAGE:
|
||||
swap(client, GloryMode.DRAYNOR_VILLAGE.toString(), option, target);
|
||||
break;
|
||||
case AL_KHARID:
|
||||
swap(client, GloryMode.AL_KHARID.toString(), option, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target.toLowerCase().contains("crafting cape") && config.getSwapCraftingCape()) {
|
||||
swap(client, "Teleport", option, target);
|
||||
if (target.toLowerCase().contains("crafting cape") && config.getSwapCraftingCape())
|
||||
{
|
||||
swap(client, "Teleport", option, target);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (target.toLowerCase().contains("construct. cape") && config.getSwapConstructionCape()) {
|
||||
swap(client, "Tele to poh", option, target);
|
||||
if (target.toLowerCase().contains("construct. cape") && config.getSwapConstructionCape())
|
||||
{
|
||||
swap(client, "Tele to poh", option, target);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void delete(int target) {
|
||||
for (int i = entries.length - 1; i >= 0; i--) {
|
||||
if (entries[i].getIdentifier() == target) {
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
private void delete(int target)
|
||||
{
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
{
|
||||
if (entries[i].getIdentifier() == target)
|
||||
{
|
||||
entries = ArrayUtils.remove(entries, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
private boolean isEssencePouch(String target) {
|
||||
return (target.equalsIgnoreCase("Small Pouch") || target.equalsIgnoreCase("Medium Pouch") || target.equalsIgnoreCase("Large Pouch") || target.equalsIgnoreCase("Giant Pouch"));
|
||||
}
|
||||
private boolean isEssencePouch(String target)
|
||||
{
|
||||
return (target.equalsIgnoreCase("Small Pouch") || target.equalsIgnoreCase("Medium Pouch") || target.equalsIgnoreCase("Large Pouch") || target.equalsIgnoreCase("Giant Pouch"));
|
||||
}
|
||||
|
||||
private boolean isHouse() {
|
||||
return client.getMapRegions()[0] == HOUSE_REGION_ID;
|
||||
}
|
||||
private boolean isHouse()
|
||||
{
|
||||
return client.getMapRegions()[0] == HOUSE_REGION_ID;
|
||||
}
|
||||
|
||||
private boolean isPuroPuro() {
|
||||
Player player = client.getLocalPlayer();
|
||||
private boolean isPuroPuro()
|
||||
{
|
||||
Player player = client.getLocalPlayer();
|
||||
|
||||
if (player == null) {
|
||||
return false;
|
||||
} else {
|
||||
WorldPoint location = player.getWorldLocation();
|
||||
return location.getRegionID() == PURO_PURO_REGION_ID;
|
||||
}
|
||||
}
|
||||
if (player == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPoint location = player.getWorldLocation();
|
||||
return location.getRegionID() == PURO_PURO_REGION_ID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,285 +29,313 @@ import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("easyscape")
|
||||
public interface EasyscapePluginConfig extends Config {
|
||||
public interface EasyscapePluginConfig extends Config
|
||||
{
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeExamine",
|
||||
name = "Remove Examine",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
default boolean getRemoveExamine() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "removeExamine",
|
||||
name = "Remove Examine",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
default boolean getRemoveExamine()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapShop",
|
||||
name = "Easy Shop",
|
||||
description = "Enables swapping of items in the shop with their buy-50 option.",
|
||||
position = 1
|
||||
)
|
||||
default boolean getSwapShop() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapShop",
|
||||
name = "Easy Shop",
|
||||
description = "Enables swapping of items in the shop with their buy-50 option.",
|
||||
position = 1
|
||||
)
|
||||
default boolean getSwapShop()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swappedItems",
|
||||
name = "Shop Items",
|
||||
description = "Items listed here will have their value and buy-50 options swapped.",
|
||||
position = 2
|
||||
)
|
||||
default String getSwappedItems() {
|
||||
return "";
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swappedItems",
|
||||
name = "Shop Items",
|
||||
description = "Items listed here will have their value and buy-50 options swapped.",
|
||||
position = 2
|
||||
)
|
||||
default String getSwappedItems()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "easyConstruction",
|
||||
name = "Easy Construction",
|
||||
description = "",
|
||||
position = 3
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "easyConstruction",
|
||||
name = "Easy Construction",
|
||||
description = "",
|
||||
position = 3
|
||||
)
|
||||
|
||||
default boolean getEasyConstruction() {
|
||||
return true;
|
||||
}
|
||||
default boolean getEasyConstruction()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "constructionItems",
|
||||
name = "Construction Items",
|
||||
description = "",
|
||||
position = 4
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "constructionItems",
|
||||
name = "Construction Items",
|
||||
description = "",
|
||||
position = 4
|
||||
)
|
||||
|
||||
default String getConstructionItems() {
|
||||
return "";
|
||||
}
|
||||
default String getConstructionItems()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeObjects",
|
||||
name = "Remove Objects",
|
||||
description = "",
|
||||
position = 5
|
||||
)
|
||||
default boolean getRemoveObjects() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "removeObjects",
|
||||
name = "Remove Objects",
|
||||
description = "",
|
||||
position = 5
|
||||
)
|
||||
default boolean getRemoveObjects()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removedObjects",
|
||||
name = "Removed Objects",
|
||||
description = "",
|
||||
position = 6
|
||||
)
|
||||
default String getRemovedObjects() {
|
||||
return "";
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "removedObjects",
|
||||
name = "Removed Objects",
|
||||
description = "",
|
||||
position = 6
|
||||
)
|
||||
default String getRemovedObjects()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSmithing",
|
||||
name = "Swap Smithing",
|
||||
description = "Enables swapping of smith-1 and smith-all options.",
|
||||
position = 7
|
||||
)
|
||||
default boolean getSwapSmithing() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapSmithing",
|
||||
name = "Swap Smithing",
|
||||
description = "Enables swapping of smith-1 and smith-all options.",
|
||||
position = 7
|
||||
)
|
||||
default boolean getSwapSmithing()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapTanning",
|
||||
name = "Swap Tanning",
|
||||
description = "Enables swapping of tan-1 and tan-all options.",
|
||||
position = 8
|
||||
)
|
||||
default boolean getSwapTanning() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapTanning",
|
||||
name = "Swap Tanning",
|
||||
description = "Enables swapping of tan-1 and tan-all options.",
|
||||
position = 8
|
||||
)
|
||||
default boolean getSwapTanning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapCrafting",
|
||||
name = "Swap Crafting",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
default boolean getSwapCrafting() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapCrafting",
|
||||
name = "Swap Crafting",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
default boolean getSwapCrafting()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapArdougneCape",
|
||||
name = "Swap Ardougne Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 10
|
||||
)
|
||||
default boolean getSwapArdougneCape() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapArdougneCape",
|
||||
name = "Swap Ardougne Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 10
|
||||
)
|
||||
default boolean getSwapArdougneCape()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapStairs",
|
||||
name = "Swap Stairs",
|
||||
description = "",
|
||||
position = 11
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "swapStairs",
|
||||
name = "Swap Stairs",
|
||||
description = "",
|
||||
position = 11
|
||||
)
|
||||
|
||||
default boolean getSwapStairs() {
|
||||
return true;
|
||||
}
|
||||
default boolean getSwapStairs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSawmill",
|
||||
name = "Swap Sawmill Operator",
|
||||
description = "",
|
||||
position = 12
|
||||
)
|
||||
default boolean getSwapSawmill() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapSawmill",
|
||||
name = "Swap Sawmill Operator",
|
||||
description = "",
|
||||
position = 12
|
||||
)
|
||||
default boolean getSwapSawmill()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapSawmillPlanks",
|
||||
name = "Swap Buy Planks",
|
||||
description = "",
|
||||
position = 13
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "swapSawmillPlanks",
|
||||
name = "Swap Buy Planks",
|
||||
description = "",
|
||||
position = 13
|
||||
)
|
||||
|
||||
default boolean getSwapSawmillPlanks() {
|
||||
return true;
|
||||
}
|
||||
default boolean getSwapSawmillPlanks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapPuroPuro",
|
||||
name = "Swap Puro Puro Wheat",
|
||||
description = "",
|
||||
position = 14
|
||||
)
|
||||
default boolean getSwapPuro() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapPuroPuro",
|
||||
name = "Swap Puro Puro Wheat",
|
||||
description = "",
|
||||
position = 14
|
||||
)
|
||||
default boolean getSwapPuro()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapEssencePounch",
|
||||
name = "Swap Essence Pouch",
|
||||
description = "Enables swapping of fill and empty for essence pounch.",
|
||||
position = 15
|
||||
)
|
||||
default boolean getSwapEssencePouch() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapEssencePounch",
|
||||
name = "Swap Essence Pouch",
|
||||
description = "Enables swapping of fill and empty for essence pounch.",
|
||||
position = 15
|
||||
)
|
||||
default boolean getSwapEssencePouch()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "essenceMode",
|
||||
name = "Essence Pouch Mode",
|
||||
description = "Runecrafting or essence mining mode.",
|
||||
position = 16
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "essenceMode",
|
||||
name = "Essence Pouch Mode",
|
||||
description = "Runecrafting or essence mining mode.",
|
||||
position = 16
|
||||
)
|
||||
|
||||
default EssenceMode getEssenceMode() {
|
||||
return EssenceMode.RUNECRAFTING;
|
||||
}
|
||||
default EssenceMode getEssenceMode()
|
||||
{
|
||||
return EssenceMode.RUNECRAFTING;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapGamesNecklace",
|
||||
name = "Swap Games Necklace",
|
||||
description = "Enables swapping of games necklace.",
|
||||
position = 17
|
||||
)
|
||||
default boolean getGamesNecklace() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapGamesNecklace",
|
||||
name = "Swap Games Necklace",
|
||||
description = "Enables swapping of games necklace.",
|
||||
position = 17
|
||||
)
|
||||
default boolean getGamesNecklace()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gamesNecklaceMode",
|
||||
name = "Games Necklace Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 18
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "gamesNecklaceMode",
|
||||
name = "Games Necklace Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 18
|
||||
)
|
||||
|
||||
default GamesNecklaceMode getGamesNecklaceMode() {
|
||||
return GamesNecklaceMode.BURTHORPE;
|
||||
}
|
||||
default GamesNecklaceMode getGamesNecklaceMode()
|
||||
{
|
||||
return GamesNecklaceMode.BURTHORPE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapDuelingRing",
|
||||
name = "Swap Dueling Ring",
|
||||
description = "Enables swapping of dueling ring.",
|
||||
position = 19
|
||||
)
|
||||
default boolean getDuelingRing() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapDuelingRing",
|
||||
name = "Swap Dueling Ring",
|
||||
description = "Enables swapping of dueling ring.",
|
||||
position = 19
|
||||
)
|
||||
default boolean getDuelingRing()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "duelingRingMode",
|
||||
name = "Dueling Ring Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 20
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "duelingRingMode",
|
||||
name = "Dueling Ring Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 20
|
||||
)
|
||||
|
||||
default DuelingRingMode getDuelingRingMode() {
|
||||
return DuelingRingMode.DUEL_ARENA;
|
||||
}
|
||||
default DuelingRingMode getDuelingRingMode()
|
||||
{
|
||||
return DuelingRingMode.DUEL_ARENA;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapGlory",
|
||||
name = "Swap Glory",
|
||||
description = "Enables swapping of Amulet of Glory.",
|
||||
position = 21
|
||||
)
|
||||
default boolean getGlory() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapGlory",
|
||||
name = "Swap Glory",
|
||||
description = "Enables swapping of Amulet of Glory.",
|
||||
position = 21
|
||||
)
|
||||
default boolean getGlory()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gloryMode",
|
||||
name = "Glory Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 22
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "gloryMode",
|
||||
name = "Glory Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 22
|
||||
)
|
||||
|
||||
default GloryMode getGloryMode() {
|
||||
return GloryMode.EDGEVILLE;
|
||||
}
|
||||
default GloryMode getGloryMode()
|
||||
{
|
||||
return GloryMode.EDGEVILLE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapWealthRing",
|
||||
name = "Swap Ring of Wealth",
|
||||
description = "Enables swapping of Ring of Wealth.",
|
||||
position = 23
|
||||
)
|
||||
default boolean getWealthRing() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapWealthRing",
|
||||
name = "Swap Ring of Wealth",
|
||||
description = "Enables swapping of Ring of Wealth.",
|
||||
position = 23
|
||||
)
|
||||
default boolean getWealthRing()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "WealthRingMode",
|
||||
name = "Wealth Ring Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 24
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "WealthRingMode",
|
||||
name = "Wealth Ring Mode",
|
||||
description = "Teleport location mode.",
|
||||
position = 24
|
||||
)
|
||||
|
||||
default WealthRingMode getWealthRingMode() {
|
||||
return WealthRingMode.GRAND_EXCHANGE;
|
||||
}
|
||||
default WealthRingMode getWealthRingMode()
|
||||
{
|
||||
return WealthRingMode.GRAND_EXCHANGE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapConstructionCape",
|
||||
name = "Swap Construction Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 25
|
||||
)
|
||||
default boolean getSwapConstructionCape() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapConstructionCape",
|
||||
name = "Swap Construction Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 25
|
||||
)
|
||||
default boolean getSwapConstructionCape()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapCraftingCape",
|
||||
name = "Swap Crafting Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 26
|
||||
)
|
||||
default boolean getSwapCraftingCape() {
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "swapCraftingCape",
|
||||
name = "Swap Crafting Cape",
|
||||
description = "Enables swapping of teleport and wear.",
|
||||
position = 26
|
||||
)
|
||||
default boolean getSwapCraftingCape()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum EssenceMode {
|
||||
RUNECRAFTING("Runecrafting"),
|
||||
ESSENCE_MINING("Essence Mining");
|
||||
|
||||
private final String name;
|
||||
|
||||
EssenceMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum EssenceMode
|
||||
{
|
||||
RUNECRAFTING("Runecrafting"),
|
||||
ESSENCE_MINING("Essence Mining");
|
||||
|
||||
private final String name;
|
||||
|
||||
EssenceMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum GamesNecklaceMode {
|
||||
BURTHORPE("Burthorpe"),
|
||||
BARBARIAN_OUTPOST("Barbarian Outpost"),
|
||||
CORPOREAL_BEAST("Corporeal Beast"),
|
||||
TEARS_OF_GUTHIX("Tears of Guthix"),
|
||||
WINTERTODT("Wintertodt Camp");
|
||||
|
||||
private final String name;
|
||||
|
||||
GamesNecklaceMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum GamesNecklaceMode
|
||||
{
|
||||
BURTHORPE("Burthorpe"),
|
||||
BARBARIAN_OUTPOST("Barbarian Outpost"),
|
||||
CORPOREAL_BEAST("Corporeal Beast"),
|
||||
TEARS_OF_GUTHIX("Tears of Guthix"),
|
||||
WINTERTODT("Wintertodt Camp");
|
||||
|
||||
private final String name;
|
||||
|
||||
GamesNecklaceMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum GloryMode {
|
||||
EDGEVILLE("Edgeville"),
|
||||
KARAMJA("Karamja"),
|
||||
DRAYNOR_VILLAGE("Draynor Village"),
|
||||
AL_KHARID("Al Kharid");
|
||||
|
||||
private final String name;
|
||||
|
||||
GloryMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum GloryMode
|
||||
{
|
||||
EDGEVILLE("Edgeville"),
|
||||
KARAMJA("Karamja"),
|
||||
DRAYNOR_VILLAGE("Draynor Village"),
|
||||
AL_KHARID("Al Kharid");
|
||||
|
||||
private final String name;
|
||||
|
||||
GloryMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum WealthRingMode {
|
||||
MISCELLANIA ("Miscellania"),
|
||||
GRAND_EXCHANGE ("Grand Exchange"),
|
||||
FALADOR ("Falador"),
|
||||
DONDAKAN ("Dondakan");
|
||||
|
||||
private final String name;
|
||||
|
||||
WealthRingMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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.easyscape;
|
||||
|
||||
public enum WealthRingMode
|
||||
{
|
||||
MISCELLANIA("Miscellania"),
|
||||
GRAND_EXCHANGE("Grand Exchange"),
|
||||
FALADOR("Falador"),
|
||||
DONDAKAN("Dondakan");
|
||||
|
||||
private final String name;
|
||||
|
||||
WealthRingMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class ItemPanel extends JPanel
|
||||
ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon)
|
||||
{
|
||||
|
||||
setBorder(new EmptyBorder(3, 3, 3, 3));
|
||||
setBorder(new EmptyBorder(3, 3, 3, 3));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
GroupLayout layout = new GroupLayout(this);
|
||||
@@ -55,20 +55,20 @@ class ItemPanel extends JPanel
|
||||
icon.addTo(imageLabel);
|
||||
|
||||
layout.setVerticalGroup(layout.createParallelGroup()
|
||||
.addComponent(imageLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
.addComponent(imageLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
);
|
||||
|
||||
layout.setHorizontalGroup(layout.createSequentialGroup()
|
||||
.addComponent(imageLabel)
|
||||
.addGap(8)
|
||||
.addGroup(layout.createParallelGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
.addComponent(imageLabel)
|
||||
.addGap(8)
|
||||
.addGroup(layout.createParallelGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
);
|
||||
|
||||
// AWT's Z order is weird. This put image at the back of the stack
|
||||
|
||||
@@ -1,75 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.examine;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
class CacheKey
|
||||
{
|
||||
private final ExamineType type;
|
||||
private final int id;
|
||||
|
||||
public CacheKey(ExamineType type, int id)
|
||||
{
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 3;
|
||||
hash = 23 * hash + Objects.hashCode(this.type);
|
||||
hash = 23 * hash + this.id;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final CacheKey other = (CacheKey) obj;
|
||||
if (this.id != other.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.type != other.type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.examine;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
class CacheKey
|
||||
{
|
||||
private final ExamineType type;
|
||||
private final int id;
|
||||
|
||||
public CacheKey(ExamineType type, int id)
|
||||
{
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 3;
|
||||
hash = 23 * hash + Objects.hashCode(this.type);
|
||||
hash = 23 * hash + this.id;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final CacheKey other = (CacheKey) obj;
|
||||
if (this.id != other.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.type == other.type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.examine;
|
||||
|
||||
public enum ExamineType
|
||||
{
|
||||
ITEM,
|
||||
ITEM_BANK_EQ,
|
||||
NPC,
|
||||
OBJECT;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.examine;
|
||||
|
||||
public enum ExamineType
|
||||
{
|
||||
ITEM,
|
||||
ITEM_BANK_EQ,
|
||||
NPC,
|
||||
OBJECT
|
||||
}
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.experiencedrop;
|
||||
|
||||
enum PrayerType
|
||||
{
|
||||
MELEE,
|
||||
RANGE,
|
||||
MAGIC;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.experiencedrop;
|
||||
|
||||
enum PrayerType
|
||||
{
|
||||
MELEE,
|
||||
RANGE,
|
||||
MAGIC
|
||||
}
|
||||
|
||||
@@ -1,112 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* 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.experiencedrop;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("xpdrop")
|
||||
public interface XpDropConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "hideSkillIcons",
|
||||
name = "Hide skill icons",
|
||||
description = "Configure if XP drops will show their respective skill icons",
|
||||
position = 0
|
||||
)
|
||||
default boolean hideSkillIcons()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "meleePrayerColor",
|
||||
name = "Melee Prayer Color",
|
||||
description = "XP drop color when a melee prayer is active",
|
||||
position = 1
|
||||
)
|
||||
default Color getMeleePrayerColor()
|
||||
{
|
||||
return new Color(0x15, 0x80, 0xAD);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rangePrayerColor",
|
||||
name = "Range Prayer Color",
|
||||
description = "XP drop color when a range prayer is active",
|
||||
position = 2
|
||||
)
|
||||
default Color getRangePrayerColor()
|
||||
{
|
||||
return new Color(0x15, 0x80, 0xAD);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "magePrayerColor",
|
||||
name = "Mage Prayer Color",
|
||||
description = "XP drop color when a mage prayer is active",
|
||||
position = 3
|
||||
)
|
||||
default Color getMagePrayerColor()
|
||||
{
|
||||
return new Color(0x15, 0x80, 0xAD);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fakeXpDropDelay",
|
||||
name = "Fake Xp Drop delay",
|
||||
description = "Configures how many ticks should pass between fake XP drops, 0 to disable",
|
||||
position = 4
|
||||
)
|
||||
default int fakeXpDropDelay()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showDamage",
|
||||
name = "Show Damage on XP Drop",
|
||||
description = "Show what you hit next to the XP drop",
|
||||
position = 5
|
||||
)
|
||||
default boolean showDamage()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "damageColor",
|
||||
name = "Damage Color",
|
||||
description = "The color you want the text to be for damage",
|
||||
position = 6
|
||||
)
|
||||
default Color getDamageColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* 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.experiencedrop;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("xpdrop")
|
||||
public interface XpDropConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "hideSkillIcons",
|
||||
name = "Hide skill icons",
|
||||
description = "Configure if XP drops will show their respective skill icons",
|
||||
position = 0
|
||||
)
|
||||
default boolean hideSkillIcons()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "meleePrayerColor",
|
||||
name = "Melee Prayer Color",
|
||||
description = "XP drop color when a melee prayer is active",
|
||||
position = 1
|
||||
)
|
||||
default Color getMeleePrayerColor()
|
||||
{
|
||||
return new Color(0x15, 0x80, 0xAD);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rangePrayerColor",
|
||||
name = "Range Prayer Color",
|
||||
description = "XP drop color when a range prayer is active",
|
||||
position = 2
|
||||
)
|
||||
default Color getRangePrayerColor()
|
||||
{
|
||||
return new Color(0x15, 0x80, 0xAD);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "magePrayerColor",
|
||||
name = "Mage Prayer Color",
|
||||
description = "XP drop color when a mage prayer is active",
|
||||
position = 3
|
||||
)
|
||||
default Color getMagePrayerColor()
|
||||
{
|
||||
return new Color(0x15, 0x80, 0xAD);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fakeXpDropDelay",
|
||||
name = "Fake Xp Drop delay",
|
||||
description = "Configures how many ticks should pass between fake XP drops, 0 to disable",
|
||||
position = 4
|
||||
)
|
||||
default int fakeXpDropDelay()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showDamage",
|
||||
name = "Show Damage on XP Drop",
|
||||
description = "Show what you hit next to the XP drop",
|
||||
position = 5
|
||||
)
|
||||
default boolean showDamage()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "damageColor",
|
||||
name = "Damage Color",
|
||||
description = "The color you want the text to be for damage",
|
||||
position = 6
|
||||
)
|
||||
default Color getDamageColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,73 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.experiencedrop;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class XpDropOverlay extends Overlay
|
||||
{
|
||||
private final XpDropPlugin plugin;
|
||||
private final XpDropConfig config;
|
||||
|
||||
@Inject
|
||||
private XpDropOverlay(XpDropPlugin plugin, XpDropConfig config)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.showDamage())
|
||||
{
|
||||
final Actor opponent = plugin.getLastOpponent();
|
||||
if (opponent != null)
|
||||
{
|
||||
int offset = opponent.getLogicalHeight() + 50;
|
||||
String damageStr = String.valueOf(this.plugin.getDamage());
|
||||
Point textLocation = opponent.getCanvasTextLocation(graphics, damageStr, offset);
|
||||
|
||||
if (textLocation != null && this.plugin.getDamage() != 0)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, damageStr, config.getDamageColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.experiencedrop;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class XpDropOverlay extends Overlay
|
||||
{
|
||||
private final XpDropPlugin plugin;
|
||||
private final XpDropConfig config;
|
||||
|
||||
@Inject
|
||||
private XpDropOverlay(XpDropPlugin plugin, XpDropConfig config)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.showDamage())
|
||||
{
|
||||
final Actor opponent = plugin.getLastOpponent();
|
||||
if (opponent != null)
|
||||
{
|
||||
int offset = opponent.getLogicalHeight() + 50;
|
||||
String damageStr = String.valueOf(this.plugin.getDamage());
|
||||
Point textLocation = opponent.getCanvasTextLocation(graphics, damageStr, offset);
|
||||
|
||||
if (textLocation != null && this.plugin.getDamage() != 0)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, damageStr, config.getDamageColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,453 +1,469 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>, SoyChai <https://github.com/SoyChai>
|
||||
* 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.experiencedrop;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.*;
|
||||
|
||||
import static net.runelite.api.ScriptID.XPDROP_DISABLED;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.*;
|
||||
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.HiscoreManager;
|
||||
import net.runelite.client.game.NPCManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.attackstyles.AttackStyle;
|
||||
import net.runelite.client.plugins.attackstyles.WeaponType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
||||
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "XP Drop",
|
||||
description = "Enable customization of the way XP drops are displayed",
|
||||
tags = {"experience", "levels", "tick"}
|
||||
)
|
||||
public class XpDropPlugin extends Plugin
|
||||
{
|
||||
private static final int XPDROP_PADDING = 2; // space between xp drop icons
|
||||
private static final Duration WAIT = Duration.ofSeconds(5);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private XpDropConfig config;
|
||||
|
||||
private int tickCounter = 0;
|
||||
private int previousExpGained;
|
||||
private boolean hasHit = false;
|
||||
private boolean hasDropped = false;
|
||||
private boolean correctPrayer;
|
||||
private Skill lastSkill = null;
|
||||
private Map<Skill, Integer> previousSkillExpTable = new EnumMap<>(Skill.class);
|
||||
private PrayerType currentTickPrayer;
|
||||
private AttackStyle attackStyle;
|
||||
private int attackStyleVarbit = -1;
|
||||
private int equippedWeaponTypeVarbit = -1;
|
||||
private int castingModeVarbit = -1;
|
||||
private int opponentHealth = -1;
|
||||
private int xpGains = 0;
|
||||
private AttackStyle[] offensiveStyles = {ACCURATE, AGGRESSIVE, DEFENSIVE, CONTROLLED, RANGING, LONGRANGE, CASTING, DEFENSIVE_CASTING};
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int damage = 0;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Actor lastOpponent;
|
||||
|
||||
private Instant lastTime;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private XpDropOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private NPCManager npcManager;
|
||||
|
||||
@Inject
|
||||
private HiscoreManager hiscoreManager;
|
||||
|
||||
@Provides
|
||||
XpDropConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(XpDropConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
lastOpponent = null;
|
||||
overlayManager.add(overlay);
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(
|
||||
equippedWeaponTypeVarbit,
|
||||
attackStyleVarbit,
|
||||
castingModeVarbit);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetHiddenChanged(WidgetHiddenChanged event)
|
||||
{
|
||||
Widget widget = event.getWidget();
|
||||
|
||||
int group = WidgetInfo.TO_GROUP(widget.getId());
|
||||
|
||||
if (group != WidgetID.EXPERIENCE_DROP_GROUP_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.hideSkillIcons())
|
||||
{
|
||||
if (widget.getSpriteId() > 0)
|
||||
{
|
||||
widget.setHidden(true);
|
||||
return;
|
||||
}
|
||||
else if (!widget.getText().isEmpty())
|
||||
{
|
||||
// Align text accordingly to take up hidden skill icon space
|
||||
int width = 0;
|
||||
for (Widget w : widget.getParent().getDynamicChildren())
|
||||
{
|
||||
if (w.getSpriteId() != -1)
|
||||
{
|
||||
if (width > 0)
|
||||
{
|
||||
// Add in space between sprites
|
||||
width += XPDROP_PADDING;
|
||||
}
|
||||
width += w.getWidth(); // width of sprite
|
||||
}
|
||||
}
|
||||
|
||||
final int xpDropPosition = client.getVar(Varbits.EXPERIENCE_TRACKER_POSITION);
|
||||
switch (xpDropPosition)
|
||||
{
|
||||
case 2: // left
|
||||
int cur = widget.getRelativeX();
|
||||
cur -= width;
|
||||
widget.setRelativeX(cur);
|
||||
break;
|
||||
case 0: // right
|
||||
break;
|
||||
case 1: // center
|
||||
cur = widget.getRelativeX();
|
||||
cur -= width / 2;
|
||||
widget.setRelativeX(cur);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrayerType prayer = currentTickPrayer;
|
||||
if (prayer == null)
|
||||
{
|
||||
resetTextColor(widget);
|
||||
return;
|
||||
}
|
||||
|
||||
String text = widget.getText();
|
||||
final IntStream spriteIDs =
|
||||
Arrays.stream(widget.getParent().getDynamicChildren()).mapToInt(Widget::getSpriteId);
|
||||
|
||||
if (text != null)
|
||||
{
|
||||
int color = widget.getTextColor();
|
||||
|
||||
switch (prayer)
|
||||
{
|
||||
case MELEE:
|
||||
if (spriteIDs.anyMatch(id ->
|
||||
id == SpriteID.SKILL_ATTACK || id == SpriteID.SKILL_STRENGTH || id == SpriteID.SKILL_DEFENCE
|
||||
|| correctPrayer))
|
||||
{
|
||||
color = config.getMeleePrayerColor().getRGB();
|
||||
correctPrayer = true;
|
||||
}
|
||||
break;
|
||||
case RANGE:
|
||||
if (spriteIDs.anyMatch(id -> id == SpriteID.SKILL_RANGED || correctPrayer))
|
||||
{
|
||||
color = config.getRangePrayerColor().getRGB();
|
||||
correctPrayer = true;
|
||||
}
|
||||
break;
|
||||
case MAGIC:
|
||||
if (spriteIDs.anyMatch(id -> id == SpriteID.SKILL_MAGIC || correctPrayer))
|
||||
{
|
||||
color = config.getMagePrayerColor().getRGB();
|
||||
correctPrayer = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
widget.setTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetTextColor(Widget widget)
|
||||
{
|
||||
int defaultColorIdx = client.getVar(Varbits.EXPERIENCE_DROP_COLOR);
|
||||
int defaultColor = DefaultColors.values()[defaultColorIdx].getColor().getRGB();
|
||||
widget.setTextColor(defaultColor);
|
||||
}
|
||||
|
||||
private PrayerType getActivePrayerType()
|
||||
{
|
||||
for (XpPrayer prayer : XpPrayer.values())
|
||||
{
|
||||
if (client.isPrayerActive(prayer.getPrayer()))
|
||||
{
|
||||
return prayer.getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
// Detect hitting a 0
|
||||
if (lastOpponent != null)
|
||||
{
|
||||
int health = calculateHealth(lastOpponent);
|
||||
if (health != -1 && opponentHealth != -1 && health == opponentHealth && hasHit)
|
||||
{
|
||||
damage = 0;
|
||||
hasHit = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle getting XP gains
|
||||
if (hasDropped)
|
||||
{
|
||||
if (xpGains != 0 && attackStyle.getSkills().length > 1 && attackStyle != LONGRANGE)
|
||||
{
|
||||
damage = (int) (xpGains / (attackStyle.getSkills().length * 1.3));
|
||||
}
|
||||
else if (xpGains != 0)
|
||||
{
|
||||
damage = xpGains / 4;
|
||||
}
|
||||
|
||||
xpGains = 0;
|
||||
hasDropped = false;
|
||||
}
|
||||
|
||||
// Clear opponent
|
||||
if (lastOpponent != null && lastTime != null && client.getLocalPlayer().getInteracting() == null)
|
||||
{
|
||||
if (Duration.between(lastTime, Instant.now()).compareTo(WAIT) > 0)
|
||||
{
|
||||
lastOpponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
currentTickPrayer = getActivePrayerType();
|
||||
correctPrayer = false;
|
||||
|
||||
final int fakeTickDelay = config.fakeXpDropDelay();
|
||||
|
||||
if (fakeTickDelay == 0 || lastSkill == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If an xp drop was created this tick, reset the counter
|
||||
if (hasDropped)
|
||||
{
|
||||
hasDropped = false;
|
||||
tickCounter = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (++tickCounter % fakeTickDelay != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.runScript(XPDROP_DISABLED, lastSkill.ordinal(), previousExpGained);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event)
|
||||
{
|
||||
final Skill skill = event.getSkill();
|
||||
final int xp = client.getSkillExperience(skill);
|
||||
|
||||
lastSkill = skill;
|
||||
|
||||
Integer previous = previousSkillExpTable.put(skill, xp);
|
||||
if (previous != null)
|
||||
{
|
||||
opponentHealth = calculateHealth(lastOpponent);
|
||||
previousExpGained = xp - previous;
|
||||
if (skill != Skill.HITPOINTS && Arrays.stream(offensiveStyles).anyMatch(attackStyle::equals))
|
||||
{
|
||||
xpGains += previousExpGained;
|
||||
}
|
||||
|
||||
hasDropped = true;
|
||||
hasHit = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode)
|
||||
{
|
||||
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles();
|
||||
if (attackStyleIndex < attackStyles.length)
|
||||
{
|
||||
attackStyle = attackStyles[attackStyleIndex];
|
||||
if (attackStyle == null)
|
||||
{
|
||||
attackStyle = OTHER;
|
||||
}
|
||||
else if ((attackStyle == CASTING) && (castingMode == 1))
|
||||
{
|
||||
attackStyle = DEFENSIVE_CASTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractingChanged(InteractingChanged event)
|
||||
{
|
||||
if (event.getSource() != client.getLocalPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Actor opponent = event.getTarget();
|
||||
|
||||
if (opponent == null)
|
||||
{
|
||||
lastTime = Instant.now();
|
||||
return;
|
||||
}
|
||||
else if (opponent.getName().equalsIgnoreCase("fishing spot"))
|
||||
{
|
||||
lastTime = Instant.now().minus(WAIT);
|
||||
return;
|
||||
}
|
||||
|
||||
damage = 0;
|
||||
lastOpponent = opponent;
|
||||
opponentHealth = calculateHealth(opponent);
|
||||
}
|
||||
|
||||
private int calculateHealth(Actor target)
|
||||
{
|
||||
if (target == null || target.getName() == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int healthScale = target.getHealth();
|
||||
final int healthRatio = target.getHealthRatio();
|
||||
final String targetName = Text.removeTags(target.getName());
|
||||
|
||||
Integer maxHealth = -1;
|
||||
if (target instanceof NPC)
|
||||
{
|
||||
maxHealth = npcManager.getHealth(targetName, target.getCombatLevel());
|
||||
}
|
||||
else if (target instanceof Player)
|
||||
{
|
||||
final HiscoreResult hiscoreResult = hiscoreManager.lookupAsync(targetName, HiscoreEndpoint.NORMAL);
|
||||
if (hiscoreResult != null)
|
||||
{
|
||||
final int hp = hiscoreResult.getHitpoints().getLevel();
|
||||
if (hp > 0)
|
||||
{
|
||||
maxHealth = hp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)((maxHealth * healthRatio / healthScale) + 0.5f);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE))
|
||||
{
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit,
|
||||
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
|
||||
}
|
||||
|
||||
if (equippedWeaponTypeVarbit == -1 || equippedWeaponTypeVarbit != client.getVar(Varbits.EQUIPPED_WEAPON_TYPE))
|
||||
{
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
updateAttackStyle(equippedWeaponTypeVarbit, client.getVar(VarPlayer.ATTACK_STYLE),
|
||||
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
|
||||
}
|
||||
|
||||
if (castingModeVarbit == -1 || castingModeVarbit != client.getVar(Varbits.DEFENSIVE_CASTING_MODE))
|
||||
{
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), client.getVar(VarPlayer.ATTACK_STYLE),
|
||||
castingModeVarbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>, SoyChai <https://github.com/SoyChai>
|
||||
* 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.experiencedrop;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import static net.runelite.api.ScriptID.XPDROP_DISABLED;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.InteractingChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetHiddenChanged;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.HiscoreManager;
|
||||
import net.runelite.client.game.NPCManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.attackstyles.AttackStyle;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.ACCURATE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.AGGRESSIVE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.CONTROLLED;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.LONGRANGE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.RANGING;
|
||||
import net.runelite.client.plugins.attackstyles.WeaponType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
||||
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "XP Drop",
|
||||
description = "Enable customization of the way XP drops are displayed",
|
||||
tags = {"experience", "levels", "tick"}
|
||||
)
|
||||
public class XpDropPlugin extends Plugin
|
||||
{
|
||||
private static final int XPDROP_PADDING = 2; // space between xp drop icons
|
||||
private static final Duration WAIT = Duration.ofSeconds(5);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private XpDropConfig config;
|
||||
|
||||
private int tickCounter = 0;
|
||||
private int previousExpGained;
|
||||
private boolean hasHit = false;
|
||||
private boolean hasDropped = false;
|
||||
private boolean correctPrayer;
|
||||
private Skill lastSkill = null;
|
||||
private Map<Skill, Integer> previousSkillExpTable = new EnumMap<>(Skill.class);
|
||||
private PrayerType currentTickPrayer;
|
||||
private AttackStyle attackStyle;
|
||||
private int attackStyleVarbit = -1;
|
||||
private int equippedWeaponTypeVarbit = -1;
|
||||
private int castingModeVarbit = -1;
|
||||
private int opponentHealth = -1;
|
||||
private int xpGains = 0;
|
||||
private AttackStyle[] offensiveStyles = {ACCURATE, AGGRESSIVE, DEFENSIVE, CONTROLLED, RANGING, LONGRANGE, CASTING, DEFENSIVE_CASTING};
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int damage = 0;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Actor lastOpponent;
|
||||
|
||||
private Instant lastTime;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private XpDropOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private NPCManager npcManager;
|
||||
|
||||
@Inject
|
||||
private HiscoreManager hiscoreManager;
|
||||
|
||||
@Provides
|
||||
XpDropConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(XpDropConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
lastOpponent = null;
|
||||
overlayManager.add(overlay);
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(
|
||||
equippedWeaponTypeVarbit,
|
||||
attackStyleVarbit,
|
||||
castingModeVarbit);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetHiddenChanged(WidgetHiddenChanged event)
|
||||
{
|
||||
Widget widget = event.getWidget();
|
||||
|
||||
int group = WidgetInfo.TO_GROUP(widget.getId());
|
||||
|
||||
if (group != WidgetID.EXPERIENCE_DROP_GROUP_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.hideSkillIcons())
|
||||
{
|
||||
if (widget.getSpriteId() > 0)
|
||||
{
|
||||
widget.setHidden(true);
|
||||
return;
|
||||
}
|
||||
else if (!widget.getText().isEmpty())
|
||||
{
|
||||
// Align text accordingly to take up hidden skill icon space
|
||||
int width = 0;
|
||||
for (Widget w : widget.getParent().getDynamicChildren())
|
||||
{
|
||||
if (w.getSpriteId() != -1)
|
||||
{
|
||||
if (width > 0)
|
||||
{
|
||||
// Add in space between sprites
|
||||
width += XPDROP_PADDING;
|
||||
}
|
||||
width += w.getWidth(); // width of sprite
|
||||
}
|
||||
}
|
||||
|
||||
final int xpDropPosition = client.getVar(Varbits.EXPERIENCE_TRACKER_POSITION);
|
||||
switch (xpDropPosition)
|
||||
{
|
||||
case 2: // left
|
||||
int cur = widget.getRelativeX();
|
||||
cur -= width;
|
||||
widget.setRelativeX(cur);
|
||||
break;
|
||||
case 0: // right
|
||||
break;
|
||||
case 1: // center
|
||||
cur = widget.getRelativeX();
|
||||
cur -= width / 2;
|
||||
widget.setRelativeX(cur);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrayerType prayer = currentTickPrayer;
|
||||
if (prayer == null)
|
||||
{
|
||||
resetTextColor(widget);
|
||||
return;
|
||||
}
|
||||
|
||||
String text = widget.getText();
|
||||
final IntStream spriteIDs =
|
||||
Arrays.stream(widget.getParent().getDynamicChildren()).mapToInt(Widget::getSpriteId);
|
||||
|
||||
if (text != null)
|
||||
{
|
||||
int color = widget.getTextColor();
|
||||
|
||||
switch (prayer)
|
||||
{
|
||||
case MELEE:
|
||||
if (spriteIDs.anyMatch(id ->
|
||||
id == SpriteID.SKILL_ATTACK || id == SpriteID.SKILL_STRENGTH || id == SpriteID.SKILL_DEFENCE
|
||||
|| correctPrayer))
|
||||
{
|
||||
color = config.getMeleePrayerColor().getRGB();
|
||||
correctPrayer = true;
|
||||
}
|
||||
break;
|
||||
case RANGE:
|
||||
if (spriteIDs.anyMatch(id -> id == SpriteID.SKILL_RANGED || correctPrayer))
|
||||
{
|
||||
color = config.getRangePrayerColor().getRGB();
|
||||
correctPrayer = true;
|
||||
}
|
||||
break;
|
||||
case MAGIC:
|
||||
if (spriteIDs.anyMatch(id -> id == SpriteID.SKILL_MAGIC || correctPrayer))
|
||||
{
|
||||
color = config.getMagePrayerColor().getRGB();
|
||||
correctPrayer = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
widget.setTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetTextColor(Widget widget)
|
||||
{
|
||||
int defaultColorIdx = client.getVar(Varbits.EXPERIENCE_DROP_COLOR);
|
||||
int defaultColor = DefaultColors.values()[defaultColorIdx].getColor().getRGB();
|
||||
widget.setTextColor(defaultColor);
|
||||
}
|
||||
|
||||
private PrayerType getActivePrayerType()
|
||||
{
|
||||
for (XpPrayer prayer : XpPrayer.values())
|
||||
{
|
||||
if (client.isPrayerActive(prayer.getPrayer()))
|
||||
{
|
||||
return prayer.getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
// Detect hitting a 0
|
||||
if (lastOpponent != null)
|
||||
{
|
||||
int health = calculateHealth(lastOpponent);
|
||||
if (health != -1 && opponentHealth != -1 && health == opponentHealth && hasHit)
|
||||
{
|
||||
damage = 0;
|
||||
hasHit = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle getting XP gains
|
||||
if (hasDropped)
|
||||
{
|
||||
if (xpGains != 0 && attackStyle.getSkills().length > 1 && attackStyle != LONGRANGE)
|
||||
{
|
||||
damage = (int) (xpGains / (attackStyle.getSkills().length * 1.3));
|
||||
}
|
||||
else if (xpGains != 0)
|
||||
{
|
||||
damage = xpGains / 4;
|
||||
}
|
||||
|
||||
xpGains = 0;
|
||||
hasDropped = false;
|
||||
}
|
||||
|
||||
// Clear opponent
|
||||
if (lastOpponent != null && lastTime != null && client.getLocalPlayer().getInteracting() == null)
|
||||
{
|
||||
if (Duration.between(lastTime, Instant.now()).compareTo(WAIT) > 0)
|
||||
{
|
||||
lastOpponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
currentTickPrayer = getActivePrayerType();
|
||||
correctPrayer = false;
|
||||
|
||||
final int fakeTickDelay = config.fakeXpDropDelay();
|
||||
|
||||
if (fakeTickDelay == 0 || lastSkill == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If an xp drop was created this tick, reset the counter
|
||||
if (hasDropped)
|
||||
{
|
||||
hasDropped = false;
|
||||
tickCounter = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (++tickCounter % fakeTickDelay != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.runScript(XPDROP_DISABLED, lastSkill.ordinal(), previousExpGained);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event)
|
||||
{
|
||||
final Skill skill = event.getSkill();
|
||||
final int xp = client.getSkillExperience(skill);
|
||||
|
||||
lastSkill = skill;
|
||||
|
||||
Integer previous = previousSkillExpTable.put(skill, xp);
|
||||
if (previous != null)
|
||||
{
|
||||
opponentHealth = calculateHealth(lastOpponent);
|
||||
previousExpGained = xp - previous;
|
||||
if (skill != Skill.HITPOINTS && Arrays.stream(offensiveStyles).anyMatch(attackStyle::equals))
|
||||
{
|
||||
xpGains += previousExpGained;
|
||||
}
|
||||
|
||||
hasDropped = true;
|
||||
hasHit = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode)
|
||||
{
|
||||
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles();
|
||||
if (attackStyleIndex < attackStyles.length)
|
||||
{
|
||||
attackStyle = attackStyles[attackStyleIndex];
|
||||
if (attackStyle == null)
|
||||
{
|
||||
attackStyle = OTHER;
|
||||
}
|
||||
else if ((attackStyle == CASTING) && (castingMode == 1))
|
||||
{
|
||||
attackStyle = DEFENSIVE_CASTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractingChanged(InteractingChanged event)
|
||||
{
|
||||
if (event.getSource() != client.getLocalPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Actor opponent = event.getTarget();
|
||||
|
||||
if (opponent == null)
|
||||
{
|
||||
lastTime = Instant.now();
|
||||
return;
|
||||
}
|
||||
else if (opponent.getName().equalsIgnoreCase("fishing spot"))
|
||||
{
|
||||
lastTime = Instant.now().minus(WAIT);
|
||||
return;
|
||||
}
|
||||
|
||||
damage = 0;
|
||||
lastOpponent = opponent;
|
||||
opponentHealth = calculateHealth(opponent);
|
||||
}
|
||||
|
||||
private int calculateHealth(Actor target)
|
||||
{
|
||||
if (target == null || target.getName() == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int healthScale = target.getHealth();
|
||||
final int healthRatio = target.getHealthRatio();
|
||||
final String targetName = Text.removeTags(target.getName());
|
||||
|
||||
Integer maxHealth = -1;
|
||||
if (target instanceof NPC)
|
||||
{
|
||||
maxHealth = npcManager.getHealth(targetName, target.getCombatLevel());
|
||||
}
|
||||
else if (target instanceof Player)
|
||||
{
|
||||
final HiscoreResult hiscoreResult = hiscoreManager.lookupAsync(targetName, HiscoreEndpoint.NORMAL);
|
||||
if (hiscoreResult != null)
|
||||
{
|
||||
final int hp = hiscoreResult.getHitpoints().getLevel();
|
||||
if (hp > 0)
|
||||
{
|
||||
maxHealth = hp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) ((maxHealth * healthRatio / healthScale) + 0.5f);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE))
|
||||
{
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit,
|
||||
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
|
||||
}
|
||||
|
||||
if (equippedWeaponTypeVarbit == -1 || equippedWeaponTypeVarbit != client.getVar(Varbits.EQUIPPED_WEAPON_TYPE))
|
||||
{
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
updateAttackStyle(equippedWeaponTypeVarbit, client.getVar(VarPlayer.ATTACK_STYLE),
|
||||
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
|
||||
}
|
||||
|
||||
if (castingModeVarbit == -1 || castingModeVarbit != client.getVar(Varbits.DEFENSIVE_CASTING_MODE))
|
||||
{
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), client.getVar(VarPlayer.ATTACK_STYLE),
|
||||
castingModeVarbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.experiencedrop;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Prayer;
|
||||
import static net.runelite.api.Prayer.*;
|
||||
import static net.runelite.client.plugins.experiencedrop.PrayerType.MAGIC;
|
||||
import static net.runelite.client.plugins.experiencedrop.PrayerType.MELEE;
|
||||
import static net.runelite.client.plugins.experiencedrop.PrayerType.RANGE;
|
||||
|
||||
enum XpPrayer
|
||||
{
|
||||
XP_BURST_OF_STRENGTH(BURST_OF_STRENGTH, MELEE),
|
||||
XP_CLARITY_OF_THOUGHT(CLARITY_OF_THOUGHT, MELEE),
|
||||
XP_SHARP_EYE(SHARP_EYE, RANGE),
|
||||
XP_MYSTIC_WILL(MYSTIC_WILL, MAGIC),
|
||||
XP_SUPERHUMAN_STRENGTH(SUPERHUMAN_STRENGTH, MELEE),
|
||||
XP_IMPROVED_REFLEXES(IMPROVED_REFLEXES, MELEE),
|
||||
XP_HAWK_EYE(HAWK_EYE, RANGE),
|
||||
XP_MYSTIC_LORE(MYSTIC_LORE, MAGIC),
|
||||
XP_ULTIMATE_STRENGTH(ULTIMATE_STRENGTH, MELEE),
|
||||
XP_INCREDIBLE_REFLEXES(INCREDIBLE_REFLEXES, MELEE),
|
||||
XP_EAGLE_EYE(EAGLE_EYE, RANGE),
|
||||
XP_MYSTIC_MIGHT(MYSTIC_MIGHT, MAGIC),
|
||||
XP_CHIVALRY(CHIVALRY, MELEE),
|
||||
XP_PIETY(PIETY, MELEE),
|
||||
XP_RIGOUR(RIGOUR, RANGE),
|
||||
XP_AUGURY(AUGURY, MAGIC);
|
||||
|
||||
@Getter
|
||||
private final Prayer prayer;
|
||||
@Getter
|
||||
private final PrayerType type;
|
||||
|
||||
XpPrayer(Prayer prayer, PrayerType type)
|
||||
{
|
||||
this.prayer = prayer;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.experiencedrop;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Prayer;
|
||||
import static net.runelite.api.Prayer.AUGURY;
|
||||
import static net.runelite.api.Prayer.BURST_OF_STRENGTH;
|
||||
import static net.runelite.api.Prayer.CHIVALRY;
|
||||
import static net.runelite.api.Prayer.CLARITY_OF_THOUGHT;
|
||||
import static net.runelite.api.Prayer.EAGLE_EYE;
|
||||
import static net.runelite.api.Prayer.HAWK_EYE;
|
||||
import static net.runelite.api.Prayer.IMPROVED_REFLEXES;
|
||||
import static net.runelite.api.Prayer.INCREDIBLE_REFLEXES;
|
||||
import static net.runelite.api.Prayer.MYSTIC_LORE;
|
||||
import static net.runelite.api.Prayer.MYSTIC_MIGHT;
|
||||
import static net.runelite.api.Prayer.MYSTIC_WILL;
|
||||
import static net.runelite.api.Prayer.PIETY;
|
||||
import static net.runelite.api.Prayer.RIGOUR;
|
||||
import static net.runelite.api.Prayer.SHARP_EYE;
|
||||
import static net.runelite.api.Prayer.SUPERHUMAN_STRENGTH;
|
||||
import static net.runelite.api.Prayer.ULTIMATE_STRENGTH;
|
||||
import static net.runelite.client.plugins.experiencedrop.PrayerType.MAGIC;
|
||||
import static net.runelite.client.plugins.experiencedrop.PrayerType.MELEE;
|
||||
import static net.runelite.client.plugins.experiencedrop.PrayerType.RANGE;
|
||||
|
||||
enum XpPrayer
|
||||
{
|
||||
XP_BURST_OF_STRENGTH(BURST_OF_STRENGTH, MELEE),
|
||||
XP_CLARITY_OF_THOUGHT(CLARITY_OF_THOUGHT, MELEE),
|
||||
XP_SHARP_EYE(SHARP_EYE, RANGE),
|
||||
XP_MYSTIC_WILL(MYSTIC_WILL, MAGIC),
|
||||
XP_SUPERHUMAN_STRENGTH(SUPERHUMAN_STRENGTH, MELEE),
|
||||
XP_IMPROVED_REFLEXES(IMPROVED_REFLEXES, MELEE),
|
||||
XP_HAWK_EYE(HAWK_EYE, RANGE),
|
||||
XP_MYSTIC_LORE(MYSTIC_LORE, MAGIC),
|
||||
XP_ULTIMATE_STRENGTH(ULTIMATE_STRENGTH, MELEE),
|
||||
XP_INCREDIBLE_REFLEXES(INCREDIBLE_REFLEXES, MELEE),
|
||||
XP_EAGLE_EYE(EAGLE_EYE, RANGE),
|
||||
XP_MYSTIC_MIGHT(MYSTIC_MIGHT, MAGIC),
|
||||
XP_CHIVALRY(CHIVALRY, MELEE),
|
||||
XP_PIETY(PIETY, MELEE),
|
||||
XP_RIGOUR(RIGOUR, RANGE),
|
||||
XP_AUGURY(AUGURY, MAGIC);
|
||||
|
||||
@Getter
|
||||
private final Prayer prayer;
|
||||
@Getter
|
||||
private final PrayerType type;
|
||||
|
||||
XpPrayer(Prayer prayer, PrayerType type)
|
||||
{
|
||||
this.prayer = prayer;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,366 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* Copyright (c) 2017, Tyler <https://github.com/tylerthardy>
|
||||
* Copyright (c) 2018, Yoav Ram <https://github.com/yoyo421>
|
||||
* Copyright (c) 2018, Infinitay <https://github.com/Infinitay>
|
||||
* 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.fairyring;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ScriptEvent;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.SoundEffectID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxTextInput;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "Fairy Rings",
|
||||
description = "Show the location of the fairy ring teleport",
|
||||
tags = {"teleportation"}
|
||||
)
|
||||
public class FairyRingPlugin extends Plugin
|
||||
{
|
||||
private static final String[] leftDial = new String[]{"A", "D", "C", "B"};
|
||||
private static final String[] middleDial = new String[]{"I", "L", "K", "J"};
|
||||
private static final String[] rightDial = new String[]{"P", "S", "R", "Q"};
|
||||
|
||||
private static final int ENTRY_PADDING = 3;
|
||||
|
||||
private static final String MENU_OPEN = "Open";
|
||||
private static final String MENU_CLOSE = "Close";
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private FairyRingConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
private ChatboxTextInput searchInput = null;
|
||||
private Widget searchBtn;
|
||||
private Collection<CodeWidgets> codes = null;
|
||||
|
||||
@Data
|
||||
private static class CodeWidgets
|
||||
{
|
||||
// The fairy hideout has both of these null, because its not the same as the rest of them
|
||||
@Nullable
|
||||
private Widget favorite;
|
||||
|
||||
@Nullable
|
||||
private Widget code;
|
||||
|
||||
private Widget description;
|
||||
}
|
||||
|
||||
@Provides
|
||||
FairyRingConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(FairyRingConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
setWidgetTextToDestination();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded widgetLoaded)
|
||||
{
|
||||
if (widgetLoaded.getGroupId() == WidgetID.FAIRY_RING_PANEL_GROUP_ID)
|
||||
{
|
||||
setWidgetTextToDestination();
|
||||
|
||||
Widget header = client.getWidget(WidgetInfo.FAIRY_RING_HEADER);
|
||||
if (header != null)
|
||||
{
|
||||
searchBtn = header.createChild(-1, WidgetType.GRAPHIC);
|
||||
searchBtn.setSpriteId(SpriteID.GE_SEARCH);
|
||||
searchBtn.setOriginalWidth(17);
|
||||
searchBtn.setOriginalHeight(17);
|
||||
searchBtn.setOriginalX(11);
|
||||
searchBtn.setOriginalY(11);
|
||||
searchBtn.setHasListener(true);
|
||||
searchBtn.setAction(1, MENU_OPEN);
|
||||
searchBtn.setOnOpListener((JavaScriptCallback) this::menuOpen);
|
||||
searchBtn.setName("Search");
|
||||
searchBtn.revalidate();
|
||||
|
||||
codes = null;
|
||||
|
||||
if (config.autoOpen())
|
||||
{
|
||||
openSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void menuOpen(ScriptEvent e)
|
||||
{
|
||||
openSearch();
|
||||
client.playSoundEffect(SoundEffectID.UI_BOOP);
|
||||
}
|
||||
|
||||
private void menuClose(ScriptEvent e)
|
||||
{
|
||||
updateFilter("");
|
||||
chatboxPanelManager.close();
|
||||
client.playSoundEffect(SoundEffectID.UI_BOOP);
|
||||
}
|
||||
|
||||
private void setWidgetTextToDestination()
|
||||
{
|
||||
Widget fairyRingTeleportButton = client.getWidget(WidgetInfo.FAIRY_RING_TELEPORT_BUTTON);
|
||||
if (fairyRingTeleportButton != null && !fairyRingTeleportButton.isHidden())
|
||||
{
|
||||
String destination;
|
||||
try
|
||||
{
|
||||
FairyRings fairyRingDestination = getFairyRingDestination(client.getVar(Varbits.FAIRY_RING_DIAL_ADCB),
|
||||
client.getVar(Varbits.FAIRY_RIGH_DIAL_ILJK), client.getVar(Varbits.FAIRY_RING_DIAL_PSRQ));
|
||||
destination = fairyRingDestination.getDestination();
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
destination = "Invalid location";
|
||||
}
|
||||
|
||||
fairyRingTeleportButton.setText(destination);
|
||||
}
|
||||
}
|
||||
|
||||
private FairyRings getFairyRingDestination(int varbitValueDialLeft, int varbitValueDialMiddle, int varbitValueDialRight)
|
||||
{
|
||||
return FairyRings.valueOf(leftDial[varbitValueDialLeft] + middleDial[varbitValueDialMiddle] + rightDial[varbitValueDialRight]);
|
||||
}
|
||||
|
||||
private void openSearch()
|
||||
{
|
||||
updateFilter("");
|
||||
searchBtn.setAction(1, MENU_CLOSE);
|
||||
searchBtn.setOnOpListener((JavaScriptCallback) this::menuClose);
|
||||
searchInput = chatboxPanelManager.openTextInput("Filter fairy rings")
|
||||
.onChanged(s -> clientThread.invokeLater(() -> updateFilter(s)))
|
||||
.onClose(() ->
|
||||
{
|
||||
clientThread.invokeLater(() -> updateFilter(""));
|
||||
searchBtn.setOnOpListener((JavaScriptCallback) this::menuOpen);
|
||||
searchBtn.setAction(1, MENU_OPEN);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick t)
|
||||
{
|
||||
// This has to happen because the only widget that gets hidden is the tli one
|
||||
Widget fairyRingTeleportButton = client.getWidget(WidgetInfo.FAIRY_RING_TELEPORT_BUTTON);
|
||||
boolean fairyRingWidgetOpen = fairyRingTeleportButton != null && !fairyRingTeleportButton.isHidden();
|
||||
boolean chatboxOpen = searchInput != null && chatboxPanelManager.getCurrentInput() == searchInput;
|
||||
|
||||
if (!fairyRingWidgetOpen && chatboxOpen)
|
||||
{
|
||||
chatboxPanelManager.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFilter(String filter)
|
||||
{
|
||||
filter = filter.toLowerCase();
|
||||
final Widget list = client.getWidget(WidgetInfo.FAIRY_RING_LIST);
|
||||
final Widget favorites = client.getWidget(WidgetInfo.FAIRY_RING_FAVORITES);
|
||||
|
||||
if (list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (codes != null)
|
||||
{
|
||||
// Check to make sure the list hasn't been rebuild since we were last her
|
||||
// Do this by making sure the list's dynamic children are the same as when we last saw them
|
||||
if (codes.stream().noneMatch(w ->
|
||||
{
|
||||
Widget codeWidget = w.getCode();
|
||||
if (codeWidget == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return list.getChild(codeWidget.getIndex()) == codeWidget;
|
||||
}))
|
||||
{
|
||||
codes = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (codes == null)
|
||||
{
|
||||
// Find all of the widgets that we care about, grouping by their Y value
|
||||
Map<Integer, CodeWidgets> codeMap = new TreeMap<>();
|
||||
|
||||
for (Widget w : list.getStaticChildren())
|
||||
{
|
||||
if (w.isSelfHidden())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (w.getSpriteId() != -1)
|
||||
{
|
||||
codeMap.computeIfAbsent(w.getRelativeY(), k -> new CodeWidgets()).setFavorite(w);
|
||||
}
|
||||
else if (!Strings.isNullOrEmpty(w.getText()))
|
||||
{
|
||||
codeMap.computeIfAbsent(w.getRelativeY(), k -> new CodeWidgets()).setDescription(w);
|
||||
}
|
||||
}
|
||||
|
||||
for (Widget w : list.getDynamicChildren())
|
||||
{
|
||||
if (w.isSelfHidden())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CodeWidgets c = codeMap.computeIfAbsent(w.getRelativeY(), k -> new CodeWidgets());
|
||||
c.setCode(w);
|
||||
}
|
||||
|
||||
codes = codeMap.values();
|
||||
}
|
||||
|
||||
// Relayout the panel
|
||||
int y = 0;
|
||||
|
||||
if (favorites != null)
|
||||
{
|
||||
boolean hide = !filter.isEmpty();
|
||||
favorites.setHidden(hide);
|
||||
if (!hide)
|
||||
{
|
||||
y += favorites.getOriginalHeight() + ENTRY_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
for (CodeWidgets c : codes)
|
||||
{
|
||||
String code = Text.removeTags(c.getDescription().getName()).replaceAll(" ", "");
|
||||
String tags = null;
|
||||
|
||||
if (!code.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
FairyRings ring = FairyRings.valueOf(code);
|
||||
tags = ring.getTags();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
log.warn("Unable to find ring with code '{}'", code, e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hidden = !(filter.isEmpty()
|
||||
|| Text.removeTags(c.getDescription().getText()).toLowerCase().contains(filter)
|
||||
|| code.toLowerCase().contains(filter)
|
||||
|| tags != null && tags.contains(filter));
|
||||
|
||||
if (c.getCode() != null)
|
||||
{
|
||||
c.getCode().setHidden(hidden);
|
||||
c.getCode().setOriginalY(y);
|
||||
}
|
||||
|
||||
if (c.getFavorite() != null)
|
||||
{
|
||||
c.getFavorite().setHidden(hidden);
|
||||
c.getFavorite().setOriginalY(y);
|
||||
}
|
||||
|
||||
c.getDescription().setHidden(hidden);
|
||||
c.getDescription().setOriginalY(y);
|
||||
|
||||
if (!hidden)
|
||||
{
|
||||
y += c.getDescription().getHeight() + ENTRY_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
y -= ENTRY_PADDING;
|
||||
|
||||
if (y < 0)
|
||||
{
|
||||
y = 0;
|
||||
}
|
||||
|
||||
int newHeight = 0;
|
||||
if (list.getScrollHeight() > 0)
|
||||
{
|
||||
newHeight = (list.getScrollY() * y) / list.getScrollHeight();
|
||||
}
|
||||
|
||||
list.setScrollHeight(y);
|
||||
list.revalidateScroll();
|
||||
client.runScript(
|
||||
ScriptID.UPDATE_SCROLLBAR,
|
||||
WidgetInfo.FAIRY_RING_LIST_SCROLLBAR.getId(),
|
||||
WidgetInfo.FAIRY_RING_LIST.getId(),
|
||||
newHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* Copyright (c) 2017, Tyler <https://github.com/tylerthardy>
|
||||
* Copyright (c) 2018, Yoav Ram <https://github.com/yoyo421>
|
||||
* Copyright (c) 2018, Infinitay <https://github.com/Infinitay>
|
||||
* 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.fairyring;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ScriptEvent;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.SoundEffectID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxTextInput;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "Fairy Rings",
|
||||
description = "Show the location of the fairy ring teleport",
|
||||
tags = {"teleportation"}
|
||||
)
|
||||
public class FairyRingPlugin extends Plugin
|
||||
{
|
||||
private static final String[] leftDial = new String[]{"A", "D", "C", "B"};
|
||||
private static final String[] middleDial = new String[]{"I", "L", "K", "J"};
|
||||
private static final String[] rightDial = new String[]{"P", "S", "R", "Q"};
|
||||
|
||||
private static final int ENTRY_PADDING = 3;
|
||||
|
||||
private static final String MENU_OPEN = "Open";
|
||||
private static final String MENU_CLOSE = "Close";
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private FairyRingConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
private ChatboxTextInput searchInput = null;
|
||||
private Widget searchBtn;
|
||||
private Collection<CodeWidgets> codes = null;
|
||||
|
||||
@Data
|
||||
private static class CodeWidgets
|
||||
{
|
||||
// The fairy hideout has both of these null, because its not the same as the rest of them
|
||||
@Nullable
|
||||
private Widget favorite;
|
||||
|
||||
@Nullable
|
||||
private Widget code;
|
||||
|
||||
private Widget description;
|
||||
}
|
||||
|
||||
@Provides
|
||||
FairyRingConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(FairyRingConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
setWidgetTextToDestination();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded widgetLoaded)
|
||||
{
|
||||
if (widgetLoaded.getGroupId() == WidgetID.FAIRY_RING_PANEL_GROUP_ID)
|
||||
{
|
||||
setWidgetTextToDestination();
|
||||
|
||||
Widget header = client.getWidget(WidgetInfo.FAIRY_RING_HEADER);
|
||||
if (header != null)
|
||||
{
|
||||
searchBtn = header.createChild(-1, WidgetType.GRAPHIC);
|
||||
searchBtn.setSpriteId(SpriteID.GE_SEARCH);
|
||||
searchBtn.setOriginalWidth(17);
|
||||
searchBtn.setOriginalHeight(17);
|
||||
searchBtn.setOriginalX(11);
|
||||
searchBtn.setOriginalY(11);
|
||||
searchBtn.setHasListener(true);
|
||||
searchBtn.setAction(1, MENU_OPEN);
|
||||
searchBtn.setOnOpListener((JavaScriptCallback) this::menuOpen);
|
||||
searchBtn.setName("Search");
|
||||
searchBtn.revalidate();
|
||||
|
||||
codes = null;
|
||||
|
||||
if (config.autoOpen())
|
||||
{
|
||||
openSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void menuOpen(ScriptEvent e)
|
||||
{
|
||||
openSearch();
|
||||
client.playSoundEffect(SoundEffectID.UI_BOOP);
|
||||
}
|
||||
|
||||
private void menuClose(ScriptEvent e)
|
||||
{
|
||||
updateFilter("");
|
||||
chatboxPanelManager.close();
|
||||
client.playSoundEffect(SoundEffectID.UI_BOOP);
|
||||
}
|
||||
|
||||
private void setWidgetTextToDestination()
|
||||
{
|
||||
Widget fairyRingTeleportButton = client.getWidget(WidgetInfo.FAIRY_RING_TELEPORT_BUTTON);
|
||||
if (fairyRingTeleportButton != null && !fairyRingTeleportButton.isHidden())
|
||||
{
|
||||
String destination;
|
||||
try
|
||||
{
|
||||
FairyRings fairyRingDestination = getFairyRingDestination(client.getVar(Varbits.FAIRY_RING_DIAL_ADCB),
|
||||
client.getVar(Varbits.FAIRY_RIGH_DIAL_ILJK), client.getVar(Varbits.FAIRY_RING_DIAL_PSRQ));
|
||||
destination = fairyRingDestination.getDestination();
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
destination = "Invalid location";
|
||||
}
|
||||
|
||||
fairyRingTeleportButton.setText(destination);
|
||||
}
|
||||
}
|
||||
|
||||
private FairyRings getFairyRingDestination(int varbitValueDialLeft, int varbitValueDialMiddle, int varbitValueDialRight)
|
||||
{
|
||||
return FairyRings.valueOf(leftDial[varbitValueDialLeft] + middleDial[varbitValueDialMiddle] + rightDial[varbitValueDialRight]);
|
||||
}
|
||||
|
||||
private void openSearch()
|
||||
{
|
||||
updateFilter("");
|
||||
searchBtn.setAction(1, MENU_CLOSE);
|
||||
searchBtn.setOnOpListener((JavaScriptCallback) this::menuClose);
|
||||
searchInput = chatboxPanelManager.openTextInput("Filter fairy rings")
|
||||
.onChanged(s -> clientThread.invokeLater(() -> updateFilter(s)))
|
||||
.onClose(() ->
|
||||
{
|
||||
clientThread.invokeLater(() -> updateFilter(""));
|
||||
searchBtn.setOnOpListener((JavaScriptCallback) this::menuOpen);
|
||||
searchBtn.setAction(1, MENU_OPEN);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick t)
|
||||
{
|
||||
// This has to happen because the only widget that gets hidden is the tli one
|
||||
Widget fairyRingTeleportButton = client.getWidget(WidgetInfo.FAIRY_RING_TELEPORT_BUTTON);
|
||||
boolean fairyRingWidgetOpen = fairyRingTeleportButton != null && !fairyRingTeleportButton.isHidden();
|
||||
boolean chatboxOpen = searchInput != null && chatboxPanelManager.getCurrentInput() == searchInput;
|
||||
|
||||
if (!fairyRingWidgetOpen && chatboxOpen)
|
||||
{
|
||||
chatboxPanelManager.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFilter(String filter)
|
||||
{
|
||||
filter = filter.toLowerCase();
|
||||
final Widget list = client.getWidget(WidgetInfo.FAIRY_RING_LIST);
|
||||
final Widget favorites = client.getWidget(WidgetInfo.FAIRY_RING_FAVORITES);
|
||||
|
||||
if (list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (codes != null)
|
||||
{
|
||||
// Check to make sure the list hasn't been rebuild since we were last her
|
||||
// Do this by making sure the list's dynamic children are the same as when we last saw them
|
||||
if (codes.stream().noneMatch(w ->
|
||||
{
|
||||
Widget codeWidget = w.getCode();
|
||||
if (codeWidget == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return list.getChild(codeWidget.getIndex()) == codeWidget;
|
||||
}))
|
||||
{
|
||||
codes = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (codes == null)
|
||||
{
|
||||
// Find all of the widgets that we care about, grouping by their Y value
|
||||
Map<Integer, CodeWidgets> codeMap = new TreeMap<>();
|
||||
|
||||
for (Widget w : list.getStaticChildren())
|
||||
{
|
||||
if (w.isSelfHidden())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (w.getSpriteId() != -1)
|
||||
{
|
||||
codeMap.computeIfAbsent(w.getRelativeY(), k -> new CodeWidgets()).setFavorite(w);
|
||||
}
|
||||
else if (!Strings.isNullOrEmpty(w.getText()))
|
||||
{
|
||||
codeMap.computeIfAbsent(w.getRelativeY(), k -> new CodeWidgets()).setDescription(w);
|
||||
}
|
||||
}
|
||||
|
||||
for (Widget w : list.getDynamicChildren())
|
||||
{
|
||||
if (w.isSelfHidden())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CodeWidgets c = codeMap.computeIfAbsent(w.getRelativeY(), k -> new CodeWidgets());
|
||||
c.setCode(w);
|
||||
}
|
||||
|
||||
codes = codeMap.values();
|
||||
}
|
||||
|
||||
// Relayout the panel
|
||||
int y = 0;
|
||||
|
||||
if (favorites != null)
|
||||
{
|
||||
boolean hide = !filter.isEmpty();
|
||||
favorites.setHidden(hide);
|
||||
if (!hide)
|
||||
{
|
||||
y += favorites.getOriginalHeight() + ENTRY_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
for (CodeWidgets c : codes)
|
||||
{
|
||||
String code = Text.removeTags(c.getDescription().getName()).replaceAll(" ", "");
|
||||
String tags = null;
|
||||
|
||||
if (!code.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
FairyRings ring = FairyRings.valueOf(code);
|
||||
tags = ring.getTags();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
log.warn("Unable to find ring with code '{}'", code, e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hidden = !(filter.isEmpty()
|
||||
|| Text.removeTags(c.getDescription().getText()).toLowerCase().contains(filter)
|
||||
|| code.toLowerCase().contains(filter)
|
||||
|| tags != null && tags.contains(filter));
|
||||
|
||||
if (c.getCode() != null)
|
||||
{
|
||||
c.getCode().setHidden(hidden);
|
||||
c.getCode().setOriginalY(y);
|
||||
}
|
||||
|
||||
if (c.getFavorite() != null)
|
||||
{
|
||||
c.getFavorite().setHidden(hidden);
|
||||
c.getFavorite().setOriginalY(y);
|
||||
}
|
||||
|
||||
c.getDescription().setHidden(hidden);
|
||||
c.getDescription().setOriginalY(y);
|
||||
|
||||
if (!hidden)
|
||||
{
|
||||
y += c.getDescription().getHeight() + ENTRY_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
y -= ENTRY_PADDING;
|
||||
|
||||
if (y < 0)
|
||||
{
|
||||
y = 0;
|
||||
}
|
||||
|
||||
int newHeight = 0;
|
||||
if (list.getScrollHeight() > 0)
|
||||
{
|
||||
newHeight = (list.getScrollY() * y) / list.getScrollHeight();
|
||||
}
|
||||
|
||||
list.setScrollHeight(y);
|
||||
list.revalidateScroll();
|
||||
client.runScript(
|
||||
ScriptID.UPDATE_SCROLLBAR,
|
||||
WidgetInfo.FAIRY_RING_LIST_SCROLLBAR.getId(),
|
||||
WidgetInfo.FAIRY_RING_LIST.getId(),
|
||||
newHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.fightcave;
|
||||
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Prayer;
|
||||
|
||||
public enum JadAttack
|
||||
{
|
||||
MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES);
|
||||
|
||||
private final int animation;
|
||||
private final Prayer prayer;
|
||||
|
||||
JadAttack(int animation, Prayer prayer)
|
||||
{
|
||||
this.animation = animation;
|
||||
this.prayer = prayer;
|
||||
}
|
||||
|
||||
public int getAnimation()
|
||||
{
|
||||
return animation;
|
||||
}
|
||||
|
||||
public Prayer getPrayer()
|
||||
{
|
||||
return prayer;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.fightcave;
|
||||
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Prayer;
|
||||
|
||||
public enum JadAttack
|
||||
{
|
||||
MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES);
|
||||
|
||||
private final int animation;
|
||||
private final Prayer prayer;
|
||||
|
||||
JadAttack(int animation, Prayer prayer)
|
||||
{
|
||||
this.animation = animation;
|
||||
this.prayer = prayer;
|
||||
}
|
||||
|
||||
public int getAnimation()
|
||||
{
|
||||
return animation;
|
||||
}
|
||||
|
||||
public Prayer getPrayer()
|
||||
{
|
||||
return prayer;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.fightcave;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class JadOverlay extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final Client client;
|
||||
private final FightCavePlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private JadOverlay(Client client, FightCavePlugin plugin, SpriteManager spriteManager)
|
||||
{
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.spriteManager = spriteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final JadAttack attack = plugin.getAttack();
|
||||
|
||||
if (attack == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final BufferedImage prayerImage = getPrayerImage(attack);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer())
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(JadAttack attack)
|
||||
{
|
||||
final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES;
|
||||
return spriteManager.getSprite(prayerSpriteID, 0);
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.fightcave;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class JadOverlay extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final Client client;
|
||||
private final FightCavePlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private JadOverlay(Client client, FightCavePlugin plugin, SpriteManager spriteManager)
|
||||
{
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.spriteManager = spriteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final JadAttack attack = plugin.getAttack();
|
||||
|
||||
if (attack == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final BufferedImage prayerImage = getPrayerImage(attack);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer())
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(JadAttack attack)
|
||||
{
|
||||
final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES;
|
||||
return spriteManager.getSprite(prayerSpriteID, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,124 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcave;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class WaveOverlay extends Overlay
|
||||
{
|
||||
private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE;
|
||||
|
||||
private final FightCaveConfig config;
|
||||
private final FightCavePlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private WaveOverlay(FightCaveConfig config, FightCavePlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.inFightCave()
|
||||
|| plugin.getCurrentWave() < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
final int currentWave = plugin.getCurrentWave();
|
||||
final int waveIndex = currentWave - 1;
|
||||
|
||||
if (config.waveDisplay() == WaveDisplayMode.CURRENT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCavePlugin.getWAVES().get(waveIndex);
|
||||
|
||||
addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents);
|
||||
}
|
||||
|
||||
if ((config.waveDisplay() == WaveDisplayMode.NEXT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
&& currentWave != FightCavePlugin.MAX_WAVE)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCavePlugin.getWAVES().get(waveIndex + 1);
|
||||
|
||||
addWaveInfo("Next wave", waveContents);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
private void addWaveInfo(final String headerText, final Map<WaveMonster, Integer> waveContents)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(headerText)
|
||||
.color(HEADER_COLOR)
|
||||
.build());
|
||||
|
||||
for (LineComponent line : buildWaveLines(waveContents))
|
||||
{
|
||||
panelComponent.getChildren().add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<LineComponent> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<WaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<LineComponent> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<WaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final WaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final LineComponent line = LineComponent.builder()
|
||||
.left(FightCavePlugin.formatMonsterQuantity(monster, quantity))
|
||||
.build();
|
||||
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcave;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class WaveOverlay extends Overlay
|
||||
{
|
||||
private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE;
|
||||
|
||||
private final FightCaveConfig config;
|
||||
private final FightCavePlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private WaveOverlay(FightCaveConfig config, FightCavePlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.inFightCave()
|
||||
|| plugin.getCurrentWave() < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
final int currentWave = plugin.getCurrentWave();
|
||||
final int waveIndex = currentWave - 1;
|
||||
|
||||
if (config.waveDisplay() == WaveDisplayMode.CURRENT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCavePlugin.getWAVES().get(waveIndex);
|
||||
|
||||
addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents);
|
||||
}
|
||||
|
||||
if ((config.waveDisplay() == WaveDisplayMode.NEXT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
&& currentWave != FightCavePlugin.MAX_WAVE)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCavePlugin.getWAVES().get(waveIndex + 1);
|
||||
|
||||
addWaveInfo("Next wave", waveContents);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private void addWaveInfo(final String headerText, final Map<WaveMonster, Integer> waveContents)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(headerText)
|
||||
.color(HEADER_COLOR)
|
||||
.build());
|
||||
|
||||
for (LineComponent line : buildWaveLines(waveContents))
|
||||
{
|
||||
panelComponent.getChildren().add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<LineComponent> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<WaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<LineComponent> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<WaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final WaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final LineComponent line = LineComponent.builder()
|
||||
.left(FightCavePlugin.formatMonsterQuantity(monster, quantity))
|
||||
.build();
|
||||
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,182 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fishing;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.ProgressPieComponent;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
class FishingSpotOverlay extends Overlay
|
||||
{
|
||||
private static final Duration MINNOW_MOVE = Duration.ofSeconds(15);
|
||||
private static final Duration MINNOW_WARN = Duration.ofSeconds(3);
|
||||
private static final int ONE_TICK_AERIAL_FISHING = 3;
|
||||
|
||||
private final FishingPlugin plugin;
|
||||
private final FishingConfig config;
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean hidden;
|
||||
|
||||
@Inject
|
||||
private FishingSpotOverlay(FishingPlugin plugin, FishingConfig config, Client client, ItemManager itemManager)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (hidden)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (NPC npc : plugin.getFishingSpots())
|
||||
{
|
||||
FishingSpot spot = FishingSpot.getSPOTS().get(npc.getId());
|
||||
|
||||
if (spot == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config.onlyCurrentSpot() && plugin.getCurrentSpot() != null && plugin.getCurrentSpot() != spot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Color color = npc.getGraphic() == GraphicID.FLYING_FISH ? Color.RED : Color.CYAN;
|
||||
|
||||
if (spot == FishingSpot.MINNOW && config.showMinnowOverlay())
|
||||
{
|
||||
MinnowSpot minnowSpot = plugin.getMinnowSpots().get(npc.getIndex());
|
||||
if (minnowSpot != null)
|
||||
{
|
||||
long millisLeft = MINNOW_MOVE.toMillis() - Duration.between(minnowSpot.getTime(), Instant.now()).toMillis();
|
||||
if (millisLeft < MINNOW_WARN.toMillis())
|
||||
{
|
||||
color = Color.ORANGE;
|
||||
}
|
||||
|
||||
LocalPoint localPoint = npc.getLocalLocation();
|
||||
Point location = Perspective.localToCanvas(client, localPoint, client.getPlane());
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
ProgressPieComponent pie = new ProgressPieComponent();
|
||||
pie.setFill(color);
|
||||
pie.setBorderColor(color);
|
||||
pie.setPosition(location);
|
||||
pie.setProgress((float) millisLeft / MINNOW_MOVE.toMillis());
|
||||
pie.render(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showSpotTiles())
|
||||
{
|
||||
Polygon poly = npc.getCanvasTilePoly();
|
||||
|
||||
if (spot == FishingSpot.COMMON_TENCH
|
||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||
{
|
||||
color = Color.GREEN;
|
||||
}
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color.darker());
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showSpotIcons())
|
||||
{
|
||||
BufferedImage fishImage = itemManager.getImage(spot.getFishSpriteId());;
|
||||
|
||||
if (spot == FishingSpot.COMMON_TENCH
|
||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||
{
|
||||
fishImage = ImageUtil.outlineImage(itemManager.getImage(spot.getFishSpriteId()), Color.GREEN);
|
||||
}
|
||||
|
||||
if (fishImage != null)
|
||||
{
|
||||
Point imageLocation = npc.getCanvasImageLocation(fishImage, npc.getLogicalHeight());
|
||||
if (imageLocation != null)
|
||||
{
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, fishImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showSpotNames())
|
||||
{
|
||||
String text = spot.getName();
|
||||
Point textLocation = npc.getCanvasTextLocation(graphics, text, npc.getLogicalHeight() + 40);
|
||||
|
||||
if (spot == FishingSpot.COMMON_TENCH
|
||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||
{
|
||||
color = Color.GREEN;
|
||||
}
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, text, color.darker());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fishing;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.components.ProgressPieComponent;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
class FishingSpotOverlay extends Overlay
|
||||
{
|
||||
private static final Duration MINNOW_MOVE = Duration.ofSeconds(15);
|
||||
private static final Duration MINNOW_WARN = Duration.ofSeconds(3);
|
||||
private static final int ONE_TICK_AERIAL_FISHING = 3;
|
||||
|
||||
private final FishingPlugin plugin;
|
||||
private final FishingConfig config;
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean hidden;
|
||||
|
||||
@Inject
|
||||
private FishingSpotOverlay(FishingPlugin plugin, FishingConfig config, Client client, ItemManager itemManager)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (hidden)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (NPC npc : plugin.getFishingSpots())
|
||||
{
|
||||
FishingSpot spot = FishingSpot.getSPOTS().get(npc.getId());
|
||||
|
||||
if (spot == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config.onlyCurrentSpot() && plugin.getCurrentSpot() != null && plugin.getCurrentSpot() != spot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Color color = npc.getGraphic() == GraphicID.FLYING_FISH ? Color.RED : Color.CYAN;
|
||||
|
||||
if (spot == FishingSpot.MINNOW && config.showMinnowOverlay())
|
||||
{
|
||||
MinnowSpot minnowSpot = plugin.getMinnowSpots().get(npc.getIndex());
|
||||
if (minnowSpot != null)
|
||||
{
|
||||
long millisLeft = MINNOW_MOVE.toMillis() - Duration.between(minnowSpot.getTime(), Instant.now()).toMillis();
|
||||
if (millisLeft < MINNOW_WARN.toMillis())
|
||||
{
|
||||
color = Color.ORANGE;
|
||||
}
|
||||
|
||||
LocalPoint localPoint = npc.getLocalLocation();
|
||||
Point location = Perspective.localToCanvas(client, localPoint, client.getPlane());
|
||||
|
||||
if (location != null)
|
||||
{
|
||||
ProgressPieComponent pie = new ProgressPieComponent();
|
||||
pie.setFill(color);
|
||||
pie.setBorderColor(color);
|
||||
pie.setPosition(location);
|
||||
pie.setProgress((float) millisLeft / MINNOW_MOVE.toMillis());
|
||||
pie.render(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showSpotTiles())
|
||||
{
|
||||
Polygon poly = npc.getCanvasTilePoly();
|
||||
|
||||
if (spot == FishingSpot.COMMON_TENCH
|
||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||
{
|
||||
color = Color.GREEN;
|
||||
}
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color.darker());
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showSpotIcons())
|
||||
{
|
||||
BufferedImage fishImage = itemManager.getImage(spot.getFishSpriteId());
|
||||
|
||||
if (spot == FishingSpot.COMMON_TENCH
|
||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||
{
|
||||
fishImage = ImageUtil.outlineImage(itemManager.getImage(spot.getFishSpriteId()), Color.GREEN);
|
||||
}
|
||||
|
||||
if (fishImage != null)
|
||||
{
|
||||
Point imageLocation = npc.getCanvasImageLocation(fishImage, npc.getLogicalHeight());
|
||||
if (imageLocation != null)
|
||||
{
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, fishImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showSpotNames())
|
||||
{
|
||||
String text = spot.getName();
|
||||
Point textLocation = npc.getCanvasTextLocation(graphics, text, npc.getLogicalHeight() + 40);
|
||||
|
||||
if (spot == FishingSpot.COMMON_TENCH
|
||||
&& npc.getWorldLocation().distanceTo2D(client.getLocalPlayer().getWorldLocation()) <= ONE_TICK_AERIAL_FISHING)
|
||||
{
|
||||
color = Color.GREEN;
|
||||
}
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, text, color.darker());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,7 @@ import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@@ -36,7 +36,7 @@ import net.runelite.api.events.FocusChanged;
|
||||
* For low powered computers, the RS client is often throttled by the hardware or OS and draws at 25-30 fps.
|
||||
* The nano timer is not used in this scenario.
|
||||
* Instead to catch up the RS client runs several cycles before drawing, thus maintaining 50 cycles / second.
|
||||
*
|
||||
* <p>
|
||||
* Enforcing FPS in the draw code does not impact the client engine's ability to run including its audio,
|
||||
* even when forced to 1 FPS with this plugin.
|
||||
*/
|
||||
|
||||
@@ -57,10 +57,12 @@ public enum PlayerSpellEffect
|
||||
|
||||
public static PlayerSpellEffect getFromSpotAnim(int spotAnim)
|
||||
{
|
||||
for(PlayerSpellEffect effect : values())
|
||||
for (PlayerSpellEffect effect : values())
|
||||
{
|
||||
if(effect.getSpotAnimId() == spotAnim)
|
||||
if (effect.getSpotAnimId() == spotAnim)
|
||||
{
|
||||
return effect;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ package net.runelite.client.plugins.friendtagging;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -21,8 +20,17 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.inject.Inject;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Friend;
|
||||
import net.runelite.api.Ignore;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Nameable;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.NameableNameChanged;
|
||||
import net.runelite.api.events.RemovedFriend;
|
||||
import net.runelite.api.events.WidgetMenuOptionClicked;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
@@ -40,8 +48,8 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
@PluginDescriptor(
|
||||
name = "Friend Tagging",
|
||||
description = "Tag people on your friends list.",
|
||||
tags = {"PVP", "friend", "finder", "pk", "pklite"},
|
||||
type = PluginType.UTILITY
|
||||
tags = {"PVP", "friend", "finder", "pk", "pklite"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
public class FriendTaggingPlugin extends Plugin
|
||||
{
|
||||
@@ -267,8 +275,8 @@ public class FriendTaggingPlugin extends Plugin
|
||||
}
|
||||
|
||||
/**
|
||||
* This method combines the list of usernames on local players friend/ignore list into a comma delimited string
|
||||
* and then copies it to the clipboard.
|
||||
* This method combines the list of usernames on local players friend/ignore list into a comma delimited string
|
||||
* and then copies it to the clipboard.
|
||||
*/
|
||||
private void friendIgnoreToClipboard()
|
||||
{
|
||||
|
||||
@@ -74,7 +74,18 @@ import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginInstantiationException;
|
||||
import net.runelite.client.plugins.PluginManager;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.*;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glDeleteBuffer;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glDeleteFrameBuffer;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glDeleteRenderbuffers;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glDeleteTexture;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glDeleteVertexArrays;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glGenBuffers;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glGenFrameBuffer;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glGenRenderbuffer;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glGenTexture;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glGenVertexArrays;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.glGetInteger;
|
||||
import static net.runelite.client.plugins.gpu.GLUtil.inputStreamToString;
|
||||
import net.runelite.client.plugins.gpu.config.AntiAliasingMode;
|
||||
import net.runelite.client.plugins.gpu.template.Template;
|
||||
import net.runelite.client.ui.DrawManager;
|
||||
@@ -414,8 +425,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
{
|
||||
glVersionHeader =
|
||||
"#version 420\n" +
|
||||
"#extension GL_ARB_compute_shader : require\n" +
|
||||
"#extension GL_ARB_shader_storage_buffer_object : require\n";
|
||||
"#extension GL_ARB_compute_shader : require\n" +
|
||||
"#extension GL_ARB_shader_storage_buffer_object : require\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -707,8 +718,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
}
|
||||
|
||||
public void drawScenePaint(int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y, int z,
|
||||
SceneTilePaint paint, int tileZ, int tileX, int tileY,
|
||||
int zoom, int centerX, int centerY)
|
||||
SceneTilePaint paint, int tileZ, int tileX, int tileY,
|
||||
int zoom, int centerX, int centerY)
|
||||
{
|
||||
if (paint.getBufferLen() > 0)
|
||||
{
|
||||
@@ -733,8 +744,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
}
|
||||
|
||||
public void drawSceneModel(int orientation, int pitchSin, int pitchCos, int yawSin, int yawCos, int x, int y, int z,
|
||||
SceneTileModel model, int tileZ, int tileX, int tileY,
|
||||
int zoom, int centerX, int centerY)
|
||||
SceneTileModel model, int tileZ, int tileX, int tileY,
|
||||
int zoom, int centerX, int centerY)
|
||||
{
|
||||
if (model.getBufferLen() > 0)
|
||||
{
|
||||
@@ -980,18 +991,18 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
renderCanvasHeight = dim.height;
|
||||
|
||||
double scaleFactorY = dim.getHeight() / canvasHeight;
|
||||
double scaleFactorX = dim.getWidth() / canvasWidth;
|
||||
double scaleFactorX = dim.getWidth() / canvasWidth;
|
||||
|
||||
// Pad the viewport a little because having ints for our viewport dimensions can introduce off-by-one errors.
|
||||
final int padding = 1;
|
||||
|
||||
// Ceil the sizes because even if the size is 599.1 we want to treat it as size 600 (i.e. render to the x=599 pixel).
|
||||
renderViewportHeight = (int) Math.ceil(scaleFactorY * (renderViewportHeight)) + padding * 2;
|
||||
renderViewportWidth = (int) Math.ceil(scaleFactorX * (renderViewportWidth )) + padding * 2;
|
||||
renderViewportWidth = (int) Math.ceil(scaleFactorX * (renderViewportWidth)) + padding * 2;
|
||||
|
||||
// Floor the offsets because even if the offset is 4.9, we want to render to the x=4 pixel anyway.
|
||||
renderHeightOff = (int) Math.floor(scaleFactorY * (renderHeightOff)) - padding;
|
||||
renderWidthOff = (int) Math.floor(scaleFactorX * (renderWidthOff )) - padding;
|
||||
renderHeightOff = (int) Math.floor(scaleFactorY * (renderHeightOff)) - padding;
|
||||
renderWidthOff = (int) Math.floor(scaleFactorX * (renderWidthOff)) - padding;
|
||||
}
|
||||
|
||||
glDpiAwareViewport(renderWidthOff, renderCanvasHeight - renderViewportHeight - renderHeightOff, renderViewportWidth, renderViewportHeight);
|
||||
@@ -1169,13 +1180,13 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
*/
|
||||
private Image screenshot()
|
||||
{
|
||||
int width = client.getCanvasWidth();
|
||||
int width = client.getCanvasWidth();
|
||||
int height = client.getCanvasHeight();
|
||||
|
||||
if (client.isStretchedEnabled())
|
||||
{
|
||||
Dimension dim = client.getStretchedDimensions();
|
||||
width = dim.width;
|
||||
width = dim.width;
|
||||
height = dim.height;
|
||||
}
|
||||
|
||||
@@ -1295,10 +1306,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
{
|
||||
int var21 = (pitchCos * modelHeight >> 16) + var19;
|
||||
int var22 = (var18 - var21) * zoom;
|
||||
if (var22 / var14 < Rasterizer3D_clipMidY2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return var22 / var14 < Rasterizer3D_clipMidY2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
import static net.runelite.client.plugins.gpu.GpuPlugin.MAX_FOG_DEPTH;
|
||||
import net.runelite.client.plugins.gpu.config.AntiAliasingMode;
|
||||
import static net.runelite.client.plugins.gpu.GpuPlugin.MAX_DISTANCE;
|
||||
|
||||
@ConfigGroup("gpu")
|
||||
public interface GpuPluginConfig extends Config
|
||||
{
|
||||
@Range(
|
||||
max = MAX_DISTANCE
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "drawDistance",
|
||||
name = "Draw Distance",
|
||||
description = "Draw distance",
|
||||
position = 1
|
||||
)
|
||||
default int drawDistance()
|
||||
{
|
||||
return 25;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "smoothBanding",
|
||||
name = "Remove Color Banding",
|
||||
description = "Smooths out the color banding that is present in the CPU renderer",
|
||||
position = 2
|
||||
)
|
||||
default boolean smoothBanding()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "antiAliasingMode",
|
||||
name = "Anti Aliasing",
|
||||
description = "Configures the anti-aliasing mode",
|
||||
position = 3
|
||||
)
|
||||
default AntiAliasingMode antiAliasingMode()
|
||||
{
|
||||
return AntiAliasingMode.DISABLED;
|
||||
}
|
||||
|
||||
@Range(
|
||||
max = MAX_FOG_DEPTH
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "fogDepth",
|
||||
name = "Fog depth",
|
||||
description = "Distance from the scene edge the fog starts",
|
||||
position = 4
|
||||
)
|
||||
default int fogDepth()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gpu;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
import static net.runelite.client.plugins.gpu.GpuPlugin.MAX_DISTANCE;
|
||||
import static net.runelite.client.plugins.gpu.GpuPlugin.MAX_FOG_DEPTH;
|
||||
import net.runelite.client.plugins.gpu.config.AntiAliasingMode;
|
||||
|
||||
@ConfigGroup("gpu")
|
||||
public interface GpuPluginConfig extends Config
|
||||
{
|
||||
@Range(
|
||||
max = MAX_DISTANCE
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "drawDistance",
|
||||
name = "Draw Distance",
|
||||
description = "Draw distance",
|
||||
position = 1
|
||||
)
|
||||
default int drawDistance()
|
||||
{
|
||||
return 25;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "smoothBanding",
|
||||
name = "Remove Color Banding",
|
||||
description = "Smooths out the color banding that is present in the CPU renderer",
|
||||
position = 2
|
||||
)
|
||||
default boolean smoothBanding()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "antiAliasingMode",
|
||||
name = "Anti Aliasing",
|
||||
description = "Configures the anti-aliasing mode",
|
||||
position = 3
|
||||
)
|
||||
default AntiAliasingMode antiAliasingMode()
|
||||
{
|
||||
return AntiAliasingMode.DISABLED;
|
||||
}
|
||||
|
||||
@Range(
|
||||
max = MAX_FOG_DEPTH
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "fogDepth",
|
||||
name = "Fog depth",
|
||||
description = "Distance from the scene edge the fog starts",
|
||||
position = 4
|
||||
)
|
||||
default int fogDepth()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,277 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||
* 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.grandexchange;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import static net.runelite.api.GrandExchangeOfferState.CANCELLED_BUY;
|
||||
import static net.runelite.api.GrandExchangeOfferState.CANCELLED_SELL;
|
||||
import static net.runelite.api.GrandExchangeOfferState.EMPTY;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.components.ThinProgressBar;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
|
||||
public class GrandExchangeOfferSlot extends JPanel
|
||||
{
|
||||
private static final String FACE_CARD = "FACE_CARD";
|
||||
private static final String DETAILS_CARD = "DETAILS_CARD";
|
||||
|
||||
private static final ImageIcon RIGHT_ARROW_ICON;
|
||||
private static final ImageIcon LEFT_ARROW_ICON;
|
||||
|
||||
private final JPanel container = new JPanel();
|
||||
private final CardLayout cardLayout = new CardLayout();
|
||||
|
||||
private final JLabel itemIcon = new JLabel();
|
||||
private final JLabel itemName = new JLabel();
|
||||
private final JLabel offerInfo = new JLabel();
|
||||
|
||||
private final JLabel itemPrice = new JLabel();
|
||||
private final JLabel offerSpent = new JLabel();
|
||||
|
||||
private final ThinProgressBar progressBar = new ThinProgressBar();
|
||||
|
||||
private boolean showingFace = true;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage rightArrow = ImageUtil.alphaOffset(ImageUtil.getResourceStreamFromClass(GrandExchangeOfferSlot.class, "/util/arrow_right.png"), 0.25f);
|
||||
RIGHT_ARROW_ICON = new ImageIcon(rightArrow);
|
||||
LEFT_ARROW_ICON = new ImageIcon(ImageUtil.flipImage(rightArrow, true, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* This (sub)panel is used for each GE slot displayed
|
||||
* in the sidebar
|
||||
*/
|
||||
GrandExchangeOfferSlot()
|
||||
{
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
setBorder(new EmptyBorder(7, 0, 0, 0));
|
||||
|
||||
final MouseListener ml = new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
super.mousePressed(mouseEvent);
|
||||
switchPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
super.mouseEntered(mouseEvent);
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_HOVER_COLOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
super.mouseExited(mouseEvent);
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
};
|
||||
|
||||
container.setLayout(cardLayout);
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
JPanel faceCard = new JPanel();
|
||||
faceCard.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
faceCard.setLayout(new BorderLayout());
|
||||
faceCard.addMouseListener(ml);
|
||||
|
||||
itemIcon.setVerticalAlignment(JLabel.CENTER);
|
||||
itemIcon.setHorizontalAlignment(JLabel.CENTER);
|
||||
itemIcon.setPreferredSize(new Dimension(45, 45));
|
||||
|
||||
itemName.setForeground(Color.WHITE);
|
||||
itemName.setVerticalAlignment(JLabel.BOTTOM);
|
||||
itemName.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
offerInfo.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
offerInfo.setVerticalAlignment(JLabel.TOP);
|
||||
offerInfo.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel switchFaceViewIcon = new JLabel();
|
||||
switchFaceViewIcon.setIcon(RIGHT_ARROW_ICON);
|
||||
switchFaceViewIcon.setVerticalAlignment(JLabel.CENTER);
|
||||
switchFaceViewIcon.setHorizontalAlignment(JLabel.CENTER);
|
||||
switchFaceViewIcon.setPreferredSize(new Dimension(30, 45));
|
||||
|
||||
JPanel offerFaceDetails = new JPanel();
|
||||
offerFaceDetails.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
offerFaceDetails.setLayout(new GridLayout(2, 1, 0, 2));
|
||||
|
||||
offerFaceDetails.add(itemName);
|
||||
offerFaceDetails.add(offerInfo);
|
||||
|
||||
faceCard.add(offerFaceDetails, BorderLayout.CENTER);
|
||||
faceCard.add(itemIcon, BorderLayout.WEST);
|
||||
faceCard.add(switchFaceViewIcon, BorderLayout.EAST);
|
||||
|
||||
JPanel detailsCard = new JPanel();
|
||||
detailsCard.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
detailsCard.setLayout(new BorderLayout());
|
||||
detailsCard.setBorder(new EmptyBorder(0, 15, 0, 0));
|
||||
detailsCard.addMouseListener(ml);
|
||||
|
||||
itemPrice.setForeground(Color.WHITE);
|
||||
itemPrice.setVerticalAlignment(JLabel.BOTTOM);
|
||||
itemPrice.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
offerSpent.setForeground(Color.WHITE);
|
||||
offerSpent.setVerticalAlignment(JLabel.TOP);
|
||||
offerSpent.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel switchDetailsViewIcon = new JLabel();
|
||||
switchDetailsViewIcon.setIcon(LEFT_ARROW_ICON);
|
||||
switchDetailsViewIcon.setVerticalAlignment(JLabel.CENTER);
|
||||
switchDetailsViewIcon.setHorizontalAlignment(JLabel.CENTER);
|
||||
switchDetailsViewIcon.setPreferredSize(new Dimension(30, 45));
|
||||
|
||||
JPanel offerDetails = new JPanel();
|
||||
offerDetails.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
offerDetails.setLayout(new GridLayout(2, 1));
|
||||
|
||||
offerDetails.add(itemPrice);
|
||||
offerDetails.add(offerSpent);
|
||||
|
||||
detailsCard.add(offerDetails, BorderLayout.CENTER);
|
||||
detailsCard.add(switchDetailsViewIcon, BorderLayout.EAST);
|
||||
|
||||
container.add(faceCard, FACE_CARD);
|
||||
container.add(detailsCard, DETAILS_CARD);
|
||||
|
||||
cardLayout.show(container, FACE_CARD);
|
||||
|
||||
add(container, BorderLayout.CENTER);
|
||||
add(progressBar, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
void updateOffer(ItemComposition offerItem, BufferedImage itemImage, @Nullable GrandExchangeOffer newOffer)
|
||||
{
|
||||
if (newOffer == null || newOffer.getState() == EMPTY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
cardLayout.show(container, FACE_CARD);
|
||||
|
||||
itemName.setText(offerItem.getName());
|
||||
itemIcon.setIcon(new ImageIcon(itemImage));
|
||||
|
||||
boolean buying = newOffer.getState() == GrandExchangeOfferState.BOUGHT
|
||||
|| newOffer.getState() == GrandExchangeOfferState.BUYING
|
||||
|| newOffer.getState() == GrandExchangeOfferState.CANCELLED_BUY;
|
||||
|
||||
String offerState = (buying ? "Bought " : "Sold ")
|
||||
+ StackFormatter.quantityToRSDecimalStack(newOffer.getQuantitySold()) + " / "
|
||||
+ StackFormatter.quantityToRSDecimalStack(newOffer.getTotalQuantity());
|
||||
|
||||
offerInfo.setText(offerState);
|
||||
|
||||
itemPrice.setText(htmlLabel("Price each: ", StackFormatter.formatNumber(newOffer.getPrice())));
|
||||
|
||||
String action = buying ? "Spent: " : "Received: ";
|
||||
|
||||
offerSpent.setText(htmlLabel(action, StackFormatter.formatNumber(newOffer.getSpent()) + " / "
|
||||
+ StackFormatter.formatNumber(newOffer.getPrice() * newOffer.getTotalQuantity())));
|
||||
|
||||
progressBar.setForeground(getProgressColor(newOffer));
|
||||
progressBar.setMaximumValue(newOffer.getTotalQuantity());
|
||||
progressBar.setValue(newOffer.getQuantitySold());
|
||||
|
||||
/* Couldn't set the tooltip for the container panel as the children override it, so I'm setting
|
||||
* the tooltips on the children instead. */
|
||||
for (Component c : container.getComponents())
|
||||
{
|
||||
if (c instanceof JPanel)
|
||||
{
|
||||
JPanel panel = (JPanel) c;
|
||||
panel.setToolTipText(htmlTooltip(((int) progressBar.getPercentage()) + "%"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private String htmlTooltip(String value)
|
||||
{
|
||||
return "<html><body style = 'color:" + ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR) + "'>Progress: <span style = 'color:white'>" + value + "</span></body></html>";
|
||||
}
|
||||
|
||||
private String htmlLabel(String key, String value)
|
||||
{
|
||||
return "<html><body style = 'color:white'>" + key + "<span style = 'color:" + ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR) + "'>" + value + "</span></body></html>";
|
||||
}
|
||||
|
||||
private void switchPanel()
|
||||
{
|
||||
this.showingFace = !this.showingFace;
|
||||
cardLayout.show(container, showingFace ? FACE_CARD : DETAILS_CARD);
|
||||
}
|
||||
|
||||
private Color getProgressColor(GrandExchangeOffer offer)
|
||||
{
|
||||
if (offer.getState() == CANCELLED_BUY || offer.getState() == CANCELLED_SELL)
|
||||
{
|
||||
return ColorScheme.PROGRESS_ERROR_COLOR;
|
||||
}
|
||||
|
||||
if (offer.getQuantitySold() == offer.getTotalQuantity())
|
||||
{
|
||||
return ColorScheme.PROGRESS_COMPLETE_COLOR;
|
||||
}
|
||||
|
||||
return ColorScheme.PROGRESS_INPROGRESS_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||
* 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.grandexchange;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import static net.runelite.api.GrandExchangeOfferState.CANCELLED_BUY;
|
||||
import static net.runelite.api.GrandExchangeOfferState.CANCELLED_SELL;
|
||||
import static net.runelite.api.GrandExchangeOfferState.EMPTY;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.components.ThinProgressBar;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
|
||||
public class GrandExchangeOfferSlot extends JPanel
|
||||
{
|
||||
private static final String FACE_CARD = "FACE_CARD";
|
||||
private static final String DETAILS_CARD = "DETAILS_CARD";
|
||||
|
||||
private static final ImageIcon RIGHT_ARROW_ICON;
|
||||
private static final ImageIcon LEFT_ARROW_ICON;
|
||||
|
||||
private final JPanel container = new JPanel();
|
||||
private final CardLayout cardLayout = new CardLayout();
|
||||
|
||||
private final JLabel itemIcon = new JLabel();
|
||||
private final JLabel itemName = new JLabel();
|
||||
private final JLabel offerInfo = new JLabel();
|
||||
|
||||
private final JLabel itemPrice = new JLabel();
|
||||
private final JLabel offerSpent = new JLabel();
|
||||
|
||||
private final ThinProgressBar progressBar = new ThinProgressBar();
|
||||
|
||||
private boolean showingFace = true;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage rightArrow = ImageUtil.alphaOffset(ImageUtil.getResourceStreamFromClass(GrandExchangeOfferSlot.class, "/util/arrow_right.png"), 0.25f);
|
||||
RIGHT_ARROW_ICON = new ImageIcon(rightArrow);
|
||||
LEFT_ARROW_ICON = new ImageIcon(ImageUtil.flipImage(rightArrow, true, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* This (sub)panel is used for each GE slot displayed
|
||||
* in the sidebar
|
||||
*/
|
||||
GrandExchangeOfferSlot()
|
||||
{
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
setBorder(new EmptyBorder(7, 0, 0, 0));
|
||||
|
||||
final MouseListener ml = new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
super.mousePressed(mouseEvent);
|
||||
switchPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
super.mouseEntered(mouseEvent);
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_HOVER_COLOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
super.mouseExited(mouseEvent);
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
};
|
||||
|
||||
container.setLayout(cardLayout);
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
JPanel faceCard = new JPanel();
|
||||
faceCard.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
faceCard.setLayout(new BorderLayout());
|
||||
faceCard.addMouseListener(ml);
|
||||
|
||||
itemIcon.setVerticalAlignment(JLabel.CENTER);
|
||||
itemIcon.setHorizontalAlignment(JLabel.CENTER);
|
||||
itemIcon.setPreferredSize(new Dimension(45, 45));
|
||||
|
||||
itemName.setForeground(Color.WHITE);
|
||||
itemName.setVerticalAlignment(JLabel.BOTTOM);
|
||||
itemName.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
offerInfo.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
offerInfo.setVerticalAlignment(JLabel.TOP);
|
||||
offerInfo.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel switchFaceViewIcon = new JLabel();
|
||||
switchFaceViewIcon.setIcon(RIGHT_ARROW_ICON);
|
||||
switchFaceViewIcon.setVerticalAlignment(JLabel.CENTER);
|
||||
switchFaceViewIcon.setHorizontalAlignment(JLabel.CENTER);
|
||||
switchFaceViewIcon.setPreferredSize(new Dimension(30, 45));
|
||||
|
||||
JPanel offerFaceDetails = new JPanel();
|
||||
offerFaceDetails.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
offerFaceDetails.setLayout(new GridLayout(2, 1, 0, 2));
|
||||
|
||||
offerFaceDetails.add(itemName);
|
||||
offerFaceDetails.add(offerInfo);
|
||||
|
||||
faceCard.add(offerFaceDetails, BorderLayout.CENTER);
|
||||
faceCard.add(itemIcon, BorderLayout.WEST);
|
||||
faceCard.add(switchFaceViewIcon, BorderLayout.EAST);
|
||||
|
||||
JPanel detailsCard = new JPanel();
|
||||
detailsCard.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
detailsCard.setLayout(new BorderLayout());
|
||||
detailsCard.setBorder(new EmptyBorder(0, 15, 0, 0));
|
||||
detailsCard.addMouseListener(ml);
|
||||
|
||||
itemPrice.setForeground(Color.WHITE);
|
||||
itemPrice.setVerticalAlignment(JLabel.BOTTOM);
|
||||
itemPrice.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
offerSpent.setForeground(Color.WHITE);
|
||||
offerSpent.setVerticalAlignment(JLabel.TOP);
|
||||
offerSpent.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel switchDetailsViewIcon = new JLabel();
|
||||
switchDetailsViewIcon.setIcon(LEFT_ARROW_ICON);
|
||||
switchDetailsViewIcon.setVerticalAlignment(JLabel.CENTER);
|
||||
switchDetailsViewIcon.setHorizontalAlignment(JLabel.CENTER);
|
||||
switchDetailsViewIcon.setPreferredSize(new Dimension(30, 45));
|
||||
|
||||
JPanel offerDetails = new JPanel();
|
||||
offerDetails.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
offerDetails.setLayout(new GridLayout(2, 1));
|
||||
|
||||
offerDetails.add(itemPrice);
|
||||
offerDetails.add(offerSpent);
|
||||
|
||||
detailsCard.add(offerDetails, BorderLayout.CENTER);
|
||||
detailsCard.add(switchDetailsViewIcon, BorderLayout.EAST);
|
||||
|
||||
container.add(faceCard, FACE_CARD);
|
||||
container.add(detailsCard, DETAILS_CARD);
|
||||
|
||||
cardLayout.show(container, FACE_CARD);
|
||||
|
||||
add(container, BorderLayout.CENTER);
|
||||
add(progressBar, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
void updateOffer(ItemComposition offerItem, BufferedImage itemImage, @Nullable GrandExchangeOffer newOffer)
|
||||
{
|
||||
if (newOffer == null || newOffer.getState() == EMPTY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
cardLayout.show(container, FACE_CARD);
|
||||
|
||||
itemName.setText(offerItem.getName());
|
||||
itemIcon.setIcon(new ImageIcon(itemImage));
|
||||
|
||||
boolean buying = newOffer.getState() == GrandExchangeOfferState.BOUGHT
|
||||
|| newOffer.getState() == GrandExchangeOfferState.BUYING
|
||||
|| newOffer.getState() == GrandExchangeOfferState.CANCELLED_BUY;
|
||||
|
||||
String offerState = (buying ? "Bought " : "Sold ")
|
||||
+ StackFormatter.quantityToRSDecimalStack(newOffer.getQuantitySold()) + " / "
|
||||
+ StackFormatter.quantityToRSDecimalStack(newOffer.getTotalQuantity());
|
||||
|
||||
offerInfo.setText(offerState);
|
||||
|
||||
itemPrice.setText(htmlLabel("Price each: ", StackFormatter.formatNumber(newOffer.getPrice())));
|
||||
|
||||
String action = buying ? "Spent: " : "Received: ";
|
||||
|
||||
offerSpent.setText(htmlLabel(action, StackFormatter.formatNumber(newOffer.getSpent()) + " / "
|
||||
+ StackFormatter.formatNumber(newOffer.getPrice() * newOffer.getTotalQuantity())));
|
||||
|
||||
progressBar.setForeground(getProgressColor(newOffer));
|
||||
progressBar.setMaximumValue(newOffer.getTotalQuantity());
|
||||
progressBar.setValue(newOffer.getQuantitySold());
|
||||
|
||||
/* Couldn't set the tooltip for the container panel as the children override it, so I'm setting
|
||||
* the tooltips on the children instead. */
|
||||
for (Component c : container.getComponents())
|
||||
{
|
||||
if (c instanceof JPanel)
|
||||
{
|
||||
JPanel panel = (JPanel) c;
|
||||
panel.setToolTipText(htmlTooltip(((int) progressBar.getPercentage()) + "%"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private String htmlTooltip(String value)
|
||||
{
|
||||
return "<html><body style = 'color:" + ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR) + "'>Progress: <span style = 'color:white'>" + value + "</span></body></html>";
|
||||
}
|
||||
|
||||
private String htmlLabel(String key, String value)
|
||||
{
|
||||
return "<html><body style = 'color:white'>" + key + "<span style = 'color:" + ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR) + "'>" + value + "</span></body></html>";
|
||||
}
|
||||
|
||||
private void switchPanel()
|
||||
{
|
||||
this.showingFace = !this.showingFace;
|
||||
cardLayout.show(container, showingFace ? FACE_CARD : DETAILS_CARD);
|
||||
}
|
||||
|
||||
private Color getProgressColor(GrandExchangeOffer offer)
|
||||
{
|
||||
if (offer.getState() == CANCELLED_BUY || offer.getState() == CANCELLED_SELL)
|
||||
{
|
||||
return ColorScheme.PROGRESS_ERROR_COLOR;
|
||||
}
|
||||
|
||||
if (offer.getQuantitySold() == offer.getTotalQuantity())
|
||||
{
|
||||
return ColorScheme.PROGRESS_COMPLETE_COLOR;
|
||||
}
|
||||
|
||||
return ColorScheme.PROGRESS_INPROGRESS_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,497 +1,497 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2017, Robbie <https://github.com/rbbi>
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* 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.grandexchange;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GrandExchangeOfferChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.account.AccountSession;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
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 net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.ge.GrandExchangeClient;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Grand Exchange",
|
||||
description = "Provide additional and/or easier access to Grand Exchange information",
|
||||
tags = {"external", "integration", "notifications", "panel", "prices", "trade"}
|
||||
)
|
||||
@Slf4j
|
||||
public class GrandExchangePlugin extends Plugin
|
||||
{
|
||||
private static final int OFFER_CONTAINER_ITEM = 21;
|
||||
private static final int OFFER_DEFAULT_ITEM_ID = 6512;
|
||||
private static final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient();
|
||||
private static final String OSB_GE_TEXT = "<br>OSBuddy Actively traded price: ";
|
||||
|
||||
private static final String BUY_LIMIT_GE_TEXT = "<br>Buy limit: ";
|
||||
private static final Gson GSON = new Gson();
|
||||
private static final TypeToken<Map<Integer, Integer>> BUY_LIMIT_TOKEN = new TypeToken<Map<Integer, Integer>>()
|
||||
{
|
||||
};
|
||||
|
||||
static final String SEARCH_GRAND_EXCHANGE = "Search Grand Exchange";
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private NavigationButton button;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private GrandExchangePanel panel;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean hotKeyPressed;
|
||||
|
||||
@Inject
|
||||
private GrandExchangeInputListener inputListener;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@Inject
|
||||
private GrandExchangeConfig config;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@Inject
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
private Widget grandExchangeText;
|
||||
private Widget grandExchangeItem;
|
||||
private Map<Integer, Integer> itemGELimits;
|
||||
|
||||
private GrandExchangeClient grandExchangeClient;
|
||||
|
||||
private SavedOffer getOffer(int slot)
|
||||
{
|
||||
String offer = configManager.getConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot));
|
||||
if (offer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GSON.fromJson(offer, SavedOffer.class);
|
||||
}
|
||||
|
||||
private void setOffer(int slot, SavedOffer offer)
|
||||
{
|
||||
configManager.setConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot), GSON.toJson(offer));
|
||||
}
|
||||
|
||||
private void deleteOffer(int slot)
|
||||
{
|
||||
configManager.unsetConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot));
|
||||
}
|
||||
|
||||
@Provides
|
||||
GrandExchangeConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(GrandExchangeConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
itemGELimits = loadGELimits();
|
||||
panel = injector.getInstance(GrandExchangePanel.class);
|
||||
panel.setGELimits(itemGELimits);
|
||||
|
||||
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "ge_icon.png");
|
||||
|
||||
button = NavigationButton.builder()
|
||||
.tooltip("Grand Exchange")
|
||||
.icon(icon)
|
||||
.priority(3)
|
||||
.panel(panel)
|
||||
.build();
|
||||
|
||||
clientToolbar.addNavigation(button);
|
||||
|
||||
if (config.quickLookup())
|
||||
{
|
||||
mouseManager.registerMouseListener(inputListener);
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
}
|
||||
|
||||
AccountSession accountSession = sessionManager.getAccountSession();
|
||||
if (accountSession != null)
|
||||
{
|
||||
grandExchangeClient = new GrandExchangeClient(accountSession.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
clientToolbar.removeNavigation(button);
|
||||
mouseManager.unregisterMouseListener(inputListener);
|
||||
keyManager.unregisterKeyListener(inputListener);
|
||||
grandExchangeText = null;
|
||||
grandExchangeItem = null;
|
||||
itemGELimits = null;
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionOpen(SessionOpen sessionOpen)
|
||||
{
|
||||
AccountSession accountSession = sessionManager.getAccountSession();
|
||||
if (accountSession.getUuid() != null)
|
||||
{
|
||||
grandExchangeClient = new GrandExchangeClient(accountSession.getUuid());
|
||||
}
|
||||
else
|
||||
{
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionClose(SessionClose sessionClose)
|
||||
{
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("grandexchange"))
|
||||
{
|
||||
if (event.getKey().equals("quickLookup"))
|
||||
{
|
||||
if (config.quickLookup())
|
||||
{
|
||||
mouseManager.registerMouseListener(inputListener);
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseManager.unregisterMouseListener(inputListener);
|
||||
keyManager.unregisterKeyListener(inputListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent)
|
||||
{
|
||||
final int slot = offerEvent.getSlot();
|
||||
final GrandExchangeOffer offer = offerEvent.getOffer();
|
||||
|
||||
ItemComposition offerItem = itemManager.getItemComposition(offer.getItemId());
|
||||
boolean shouldStack = offerItem.isStackable() || offer.getTotalQuantity() > 1;
|
||||
BufferedImage itemImage = itemManager.getImage(offer.getItemId(), offer.getTotalQuantity(), shouldStack);
|
||||
SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offer, slot));
|
||||
|
||||
submitTrades(slot, offer);
|
||||
|
||||
updateConfig(slot, offer);
|
||||
}
|
||||
|
||||
private void submitTrades(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (grandExchangeClient == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only interested in offers which are fully bought/sold
|
||||
if (offer.getState() != GrandExchangeOfferState.BOUGHT && offer.getState() != GrandExchangeOfferState.SOLD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SavedOffer savedOffer = getOffer(slot);
|
||||
if (!shouldUpdate(savedOffer, offer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// getPrice() is the price of the offer, not necessarily what the item bought at
|
||||
int priceEach = offer.getSpent() / offer.getTotalQuantity();
|
||||
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(offer.getState() == GrandExchangeOfferState.BOUGHT);
|
||||
grandExchangeTrade.setItemId(offer.getItemId());
|
||||
grandExchangeTrade.setQuantity(offer.getTotalQuantity());
|
||||
grandExchangeTrade.setPrice(priceEach);
|
||||
|
||||
log.debug("Submitting trade: {}", grandExchangeTrade);
|
||||
grandExchangeClient.submit(grandExchangeTrade);
|
||||
}
|
||||
|
||||
private void updateConfig(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (offer.getState() == GrandExchangeOfferState.EMPTY)
|
||||
{
|
||||
deleteOffer(slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(offer.getItemId());
|
||||
savedOffer.setQuantitySold(offer.getQuantitySold());
|
||||
savedOffer.setTotalQuantity(offer.getTotalQuantity());
|
||||
savedOffer.setPrice(offer.getPrice());
|
||||
savedOffer.setSpent(offer.getSpent());
|
||||
savedOffer.setState(offer.getState());
|
||||
setOffer(slot, savedOffer);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldUpdate(SavedOffer savedOffer, GrandExchangeOffer grandExchangeOffer)
|
||||
{
|
||||
if (savedOffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only update offer if state has changed
|
||||
return savedOffer.getState() != grandExchangeOffer.getState();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (!this.config.enableNotifications() || event.getType() != ChatMessageType.GAMEMESSAGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String message = Text.removeTags(event.getMessage());
|
||||
|
||||
if (message.startsWith("Grand Exchange:"))
|
||||
{
|
||||
this.notifier.notify(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
panel.getOffersPanel().resetOffers();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
// At the moment, if the user disables quick lookup, the input listener gets disabled. Thus, isHotKeyPressed()
|
||||
// should always return false when quick lookup is disabled.
|
||||
// Replace the default option with "Search ..." when holding alt
|
||||
if (client.getGameState() != GameState.LOGGED_IN || !hotKeyPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final MenuEntry[] entries = client.getMenuEntries();
|
||||
final MenuEntry menuEntry = entries[entries.length - 1];
|
||||
final int widgetId = menuEntry.getParam1();
|
||||
final int groupId = WidgetInfo.TO_GROUP(widgetId);
|
||||
|
||||
switch (groupId)
|
||||
{
|
||||
case WidgetID.BANK_GROUP_ID:
|
||||
// Don't show for view tabs and such
|
||||
if (WidgetInfo.TO_CHILD(widgetId) != WidgetInfo.BANK_ITEM_CONTAINER.getChildId())
|
||||
{
|
||||
break;
|
||||
}
|
||||
case WidgetID.INVENTORY_GROUP_ID:
|
||||
case WidgetID.BANK_INVENTORY_GROUP_ID:
|
||||
case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID:
|
||||
case WidgetID.SHOP_INVENTORY_GROUP_ID:
|
||||
menuEntry.setOption(SEARCH_GRAND_EXCHANGE);
|
||||
menuEntry.setType(MenuAction.RUNELITE.getId());
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onFocusChanged(FocusChanged focusChanged)
|
||||
{
|
||||
if (!focusChanged.isFocused())
|
||||
{
|
||||
setHotKeyPressed(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
switch (event.getGroupId())
|
||||
{
|
||||
// Grand exchange was opened.
|
||||
case WidgetID.GRAND_EXCHANGE_GROUP_ID:
|
||||
Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER);
|
||||
grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT);
|
||||
grandExchangeItem = grandExchangeOffer.getDynamicChildren()[OFFER_CONTAINER_ITEM];
|
||||
break;
|
||||
// Grand exchange was closed (if it was open before).
|
||||
case WidgetID.INVENTORY_GROUP_ID:
|
||||
grandExchangeText = null;
|
||||
grandExchangeItem = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (grandExchangeText == null || grandExchangeItem == null || grandExchangeItem.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget geText = grandExchangeText;
|
||||
final String geTextString = geText.getText();
|
||||
final int itemId = grandExchangeItem.getItemId();
|
||||
|
||||
if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1)
|
||||
{
|
||||
// This item is invalid/nothing has been searched for
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.enableGELimits() && itemGELimits != null && !geTextString.contains(BUY_LIMIT_GE_TEXT))
|
||||
{
|
||||
final Integer itemLimit = itemGELimits.get(itemId);
|
||||
|
||||
// If we have item buy limit, append it
|
||||
if (itemLimit != null)
|
||||
{
|
||||
final String text = geText.getText() + BUY_LIMIT_GE_TEXT + StackFormatter.formatNumber(itemLimit);
|
||||
geText.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.enableOsbPrices() || geTextString.contains(OSB_GE_TEXT))
|
||||
{
|
||||
// OSB prices are disabled or price was already looked up, so no need to set it again
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Looking up OSB item price {}", itemId);
|
||||
|
||||
executorService.submit(() ->
|
||||
{
|
||||
if (geText.getText().contains(OSB_GE_TEXT))
|
||||
{
|
||||
// If there are multiple tasks queued and one of them have already added the price
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final OSBGrandExchangeResult result = CLIENT.lookupItem(itemId);
|
||||
final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(result.getOverall_average());
|
||||
geText.setText(text);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.debug("Error getting price of item {}", itemId, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<Integer, Integer> loadGELimits()
|
||||
{
|
||||
final InputStream geLimitData = GrandExchangePlugin.class.getResourceAsStream("ge_limits.json");
|
||||
final Map<Integer, Integer> itemGELimits = GSON.fromJson(new InputStreamReader(geLimitData), BUY_LIMIT_TOKEN.getType());
|
||||
log.debug("Loaded {} limits", itemGELimits.size());
|
||||
return itemGELimits;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2017, Robbie <https://github.com/rbbi>
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* 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.grandexchange;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GrandExchangeOfferChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.account.AccountSession;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
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 net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.ge.GrandExchangeClient;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Grand Exchange",
|
||||
description = "Provide additional and/or easier access to Grand Exchange information",
|
||||
tags = {"external", "integration", "notifications", "panel", "prices", "trade"}
|
||||
)
|
||||
@Slf4j
|
||||
public class GrandExchangePlugin extends Plugin
|
||||
{
|
||||
private static final int OFFER_CONTAINER_ITEM = 21;
|
||||
private static final int OFFER_DEFAULT_ITEM_ID = 6512;
|
||||
private static final OSBGrandExchangeClient CLIENT = new OSBGrandExchangeClient();
|
||||
private static final String OSB_GE_TEXT = "<br>OSBuddy Actively traded price: ";
|
||||
|
||||
private static final String BUY_LIMIT_GE_TEXT = "<br>Buy limit: ";
|
||||
private static final Gson GSON = new Gson();
|
||||
private static final TypeToken<Map<Integer, Integer>> BUY_LIMIT_TOKEN = new TypeToken<Map<Integer, Integer>>()
|
||||
{
|
||||
};
|
||||
|
||||
static final String SEARCH_GRAND_EXCHANGE = "Search Grand Exchange";
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private NavigationButton button;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private GrandExchangePanel panel;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean hotKeyPressed;
|
||||
|
||||
@Inject
|
||||
private GrandExchangeInputListener inputListener;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@Inject
|
||||
private GrandExchangeConfig config;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@Inject
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
private Widget grandExchangeText;
|
||||
private Widget grandExchangeItem;
|
||||
private Map<Integer, Integer> itemGELimits;
|
||||
|
||||
private GrandExchangeClient grandExchangeClient;
|
||||
|
||||
private SavedOffer getOffer(int slot)
|
||||
{
|
||||
String offer = configManager.getConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot));
|
||||
if (offer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GSON.fromJson(offer, SavedOffer.class);
|
||||
}
|
||||
|
||||
private void setOffer(int slot, SavedOffer offer)
|
||||
{
|
||||
configManager.setConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot), GSON.toJson(offer));
|
||||
}
|
||||
|
||||
private void deleteOffer(int slot)
|
||||
{
|
||||
configManager.unsetConfiguration("geoffer." + client.getUsername().toLowerCase(), Integer.toString(slot));
|
||||
}
|
||||
|
||||
@Provides
|
||||
GrandExchangeConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(GrandExchangeConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
itemGELimits = loadGELimits();
|
||||
panel = injector.getInstance(GrandExchangePanel.class);
|
||||
panel.setGELimits(itemGELimits);
|
||||
|
||||
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "ge_icon.png");
|
||||
|
||||
button = NavigationButton.builder()
|
||||
.tooltip("Grand Exchange")
|
||||
.icon(icon)
|
||||
.priority(3)
|
||||
.panel(panel)
|
||||
.build();
|
||||
|
||||
clientToolbar.addNavigation(button);
|
||||
|
||||
if (config.quickLookup())
|
||||
{
|
||||
mouseManager.registerMouseListener(inputListener);
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
}
|
||||
|
||||
AccountSession accountSession = sessionManager.getAccountSession();
|
||||
if (accountSession != null)
|
||||
{
|
||||
grandExchangeClient = new GrandExchangeClient(accountSession.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
clientToolbar.removeNavigation(button);
|
||||
mouseManager.unregisterMouseListener(inputListener);
|
||||
keyManager.unregisterKeyListener(inputListener);
|
||||
grandExchangeText = null;
|
||||
grandExchangeItem = null;
|
||||
itemGELimits = null;
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionOpen(SessionOpen sessionOpen)
|
||||
{
|
||||
AccountSession accountSession = sessionManager.getAccountSession();
|
||||
if (accountSession.getUuid() != null)
|
||||
{
|
||||
grandExchangeClient = new GrandExchangeClient(accountSession.getUuid());
|
||||
}
|
||||
else
|
||||
{
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSessionClose(SessionClose sessionClose)
|
||||
{
|
||||
grandExchangeClient = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("grandexchange"))
|
||||
{
|
||||
if (event.getKey().equals("quickLookup"))
|
||||
{
|
||||
if (config.quickLookup())
|
||||
{
|
||||
mouseManager.registerMouseListener(inputListener);
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseManager.unregisterMouseListener(inputListener);
|
||||
keyManager.unregisterKeyListener(inputListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent)
|
||||
{
|
||||
final int slot = offerEvent.getSlot();
|
||||
final GrandExchangeOffer offer = offerEvent.getOffer();
|
||||
|
||||
ItemComposition offerItem = itemManager.getItemComposition(offer.getItemId());
|
||||
boolean shouldStack = offerItem.isStackable() || offer.getTotalQuantity() > 1;
|
||||
BufferedImage itemImage = itemManager.getImage(offer.getItemId(), offer.getTotalQuantity(), shouldStack);
|
||||
SwingUtilities.invokeLater(() -> panel.getOffersPanel().updateOffer(offerItem, itemImage, offer, slot));
|
||||
|
||||
submitTrades(slot, offer);
|
||||
|
||||
updateConfig(slot, offer);
|
||||
}
|
||||
|
||||
private void submitTrades(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (grandExchangeClient == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only interested in offers which are fully bought/sold
|
||||
if (offer.getState() != GrandExchangeOfferState.BOUGHT && offer.getState() != GrandExchangeOfferState.SOLD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SavedOffer savedOffer = getOffer(slot);
|
||||
if (!shouldUpdate(savedOffer, offer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// getPrice() is the price of the offer, not necessarily what the item bought at
|
||||
int priceEach = offer.getSpent() / offer.getTotalQuantity();
|
||||
|
||||
GrandExchangeTrade grandExchangeTrade = new GrandExchangeTrade();
|
||||
grandExchangeTrade.setBuy(offer.getState() == GrandExchangeOfferState.BOUGHT);
|
||||
grandExchangeTrade.setItemId(offer.getItemId());
|
||||
grandExchangeTrade.setQuantity(offer.getTotalQuantity());
|
||||
grandExchangeTrade.setPrice(priceEach);
|
||||
|
||||
log.debug("Submitting trade: {}", grandExchangeTrade);
|
||||
grandExchangeClient.submit(grandExchangeTrade);
|
||||
}
|
||||
|
||||
private void updateConfig(int slot, GrandExchangeOffer offer)
|
||||
{
|
||||
if (offer.getState() == GrandExchangeOfferState.EMPTY)
|
||||
{
|
||||
deleteOffer(slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(offer.getItemId());
|
||||
savedOffer.setQuantitySold(offer.getQuantitySold());
|
||||
savedOffer.setTotalQuantity(offer.getTotalQuantity());
|
||||
savedOffer.setPrice(offer.getPrice());
|
||||
savedOffer.setSpent(offer.getSpent());
|
||||
savedOffer.setState(offer.getState());
|
||||
setOffer(slot, savedOffer);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldUpdate(SavedOffer savedOffer, GrandExchangeOffer grandExchangeOffer)
|
||||
{
|
||||
if (savedOffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only update offer if state has changed
|
||||
return savedOffer.getState() != grandExchangeOffer.getState();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (!this.config.enableNotifications() || event.getType() != ChatMessageType.GAMEMESSAGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String message = Text.removeTags(event.getMessage());
|
||||
|
||||
if (message.startsWith("Grand Exchange:"))
|
||||
{
|
||||
this.notifier.notify(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
panel.getOffersPanel().resetOffers();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
// At the moment, if the user disables quick lookup, the input listener gets disabled. Thus, isHotKeyPressed()
|
||||
// should always return false when quick lookup is disabled.
|
||||
// Replace the default option with "Search ..." when holding alt
|
||||
if (client.getGameState() != GameState.LOGGED_IN || !hotKeyPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final MenuEntry[] entries = client.getMenuEntries();
|
||||
final MenuEntry menuEntry = entries[entries.length - 1];
|
||||
final int widgetId = menuEntry.getParam1();
|
||||
final int groupId = WidgetInfo.TO_GROUP(widgetId);
|
||||
|
||||
switch (groupId)
|
||||
{
|
||||
case WidgetID.BANK_GROUP_ID:
|
||||
// Don't show for view tabs and such
|
||||
if (WidgetInfo.TO_CHILD(widgetId) != WidgetInfo.BANK_ITEM_CONTAINER.getChildId())
|
||||
{
|
||||
break;
|
||||
}
|
||||
case WidgetID.INVENTORY_GROUP_ID:
|
||||
case WidgetID.BANK_INVENTORY_GROUP_ID:
|
||||
case WidgetID.GRAND_EXCHANGE_INVENTORY_GROUP_ID:
|
||||
case WidgetID.SHOP_INVENTORY_GROUP_ID:
|
||||
menuEntry.setOption(SEARCH_GRAND_EXCHANGE);
|
||||
menuEntry.setType(MenuAction.RUNELITE.getId());
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onFocusChanged(FocusChanged focusChanged)
|
||||
{
|
||||
if (!focusChanged.isFocused())
|
||||
{
|
||||
setHotKeyPressed(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
switch (event.getGroupId())
|
||||
{
|
||||
// Grand exchange was opened.
|
||||
case WidgetID.GRAND_EXCHANGE_GROUP_ID:
|
||||
Widget grandExchangeOffer = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_CONTAINER);
|
||||
grandExchangeText = client.getWidget(WidgetInfo.GRAND_EXCHANGE_OFFER_TEXT);
|
||||
grandExchangeItem = grandExchangeOffer.getDynamicChildren()[OFFER_CONTAINER_ITEM];
|
||||
break;
|
||||
// Grand exchange was closed (if it was open before).
|
||||
case WidgetID.INVENTORY_GROUP_ID:
|
||||
grandExchangeText = null;
|
||||
grandExchangeItem = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (grandExchangeText == null || grandExchangeItem == null || grandExchangeItem.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget geText = grandExchangeText;
|
||||
final String geTextString = geText.getText();
|
||||
final int itemId = grandExchangeItem.getItemId();
|
||||
|
||||
if (itemId == OFFER_DEFAULT_ITEM_ID || itemId == -1)
|
||||
{
|
||||
// This item is invalid/nothing has been searched for
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.enableGELimits() && itemGELimits != null && !geTextString.contains(BUY_LIMIT_GE_TEXT))
|
||||
{
|
||||
final Integer itemLimit = itemGELimits.get(itemId);
|
||||
|
||||
// If we have item buy limit, append it
|
||||
if (itemLimit != null)
|
||||
{
|
||||
final String text = geText.getText() + BUY_LIMIT_GE_TEXT + StackFormatter.formatNumber(itemLimit);
|
||||
geText.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.enableOsbPrices() || geTextString.contains(OSB_GE_TEXT))
|
||||
{
|
||||
// OSB prices are disabled or price was already looked up, so no need to set it again
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Looking up OSB item price {}", itemId);
|
||||
|
||||
executorService.submit(() ->
|
||||
{
|
||||
if (geText.getText().contains(OSB_GE_TEXT))
|
||||
{
|
||||
// If there are multiple tasks queued and one of them have already added the price
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final OSBGrandExchangeResult result = CLIENT.lookupItem(itemId);
|
||||
final String text = geText.getText() + OSB_GE_TEXT + StackFormatter.formatNumber(result.getOverall_average());
|
||||
geText.setText(text);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.debug("Error getting price of item {}", itemId, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<Integer, Integer> loadGELimits()
|
||||
{
|
||||
final InputStream geLimitData = GrandExchangePlugin.class.getResourceAsStream("ge_limits.json");
|
||||
final Map<Integer, Integer> itemGELimits = GSON.fromJson(new InputStreamReader(geLimitData), BUY_LIMIT_TOKEN.getType());
|
||||
log.debug("Loaded {} limits", itemGELimits.size());
|
||||
return itemGELimits;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Damen <https://github.com/basicDamen>
|
||||
* 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.grotesqueguardians;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Grotesque Guardians",
|
||||
description = "Display tile indicators for the Grotesque Guardian special attacks",
|
||||
tags = {"grotesque", "guardians", "gargoyle", "garg"},
|
||||
type = PluginType.PVM
|
||||
)
|
||||
public class GrotesqueGuardiansPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private GrotesqueGuardiansOverlay overlay;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Damen <https://github.com/basicDamen>
|
||||
* 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.grotesqueguardians;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Grotesque Guardians",
|
||||
description = "Display tile indicators for the Grotesque Guardian special attacks",
|
||||
tags = {"grotesque", "guardians", "gargoyle", "garg"},
|
||||
type = PluginType.PVM
|
||||
)
|
||||
public class GrotesqueGuardiansPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private GrotesqueGuardiansOverlay overlay;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,383 +1,383 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||
* 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;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
|
||||
import net.runelite.client.plugins.grounditems.config.ValueCalculationMode;
|
||||
|
||||
@ConfigGroup("grounditems")
|
||||
public interface GroundItemsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "highlightedItems",
|
||||
name = "Highlighted Items",
|
||||
description = "Configures specifically highlighted ground items. Format: (item), (item)",
|
||||
position = 0
|
||||
)
|
||||
default String getHighlightItems()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightedItems",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void setHighlightedItem(String key);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hiddenItems",
|
||||
name = "Hidden Items",
|
||||
description = "Configures hidden ground items. Format: (item), (item)",
|
||||
position = 1
|
||||
)
|
||||
default String getHiddenItems()
|
||||
{
|
||||
return "Vial, Ashes, Coins, Bones, Bucket, Jug, Seaweed";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hiddenItems",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void setHiddenItems(String key);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHighlightedOnly",
|
||||
name = "Show Highlighted items only",
|
||||
description = "Configures whether or not to draw items only on your highlighted list",
|
||||
position = 2
|
||||
)
|
||||
default boolean showHighlightedOnly()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "dontHideUntradeables",
|
||||
name = "Do not hide untradeables",
|
||||
description = "Configures whether or not untradeable items ignore hiding under settings",
|
||||
position = 3
|
||||
)
|
||||
default boolean dontHideUntradeables()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showMenuItemQuantities",
|
||||
name = "Show Menu Item Quantities",
|
||||
description = "Configures whether or not to show the item quantities in the menu",
|
||||
position = 4
|
||||
)
|
||||
default boolean showMenuItemQuantities()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "recolorMenuHiddenItems",
|
||||
name = "Recolor Menu Hidden Items",
|
||||
description = "Configures whether or not hidden items in right click menu will be recolored",
|
||||
position = 5
|
||||
)
|
||||
default boolean recolorMenuHiddenItems()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightTiles",
|
||||
name = "Highlight Tiles",
|
||||
description = "Configures whether or not to highlight tiles containing ground items",
|
||||
position = 6
|
||||
)
|
||||
default boolean highlightTiles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notifyHighlightedDrops",
|
||||
name = "Notify for Highlighted drops",
|
||||
description = "Configures whether or not to notify for drops on your highlighted list",
|
||||
position = 7
|
||||
)
|
||||
default boolean notifyHighlightedDrops()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "priceDisplayMode",
|
||||
name = "Price Display Mode",
|
||||
description = "Configures what price types are shown alongside of ground item name",
|
||||
position = 8
|
||||
)
|
||||
default PriceDisplayMode priceDisplayMode()
|
||||
{
|
||||
return PriceDisplayMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "itemHighlightMode",
|
||||
name = "Item Highlight Mode",
|
||||
description = "Configures how ground items will be highlighted",
|
||||
position = 9
|
||||
)
|
||||
default ItemHighlightMode itemHighlightMode()
|
||||
{
|
||||
return ItemHighlightMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "menuHighlightMode",
|
||||
name = "Menu Highlight Mode",
|
||||
description = "Configures what to highlight in right-click menu",
|
||||
position = 10
|
||||
)
|
||||
default MenuHighlightMode menuHighlightMode()
|
||||
{
|
||||
return MenuHighlightMode.NAME;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightValueCalculation",
|
||||
name = "Highlight Value Calculation",
|
||||
description = "Configures which coin value is used to determine highlight color",
|
||||
position = 11
|
||||
)
|
||||
default ValueCalculationMode valueCalculationMode()
|
||||
{
|
||||
return ValueCalculationMode.HIGHEST;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightOverValue2",
|
||||
name = "Highlight > Value",
|
||||
description = "Configures highlighted ground items over either GE or HA value",
|
||||
position = 12
|
||||
)
|
||||
default int getHighlightOverValue()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideUnderValue",
|
||||
name = "Hide < Value",
|
||||
description = "Configures hidden ground items under both GE and HA value",
|
||||
position = 13
|
||||
)
|
||||
default int getHideUnderValue()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "defaultColor",
|
||||
name = "Default items color",
|
||||
description = "Configures the color for default, non-highlighted items",
|
||||
position = 14
|
||||
)
|
||||
default Color defaultColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightedColor",
|
||||
name = "Highlighted items color",
|
||||
description = "Configures the color for highlighted items",
|
||||
position = 15
|
||||
)
|
||||
default Color highlightedColor()
|
||||
{
|
||||
return Color.decode("#AA00FF");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hiddenColor",
|
||||
name = "Hidden items color",
|
||||
description = "Configures the color for hidden items in right-click menu and when holding ALT",
|
||||
position = 16
|
||||
)
|
||||
default Color hiddenColor()
|
||||
{
|
||||
return Color.GRAY;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lowValueColor",
|
||||
name = "Low value items color",
|
||||
description = "Configures the color for low value items",
|
||||
position = 17
|
||||
)
|
||||
default Color lowValueColor()
|
||||
{
|
||||
return Color.decode("#66B2FF");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lowValuePrice",
|
||||
name = "Low value price",
|
||||
description = "Configures the start price for low value items",
|
||||
position = 18
|
||||
)
|
||||
default int lowValuePrice()
|
||||
{
|
||||
return 20000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "mediumValueColor",
|
||||
name = "Medium value items color",
|
||||
description = "Configures the color for medium value items",
|
||||
position = 19
|
||||
)
|
||||
default Color mediumValueColor()
|
||||
{
|
||||
return Color.decode("#99FF99");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "mediumValuePrice",
|
||||
name = "Medium value price",
|
||||
description = "Configures the start price for medium value items",
|
||||
position = 20
|
||||
)
|
||||
default int mediumValuePrice()
|
||||
{
|
||||
return 100000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highValueColor",
|
||||
name = "High value items color",
|
||||
description = "Configures the color for high value items",
|
||||
position = 21
|
||||
)
|
||||
default Color highValueColor()
|
||||
{
|
||||
return Color.decode("#FF9600");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highValuePrice",
|
||||
name = "High value price",
|
||||
description = "Configures the start price for high value items",
|
||||
position = 22
|
||||
)
|
||||
default int highValuePrice()
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "insaneValueColor",
|
||||
name = "Insane value items color",
|
||||
description = "Configures the color for insane value items",
|
||||
position = 23
|
||||
)
|
||||
default Color insaneValueColor()
|
||||
{
|
||||
return Color.decode("#FF66B2");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "insaneValuePrice",
|
||||
name = "Insane value price",
|
||||
description = "Configures the start price for insane value items",
|
||||
position = 24
|
||||
)
|
||||
default int insaneValuePrice()
|
||||
{
|
||||
return 10000000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "onlyShowLoot",
|
||||
name = "Only show loot",
|
||||
description = "Only shows drops from NPCs and players",
|
||||
position = 25
|
||||
)
|
||||
default boolean onlyShowLoot()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "doubleTapDelay",
|
||||
name = "Delay for double-tap ALT to hide",
|
||||
description = "Decrease this number if you accidentally hide ground items often. (0 = Disabled)",
|
||||
position = 26
|
||||
)
|
||||
default int doubleTapDelay()
|
||||
{
|
||||
return 250;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "collapseEntries",
|
||||
name = "Collapse ground item menu entries",
|
||||
description = "Collapses ground item menu entries together and appends count",
|
||||
position = 27
|
||||
)
|
||||
default boolean collapseEntries()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 27,
|
||||
keyName = "removeIgnored",
|
||||
name = "Hide Ignored",
|
||||
description = "Remove take option for items that are on the hidden items list."
|
||||
)
|
||||
default boolean removeIgnored()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "toggleOutline",
|
||||
name = "Text Outline",
|
||||
description = "Use an outline around text instead of a text shadow",
|
||||
position = 29
|
||||
)
|
||||
default boolean toggleOutline()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||
* 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;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
|
||||
import net.runelite.client.plugins.grounditems.config.ValueCalculationMode;
|
||||
|
||||
@ConfigGroup("grounditems")
|
||||
public interface GroundItemsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "highlightedItems",
|
||||
name = "Highlighted Items",
|
||||
description = "Configures specifically highlighted ground items. Format: (item), (item)",
|
||||
position = 0
|
||||
)
|
||||
default String getHighlightItems()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightedItems",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void setHighlightedItem(String key);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hiddenItems",
|
||||
name = "Hidden Items",
|
||||
description = "Configures hidden ground items. Format: (item), (item)",
|
||||
position = 1
|
||||
)
|
||||
default String getHiddenItems()
|
||||
{
|
||||
return "Vial, Ashes, Coins, Bones, Bucket, Jug, Seaweed";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hiddenItems",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void setHiddenItems(String key);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHighlightedOnly",
|
||||
name = "Show Highlighted items only",
|
||||
description = "Configures whether or not to draw items only on your highlighted list",
|
||||
position = 2
|
||||
)
|
||||
default boolean showHighlightedOnly()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "dontHideUntradeables",
|
||||
name = "Do not hide untradeables",
|
||||
description = "Configures whether or not untradeable items ignore hiding under settings",
|
||||
position = 3
|
||||
)
|
||||
default boolean dontHideUntradeables()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showMenuItemQuantities",
|
||||
name = "Show Menu Item Quantities",
|
||||
description = "Configures whether or not to show the item quantities in the menu",
|
||||
position = 4
|
||||
)
|
||||
default boolean showMenuItemQuantities()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "recolorMenuHiddenItems",
|
||||
name = "Recolor Menu Hidden Items",
|
||||
description = "Configures whether or not hidden items in right click menu will be recolored",
|
||||
position = 5
|
||||
)
|
||||
default boolean recolorMenuHiddenItems()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightTiles",
|
||||
name = "Highlight Tiles",
|
||||
description = "Configures whether or not to highlight tiles containing ground items",
|
||||
position = 6
|
||||
)
|
||||
default boolean highlightTiles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notifyHighlightedDrops",
|
||||
name = "Notify for Highlighted drops",
|
||||
description = "Configures whether or not to notify for drops on your highlighted list",
|
||||
position = 7
|
||||
)
|
||||
default boolean notifyHighlightedDrops()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "priceDisplayMode",
|
||||
name = "Price Display Mode",
|
||||
description = "Configures what price types are shown alongside of ground item name",
|
||||
position = 8
|
||||
)
|
||||
default PriceDisplayMode priceDisplayMode()
|
||||
{
|
||||
return PriceDisplayMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "itemHighlightMode",
|
||||
name = "Item Highlight Mode",
|
||||
description = "Configures how ground items will be highlighted",
|
||||
position = 9
|
||||
)
|
||||
default ItemHighlightMode itemHighlightMode()
|
||||
{
|
||||
return ItemHighlightMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "menuHighlightMode",
|
||||
name = "Menu Highlight Mode",
|
||||
description = "Configures what to highlight in right-click menu",
|
||||
position = 10
|
||||
)
|
||||
default MenuHighlightMode menuHighlightMode()
|
||||
{
|
||||
return MenuHighlightMode.NAME;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightValueCalculation",
|
||||
name = "Highlight Value Calculation",
|
||||
description = "Configures which coin value is used to determine highlight color",
|
||||
position = 11
|
||||
)
|
||||
default ValueCalculationMode valueCalculationMode()
|
||||
{
|
||||
return ValueCalculationMode.HIGHEST;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightOverValue2",
|
||||
name = "Highlight > Value",
|
||||
description = "Configures highlighted ground items over either GE or HA value",
|
||||
position = 12
|
||||
)
|
||||
default int getHighlightOverValue()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideUnderValue",
|
||||
name = "Hide < Value",
|
||||
description = "Configures hidden ground items under both GE and HA value",
|
||||
position = 13
|
||||
)
|
||||
default int getHideUnderValue()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "defaultColor",
|
||||
name = "Default items color",
|
||||
description = "Configures the color for default, non-highlighted items",
|
||||
position = 14
|
||||
)
|
||||
default Color defaultColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightedColor",
|
||||
name = "Highlighted items color",
|
||||
description = "Configures the color for highlighted items",
|
||||
position = 15
|
||||
)
|
||||
default Color highlightedColor()
|
||||
{
|
||||
return Color.decode("#AA00FF");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hiddenColor",
|
||||
name = "Hidden items color",
|
||||
description = "Configures the color for hidden items in right-click menu and when holding ALT",
|
||||
position = 16
|
||||
)
|
||||
default Color hiddenColor()
|
||||
{
|
||||
return Color.GRAY;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lowValueColor",
|
||||
name = "Low value items color",
|
||||
description = "Configures the color for low value items",
|
||||
position = 17
|
||||
)
|
||||
default Color lowValueColor()
|
||||
{
|
||||
return Color.decode("#66B2FF");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lowValuePrice",
|
||||
name = "Low value price",
|
||||
description = "Configures the start price for low value items",
|
||||
position = 18
|
||||
)
|
||||
default int lowValuePrice()
|
||||
{
|
||||
return 20000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "mediumValueColor",
|
||||
name = "Medium value items color",
|
||||
description = "Configures the color for medium value items",
|
||||
position = 19
|
||||
)
|
||||
default Color mediumValueColor()
|
||||
{
|
||||
return Color.decode("#99FF99");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "mediumValuePrice",
|
||||
name = "Medium value price",
|
||||
description = "Configures the start price for medium value items",
|
||||
position = 20
|
||||
)
|
||||
default int mediumValuePrice()
|
||||
{
|
||||
return 100000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highValueColor",
|
||||
name = "High value items color",
|
||||
description = "Configures the color for high value items",
|
||||
position = 21
|
||||
)
|
||||
default Color highValueColor()
|
||||
{
|
||||
return Color.decode("#FF9600");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highValuePrice",
|
||||
name = "High value price",
|
||||
description = "Configures the start price for high value items",
|
||||
position = 22
|
||||
)
|
||||
default int highValuePrice()
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "insaneValueColor",
|
||||
name = "Insane value items color",
|
||||
description = "Configures the color for insane value items",
|
||||
position = 23
|
||||
)
|
||||
default Color insaneValueColor()
|
||||
{
|
||||
return Color.decode("#FF66B2");
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "insaneValuePrice",
|
||||
name = "Insane value price",
|
||||
description = "Configures the start price for insane value items",
|
||||
position = 24
|
||||
)
|
||||
default int insaneValuePrice()
|
||||
{
|
||||
return 10000000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "onlyShowLoot",
|
||||
name = "Only show loot",
|
||||
description = "Only shows drops from NPCs and players",
|
||||
position = 25
|
||||
)
|
||||
default boolean onlyShowLoot()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "doubleTapDelay",
|
||||
name = "Delay for double-tap ALT to hide",
|
||||
description = "Decrease this number if you accidentally hide ground items often. (0 = Disabled)",
|
||||
position = 26
|
||||
)
|
||||
default int doubleTapDelay()
|
||||
{
|
||||
return 250;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "collapseEntries",
|
||||
name = "Collapse ground item menu entries",
|
||||
description = "Collapses ground item menu entries together and appends count",
|
||||
position = 27
|
||||
)
|
||||
default boolean collapseEntries()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 27,
|
||||
keyName = "removeIgnored",
|
||||
name = "Hide Ignored",
|
||||
description = "Remove take option for items that are on the hidden items list."
|
||||
)
|
||||
default boolean removeIgnored()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "toggleOutline",
|
||||
name = "Text Outline",
|
||||
description = "Use an outline around text instead of a text shadow",
|
||||
position = 29
|
||||
)
|
||||
default boolean toggleOutline()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user