more checkstyle etc
This commit is contained in:
@@ -79,7 +79,7 @@ public class ClientSessionManager
|
||||
}
|
||||
sessionId = null;
|
||||
}
|
||||
|
||||
|
||||
scheduledFuture.cancel(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public class Notifier
|
||||
// First check if we are running in launcher
|
||||
this.terminalNotifierAvailable =
|
||||
!Strings.isNullOrEmpty(RuneLiteProperties.getLauncherVersion())
|
||||
&& isTerminalNotifierAvailable();
|
||||
&& isTerminalNotifierAvailable();
|
||||
|
||||
storeIcon();
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginInstantiationException;
|
||||
import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.plugins.config.ConfigPanel;
|
||||
import net.runelite.client.rs.ClientUpdateCheckMode;
|
||||
import net.runelite.client.task.Scheduler;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
@@ -86,10 +85,10 @@ public class RuneLite
|
||||
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
||||
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
|
||||
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
|
||||
public static RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen();
|
||||
static final RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen();
|
||||
|
||||
|
||||
@Getter
|
||||
@Getter
|
||||
private static Injector injector;
|
||||
|
||||
@Inject
|
||||
@@ -242,7 +241,7 @@ public class RuneLite
|
||||
|
||||
// The submessage is shown in case the connection is slow
|
||||
splashScreen.setMessage("Starting RuneLite Injector");
|
||||
splashScreen.setSubMessage( " ");
|
||||
splashScreen.setSubMessage(" ");
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
|
||||
@@ -80,9 +80,12 @@ public class RuneLiteProperties
|
||||
|
||||
public String getDiscordAppId()
|
||||
{
|
||||
if (RuneLitePlusPlugin.customPresenceEnabled) {
|
||||
if (RuneLitePlusPlugin.customPresenceEnabled)
|
||||
{
|
||||
return properties.getProperty(RuneLitePlusPlugin.rlPlusDiscordApp);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return properties.getProperty(DISCORD_APP_ID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class SessionClient
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
ResponseBody body = response.body();
|
||||
|
||||
|
||||
InputStream in = body.byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), UUID.class);
|
||||
}
|
||||
|
||||
@@ -1,232 +1,232 @@
|
||||
/*
|
||||
* 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.account;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.util.LinkBrowser;
|
||||
import net.runelite.client.ws.WSClient;
|
||||
import net.runelite.http.api.account.AccountClient;
|
||||
import net.runelite.http.api.account.OAuthResponse;
|
||||
import net.runelite.http.api.ws.messages.LoginResponse;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class SessionManager
|
||||
{
|
||||
private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session");
|
||||
|
||||
@Getter
|
||||
private AccountSession accountSession;
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final ConfigManager configManager;
|
||||
private final WSClient wsClient;
|
||||
|
||||
@Inject
|
||||
private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
this.wsClient = wsClient;
|
||||
eventBus.register(this);
|
||||
}
|
||||
|
||||
public void loadSession()
|
||||
{
|
||||
if (!SESSION_FILE.exists())
|
||||
{
|
||||
log.info("No session file exists");
|
||||
return;
|
||||
}
|
||||
|
||||
AccountSession session;
|
||||
|
||||
try (FileInputStream in = new FileInputStream(SESSION_FILE))
|
||||
{
|
||||
session = new Gson().fromJson(new InputStreamReader(in), AccountSession.class);
|
||||
|
||||
log.debug("Loaded session for {}", session.getUsername());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn("Unable to load session file", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if session is still valid
|
||||
AccountClient accountClient = new AccountClient(session.getUuid());
|
||||
if (!accountClient.sesssionCheck())
|
||||
{
|
||||
log.debug("Loaded session {} is invalid", session.getUuid());
|
||||
return;
|
||||
}
|
||||
|
||||
openSession(session, false);
|
||||
}
|
||||
|
||||
private void saveSession()
|
||||
{
|
||||
if (accountSession == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try (FileWriter fw = new FileWriter(SESSION_FILE))
|
||||
{
|
||||
new Gson().toJson(accountSession, fw);
|
||||
|
||||
log.debug("Saved session to {}", SESSION_FILE);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Unable to save session file", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteSession()
|
||||
{
|
||||
SESSION_FILE.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given session as the active session and open a socket to the
|
||||
* server with the given session
|
||||
*
|
||||
* @param session session
|
||||
*/
|
||||
private void openSession(AccountSession session, boolean openSocket)
|
||||
{
|
||||
// Change session on the websocket
|
||||
if (openSocket)
|
||||
{
|
||||
wsClient.changeSession(session.getUuid());
|
||||
}
|
||||
|
||||
accountSession = session;
|
||||
|
||||
if (session.getUsername() != null)
|
||||
{
|
||||
// Initialize config for new session
|
||||
// If the session isn't logged in yet, don't switch to the new config
|
||||
configManager.switchSession(session);
|
||||
}
|
||||
|
||||
eventBus.post(new SessionOpen());
|
||||
}
|
||||
|
||||
private void closeSession()
|
||||
{
|
||||
wsClient.changeSession(null);
|
||||
|
||||
if (accountSession == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Logging out of account {}", accountSession.getUsername());
|
||||
|
||||
AccountClient client = new AccountClient(accountSession.getUuid());
|
||||
try
|
||||
{
|
||||
client.logout();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Unable to logout of session", ex);
|
||||
}
|
||||
|
||||
accountSession = null; // No more account
|
||||
|
||||
// Restore config
|
||||
configManager.switchSession(null);
|
||||
|
||||
eventBus.post(new SessionClose());
|
||||
}
|
||||
|
||||
public void login()
|
||||
{
|
||||
// If a session is already open, use that id. Otherwise generate a new id.
|
||||
UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID();
|
||||
AccountClient loginClient = new AccountClient(uuid);
|
||||
|
||||
final OAuthResponse login;
|
||||
|
||||
try
|
||||
{
|
||||
login = loginClient.login();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Unable to get oauth url", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new session
|
||||
openSession(new AccountSession(login.getUid(), Instant.now()), true);
|
||||
|
||||
// Navigate to login link
|
||||
LinkBrowser.browse(login.getOauthUrl());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onLoginResponse(LoginResponse loginResponse)
|
||||
{
|
||||
log.debug("Now logged in as {}", loginResponse.getUsername());
|
||||
|
||||
AccountSession session = getAccountSession();
|
||||
session.setUsername(loginResponse.getUsername());
|
||||
|
||||
// Open session, again, now that we have a username
|
||||
// This triggers onSessionOpen
|
||||
// The socket is already opened here anyway so we pass true for openSocket
|
||||
openSession(session, true);
|
||||
|
||||
// Save session to disk
|
||||
saveSession();
|
||||
}
|
||||
|
||||
public void logout()
|
||||
{
|
||||
closeSession();
|
||||
deleteSession();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.account;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.SessionClose;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.util.LinkBrowser;
|
||||
import net.runelite.client.ws.WSClient;
|
||||
import net.runelite.http.api.account.AccountClient;
|
||||
import net.runelite.http.api.account.OAuthResponse;
|
||||
import net.runelite.http.api.ws.messages.LoginResponse;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class SessionManager
|
||||
{
|
||||
private static final File SESSION_FILE = new File(RuneLite.RUNELITE_DIR, "session");
|
||||
|
||||
@Getter
|
||||
private AccountSession accountSession;
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final ConfigManager configManager;
|
||||
private final WSClient wsClient;
|
||||
|
||||
@Inject
|
||||
private SessionManager(ConfigManager configManager, EventBus eventBus, WSClient wsClient)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
this.wsClient = wsClient;
|
||||
eventBus.register(this);
|
||||
}
|
||||
|
||||
public void loadSession()
|
||||
{
|
||||
if (!SESSION_FILE.exists())
|
||||
{
|
||||
log.info("No session file exists");
|
||||
return;
|
||||
}
|
||||
|
||||
AccountSession session;
|
||||
|
||||
try (FileInputStream in = new FileInputStream(SESSION_FILE))
|
||||
{
|
||||
session = new Gson().fromJson(new InputStreamReader(in), AccountSession.class);
|
||||
|
||||
log.debug("Loaded session for {}", session.getUsername());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn("Unable to load session file", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if session is still valid
|
||||
AccountClient accountClient = new AccountClient(session.getUuid());
|
||||
if (!accountClient.sesssionCheck())
|
||||
{
|
||||
log.debug("Loaded session {} is invalid", session.getUuid());
|
||||
return;
|
||||
}
|
||||
|
||||
openSession(session, false);
|
||||
}
|
||||
|
||||
private void saveSession()
|
||||
{
|
||||
if (accountSession == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try (FileWriter fw = new FileWriter(SESSION_FILE))
|
||||
{
|
||||
new Gson().toJson(accountSession, fw);
|
||||
|
||||
log.debug("Saved session to {}", SESSION_FILE);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Unable to save session file", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteSession()
|
||||
{
|
||||
SESSION_FILE.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given session as the active session and open a socket to the
|
||||
* server with the given session
|
||||
*
|
||||
* @param session session
|
||||
*/
|
||||
private void openSession(AccountSession session, boolean openSocket)
|
||||
{
|
||||
// Change session on the websocket
|
||||
if (openSocket)
|
||||
{
|
||||
wsClient.changeSession(session.getUuid());
|
||||
}
|
||||
|
||||
accountSession = session;
|
||||
|
||||
if (session.getUsername() != null)
|
||||
{
|
||||
// Initialize config for new session
|
||||
// If the session isn't logged in yet, don't switch to the new config
|
||||
configManager.switchSession(session);
|
||||
}
|
||||
|
||||
eventBus.post(new SessionOpen());
|
||||
}
|
||||
|
||||
private void closeSession()
|
||||
{
|
||||
wsClient.changeSession(null);
|
||||
|
||||
if (accountSession == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("Logging out of account {}", accountSession.getUsername());
|
||||
|
||||
AccountClient client = new AccountClient(accountSession.getUuid());
|
||||
try
|
||||
{
|
||||
client.logout();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Unable to logout of session", ex);
|
||||
}
|
||||
|
||||
accountSession = null; // No more account
|
||||
|
||||
// Restore config
|
||||
configManager.switchSession(null);
|
||||
|
||||
eventBus.post(new SessionClose());
|
||||
}
|
||||
|
||||
public void login()
|
||||
{
|
||||
// If a session is already open, use that id. Otherwise generate a new id.
|
||||
UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID();
|
||||
AccountClient loginClient = new AccountClient(uuid);
|
||||
|
||||
final OAuthResponse login;
|
||||
|
||||
try
|
||||
{
|
||||
login = loginClient.login();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("Unable to get oauth url", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new session
|
||||
openSession(new AccountSession(login.getUid(), Instant.now()), true);
|
||||
|
||||
// Navigate to login link
|
||||
LinkBrowser.browse(login.getOauthUrl());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onLoginResponse(LoginResponse loginResponse)
|
||||
{
|
||||
log.debug("Now logged in as {}", loginResponse.getUsername());
|
||||
|
||||
AccountSession session = getAccountSession();
|
||||
session.setUsername(loginResponse.getUsername());
|
||||
|
||||
// Open session, again, now that we have a username
|
||||
// This triggers onSessionOpen
|
||||
// The socket is already opened here anyway so we pass true for openSocket
|
||||
openSession(session, true);
|
||||
|
||||
// Save session to disk
|
||||
saveSession();
|
||||
}
|
||||
|
||||
public void logout()
|
||||
{
|
||||
closeSession();
|
||||
deleteSession();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,6 +374,7 @@ public class Hooks implements Callbacks
|
||||
|
||||
/**
|
||||
* Copy an image
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -1,153 +1,153 @@
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
class ConfigInvocationHandler implements InvocationHandler
|
||||
{
|
||||
private final ConfigManager manager;
|
||||
|
||||
public ConfigInvocationHandler(ConfigManager manager)
|
||||
{
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
Class<?> iface = proxy.getClass().getInterfaces()[0];
|
||||
|
||||
ConfigGroup group = iface.getAnnotation(ConfigGroup.class);
|
||||
ConfigItem item = method.getAnnotation(ConfigItem.class);
|
||||
|
||||
if (group == null)
|
||||
{
|
||||
log.warn("Configuration proxy class {} has no @ConfigGroup!", proxy.getClass());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
log.warn("Configuration method {} has no @ConfigItem!", method);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
{
|
||||
// Getting configuration item
|
||||
String value = manager.getConfiguration(group.value(), item.keyName());
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
if (method.isDefault())
|
||||
{
|
||||
return callDefaultMethod(proxy, method, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Convert value to return type
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
try
|
||||
{
|
||||
return ConfigManager.stringToObject(value, returnType);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e);
|
||||
if (method.isDefault())
|
||||
{
|
||||
return callDefaultMethod(proxy, method, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setting a configuration value
|
||||
|
||||
if (args.length != 1)
|
||||
{
|
||||
throw new RuntimeException("Invalid number of arguents to configuration method");
|
||||
}
|
||||
|
||||
Object newValue = args[0];
|
||||
|
||||
Class<?> type = method.getParameterTypes()[0];
|
||||
Object oldValue = manager.getConfiguration(group.value(), item.keyName(), type);
|
||||
|
||||
if (Objects.equals(oldValue, newValue))
|
||||
{
|
||||
// nothing to do
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method.isDefault())
|
||||
{
|
||||
Object defaultValue = callDefaultMethod(proxy, method, args);
|
||||
|
||||
if (Objects.equals(newValue, defaultValue))
|
||||
{
|
||||
// Just unset if it goes back to the default
|
||||
manager.unsetConfiguration(group.value(), item.keyName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
manager.unsetConfiguration(group.value(), item.keyName());
|
||||
}
|
||||
else
|
||||
{
|
||||
String newValueStr = ConfigManager.objectToString(newValue);
|
||||
manager.setConfiguration(group.value(), item.keyName(), newValueStr);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
// Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/
|
||||
Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
|
||||
constructor.setAccessible(true);
|
||||
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE)
|
||||
.unreflectSpecial(method, declaringClass)
|
||||
.bindTo(proxy)
|
||||
.invokeWithArguments(args);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
class ConfigInvocationHandler implements InvocationHandler
|
||||
{
|
||||
private final ConfigManager manager;
|
||||
|
||||
public ConfigInvocationHandler(ConfigManager manager)
|
||||
{
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
Class<?> iface = proxy.getClass().getInterfaces()[0];
|
||||
|
||||
ConfigGroup group = iface.getAnnotation(ConfigGroup.class);
|
||||
ConfigItem item = method.getAnnotation(ConfigItem.class);
|
||||
|
||||
if (group == null)
|
||||
{
|
||||
log.warn("Configuration proxy class {} has no @ConfigGroup!", proxy.getClass());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
log.warn("Configuration method {} has no @ConfigItem!", method);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
{
|
||||
// Getting configuration item
|
||||
String value = manager.getConfiguration(group.value(), item.keyName());
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
if (method.isDefault())
|
||||
{
|
||||
return callDefaultMethod(proxy, method, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Convert value to return type
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
try
|
||||
{
|
||||
return ConfigManager.stringToObject(value, returnType);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("Unable to unmarshal {}.{} ", group.value(), item.keyName(), e);
|
||||
if (method.isDefault())
|
||||
{
|
||||
return callDefaultMethod(proxy, method, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setting a configuration value
|
||||
|
||||
if (args.length != 1)
|
||||
{
|
||||
throw new RuntimeException("Invalid number of arguents to configuration method");
|
||||
}
|
||||
|
||||
Object newValue = args[0];
|
||||
|
||||
Class<?> type = method.getParameterTypes()[0];
|
||||
Object oldValue = manager.getConfiguration(group.value(), item.keyName(), type);
|
||||
|
||||
if (Objects.equals(oldValue, newValue))
|
||||
{
|
||||
// nothing to do
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method.isDefault())
|
||||
{
|
||||
Object defaultValue = callDefaultMethod(proxy, method, args);
|
||||
|
||||
if (Objects.equals(newValue, defaultValue))
|
||||
{
|
||||
// Just unset if it goes back to the default
|
||||
manager.unsetConfiguration(group.value(), item.keyName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
manager.unsetConfiguration(group.value(), item.keyName());
|
||||
}
|
||||
else
|
||||
{
|
||||
String newValueStr = ConfigManager.objectToString(newValue);
|
||||
manager.setConfiguration(group.value(), item.keyName(), newValueStr);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
// Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/
|
||||
Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
|
||||
constructor.setAccessible(true);
|
||||
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE)
|
||||
.unreflectSpecial(method, declaringClass)
|
||||
.bindTo(proxy)
|
||||
.invokeWithArguments(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Craftiii4 <craftiii4@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.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class ConfigItemsGroup
|
||||
{
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final String group;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private Collection<ConfigItemDescriptor> items;
|
||||
|
||||
public ConfigItemsGroup(String group)
|
||||
{
|
||||
this.group = group;
|
||||
this.items = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addItem(ConfigItemDescriptor item)
|
||||
{
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Craftiii4 <craftiii4@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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ConfigItemsGroup
|
||||
{
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final String group;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private Collection<ConfigItemDescriptor> items;
|
||||
|
||||
public ConfigItemsGroup(String group)
|
||||
{
|
||||
this.group = group;
|
||||
this.items = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addItem(ConfigItemDescriptor item)
|
||||
{
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -364,9 +364,9 @@ public class ConfigManager
|
||||
}
|
||||
|
||||
itemGroups = itemGroups.stream().sorted((a, b) -> ComparisonChain.start()
|
||||
.compare(a.getGroup(), b.getGroup())
|
||||
.result())
|
||||
.collect(Collectors.toList());
|
||||
.compare(a.getGroup(), b.getGroup())
|
||||
.result())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new ConfigDescriptor(group, itemGroups);
|
||||
}
|
||||
@@ -511,22 +511,22 @@ public class ConfigManager
|
||||
{
|
||||
return Duration.ofMillis(Long.parseLong(str));
|
||||
}
|
||||
if (type == Map.class)
|
||||
{
|
||||
Map<String, String> output = new HashMap<>();
|
||||
str = str.substring(1, str.length() - 1);
|
||||
String[] splitStr = str.split(", ");
|
||||
for (String s : splitStr)
|
||||
{
|
||||
String[] keyVal = s.split("=");
|
||||
if (keyVal.length > 1)
|
||||
{
|
||||
output.put(keyVal[0], keyVal[1]);
|
||||
}
|
||||
}
|
||||
if (type == Map.class)
|
||||
{
|
||||
Map<String, String> output = new HashMap<>();
|
||||
str = str.substring(1, str.length() - 1);
|
||||
String[] splitStr = str.split(", ");
|
||||
for (String s : splitStr)
|
||||
{
|
||||
String[] keyVal = s.split("=");
|
||||
if (keyVal.length > 1)
|
||||
{
|
||||
output.put(keyVal[0], keyVal[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tanner <https://github.com/Reasel>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
import java.awt.Font;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FontType
|
||||
{
|
||||
REGULAR("Regular", FontManager.getRunescapeFont()),
|
||||
BOLD("Bold", FontManager.getRunescapeBoldFont()),
|
||||
SMALL("Small", FontManager.getRunescapeSmallFont());
|
||||
|
||||
private final String name;
|
||||
private final Font font;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Tanner <https://github.com/Reasel>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import java.awt.Font;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FontType
|
||||
{
|
||||
REGULAR("Regular", FontManager.getRunescapeFont()),
|
||||
BOLD("Bold", FontManager.getRunescapeBoldFont()),
|
||||
SMALL("Small", FontManager.getRunescapeSmallFont());
|
||||
|
||||
private final String name;
|
||||
private final Font font;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "enablePlugins",
|
||||
name = "Enable loading of external plugins",
|
||||
description = "Enable loading of external plugins",
|
||||
position = 10
|
||||
position = 10
|
||||
)
|
||||
default boolean enablePlugins()
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ public class DiscordService implements AutoCloseable
|
||||
discordEventHandlers.joinGame = this::joinGame;
|
||||
discordEventHandlers.spectateGame = this::spectateGame;
|
||||
discordEventHandlers.joinRequest = this::joinRequest;
|
||||
discordRPC.Discord_Initialize(runeLiteProperties.discordAppID, discordEventHandlers, true, null);
|
||||
discordRPC.Discord_Initialize(RuneLiteProperties.discordAppID, discordEventHandlers, true, null);
|
||||
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,248 +35,307 @@ for mouse motion.
|
||||
package net.runelite.client.flexo;
|
||||
|
||||
import com.github.joonasvali.naturalmouse.api.MouseMotionFactory;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import sun.awt.ComponentFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Color;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.peer.RobotPeer;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import sun.awt.ComponentFactory;
|
||||
|
||||
public class Flexo extends Robot {
|
||||
public ThreadGroup flexoThreads = new ThreadGroup("flexo");
|
||||
public static boolean isActive;
|
||||
public static double scale;
|
||||
public static Client client;
|
||||
public static ClientUI clientUI;
|
||||
public static int fixedWidth = 765;
|
||||
public static int fixedHeight = 503;
|
||||
public static boolean isStretched;
|
||||
public static int minDelay = 45;
|
||||
public static MouseMotionFactory currentMouseMotionFactory;
|
||||
public boolean pausedIndefinitely = false;
|
||||
private Thread holdKeyThread;
|
||||
private RobotPeer peer;
|
||||
public class Flexo extends Robot
|
||||
{
|
||||
public ThreadGroup flexoThreads = new ThreadGroup("flexo");
|
||||
public static boolean isActive;
|
||||
public static double scale;
|
||||
public static Client client;
|
||||
public static ClientUI clientUI;
|
||||
public static int fixedWidth = Constants.GAME_FIXED_WIDTH;
|
||||
public static int fixedHeight = Constants.GAME_FIXED_HEIGHT;
|
||||
public static boolean isStretched;
|
||||
public static int minDelay = 45;
|
||||
public static MouseMotionFactory currentMouseMotionFactory;
|
||||
public boolean pausedIndefinitely = false;
|
||||
private Thread holdKeyThread;
|
||||
private RobotPeer peer;
|
||||
|
||||
public Flexo() throws AWTException {
|
||||
if (GraphicsEnvironment.isHeadless()) {
|
||||
throw new AWTException("headless environment");
|
||||
}
|
||||
init(GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice());
|
||||
}
|
||||
public Flexo() throws AWTException
|
||||
{
|
||||
if (GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
throw new AWTException("headless environment");
|
||||
}
|
||||
init(GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice());
|
||||
}
|
||||
|
||||
private void init(GraphicsDevice screen) throws AWTException {
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
if (toolkit instanceof ComponentFactory) {
|
||||
peer = ((ComponentFactory)toolkit).createRobot(this, screen);
|
||||
RobotDisposer disposer = new RobotDisposer(peer);
|
||||
sun.java2d.Disposer.addRecord(anchor, disposer);
|
||||
}
|
||||
}
|
||||
private void init(GraphicsDevice screen) throws AWTException
|
||||
{
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
if (toolkit instanceof ComponentFactory)
|
||||
{
|
||||
peer = ((ComponentFactory) toolkit).createRobot(this, screen);
|
||||
RobotDisposer disposer = new RobotDisposer(peer);
|
||||
sun.java2d.Disposer.addRecord(anchor, disposer);
|
||||
}
|
||||
}
|
||||
|
||||
private transient Object anchor = new Object();
|
||||
private transient Object anchor = new Object();
|
||||
|
||||
static class RobotDisposer implements sun.java2d.DisposerRecord {
|
||||
private final RobotPeer peer;
|
||||
private RobotDisposer(RobotPeer peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
public void dispose() {
|
||||
if (peer != null) {
|
||||
peer.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
static class RobotDisposer implements sun.java2d.DisposerRecord
|
||||
{
|
||||
private final RobotPeer peer;
|
||||
|
||||
private void pauseMS(int delayMS) {
|
||||
long initialMS = System.currentTimeMillis();
|
||||
while (System.currentTimeMillis()<initialMS+delayMS) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
isActive = false;
|
||||
}
|
||||
private RobotDisposer(RobotPeer peer)
|
||||
{
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mouseMove(int x, int y) {
|
||||
try {
|
||||
//TODO: Must be better way to determine titlebar width
|
||||
currentMouseMotionFactory.build(ClientUI.frame.getX()+x+determineHorizontalOffset(), ClientUI.frame.getY()+y+determineVerticalOffset()).move();
|
||||
this.delay(getMinDelay());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void dispose()
|
||||
{
|
||||
if (peer != null)
|
||||
{
|
||||
peer.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void mouseMove(Point p) {
|
||||
Point p2 = p;
|
||||
mouseMove((int)p.getX(), (int)p.getY());
|
||||
try {
|
||||
Thread.sleep(150);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private void pauseMS(int delayMS)
|
||||
{
|
||||
long initialMS = System.currentTimeMillis();
|
||||
while (System.currentTimeMillis() < initialMS + delayMS)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mousePress(int buttonID) {
|
||||
if (buttonID<1 || buttonID >5) {
|
||||
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
|
||||
return;
|
||||
}
|
||||
peer.mousePress(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
@Override
|
||||
public synchronized void mouseMove(int x, int y)
|
||||
{
|
||||
try
|
||||
{
|
||||
//TODO: Must be better way to determine titlebar width
|
||||
currentMouseMotionFactory.build(ClientUI.frame.getX() + x + determineHorizontalOffset(), ClientUI.frame.getY() + y + determineVerticalOffset()).move();
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void mousePressAndRelease(int buttonID) {
|
||||
if (buttonID<1 || buttonID >5) {
|
||||
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
|
||||
return;
|
||||
}
|
||||
peer.mousePress(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
public synchronized void mouseMove(Point p)
|
||||
{
|
||||
Point p2 = p;
|
||||
mouseMove((int) p.getX(), (int) p.getY());
|
||||
try
|
||||
{
|
||||
Thread.sleep(150);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Symbols are nut supported at this time
|
||||
public synchronized void typeMessage(String message) {
|
||||
@Override
|
||||
public synchronized void mousePress(int buttonID)
|
||||
{
|
||||
if (buttonID < 1 || buttonID > 5)
|
||||
{
|
||||
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
|
||||
return;
|
||||
}
|
||||
peer.mousePress(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
|
||||
Random r = new Random();
|
||||
char[] charArray = message.toCharArray();
|
||||
for (char c : charArray) {
|
||||
keyPress(KeyEvent.getExtendedKeyCodeForChar(c));
|
||||
this.delay(93+r.nextInt(getMinDelay()));
|
||||
}
|
||||
keyPress(KeyEvent.VK_ENTER);
|
||||
this.delay(93+r.nextInt(getMinDelay()));
|
||||
ClientUI.allowInput = true;
|
||||
}
|
||||
public synchronized void mousePressAndRelease(int buttonID)
|
||||
{
|
||||
if (buttonID < 1 || buttonID > 5)
|
||||
{
|
||||
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
|
||||
return;
|
||||
}
|
||||
peer.mousePress(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
|
||||
//TODO: Symbols are nut supported at this time
|
||||
public synchronized void typeMessage(String message)
|
||||
{
|
||||
|
||||
Random r = new Random();
|
||||
char[] charArray = message.toCharArray();
|
||||
for (char c : charArray)
|
||||
{
|
||||
keyPress(KeyEvent.getExtendedKeyCodeForChar(c));
|
||||
this.delay(93 + r.nextInt(getMinDelay()));
|
||||
}
|
||||
keyPress(KeyEvent.VK_ENTER);
|
||||
this.delay(93 + r.nextInt(getMinDelay()));
|
||||
ClientUI.allowInput = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void mouseRelease(int buttonID)
|
||||
{
|
||||
if (buttonID < 1 || buttonID > 5)
|
||||
{
|
||||
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
|
||||
return;
|
||||
}
|
||||
peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mouseRelease(int buttonID) {
|
||||
if (buttonID<1 || buttonID >5) {
|
||||
Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
|
||||
return;
|
||||
}
|
||||
peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
private int getMinDelay()
|
||||
{
|
||||
Random random = new Random();
|
||||
int random1 = random.nextInt(minDelay);
|
||||
if (random1 < minDelay / 2)
|
||||
{
|
||||
random1 = random.nextInt(minDelay / 2) + minDelay / 2 + random.nextInt(minDelay / 2);
|
||||
}
|
||||
return random1;
|
||||
}
|
||||
|
||||
private int getMinDelay() {
|
||||
Random random = new Random();
|
||||
int random1 = random.nextInt(minDelay);
|
||||
if (random1 < minDelay/2)
|
||||
random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2);
|
||||
return random1;
|
||||
}
|
||||
private int getWheelDelay()
|
||||
{
|
||||
Random random = new Random();
|
||||
int random1 = random.nextInt(minDelay);
|
||||
if (random1 < minDelay / 2)
|
||||
{
|
||||
random1 = random.nextInt(minDelay / 2) + minDelay / 2 + random.nextInt(minDelay / 2);
|
||||
}
|
||||
return random1;
|
||||
}
|
||||
|
||||
private int getWheelDelay() {
|
||||
Random random = new Random();
|
||||
int random1 = random.nextInt(minDelay);
|
||||
if (random1 < minDelay/2)
|
||||
random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2);
|
||||
return random1;
|
||||
}
|
||||
/**
|
||||
* Rotates the scroll wheel on wheel-equipped mice.
|
||||
*
|
||||
* @param wheelAmt number of "notches" to move the mouse wheel
|
||||
* Negative values indicate movement up/away from the user,
|
||||
* positive values indicate movement down/towards the user.
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public synchronized void mouseWheel(int wheelAmt)
|
||||
{
|
||||
for (int i : new int[wheelAmt])
|
||||
{
|
||||
peer.mouseWheel(wheelAmt);
|
||||
this.delay(getWheelDelay());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the scroll wheel on wheel-equipped mice.
|
||||
*
|
||||
* @param wheelAmt number of "notches" to move the mouse wheel
|
||||
* Negative values indicate movement up/away from the user,
|
||||
* positive values indicate movement down/towards the user.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
public synchronized void mouseWheel(int wheelAmt) {
|
||||
for (int i : new int[wheelAmt]) {
|
||||
peer.mouseWheel(wheelAmt);
|
||||
this.delay(getWheelDelay());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Presses a given key. The key should be released using the
|
||||
* <code>keyRelease</code> method.
|
||||
* <p>
|
||||
* Key codes that have more than one physical key associated with them
|
||||
* (e.g. <code>KeyEvent.VK_SHIFT</code> could mean either the
|
||||
* left or right shift key) will map to the left key.
|
||||
*
|
||||
* @param keycode Key to press (e.g. <code>KeyEvent.VK_A</code>)
|
||||
* @throws IllegalArgumentException if <code>keycode</code> is not
|
||||
* a valid key
|
||||
* @see #keyRelease(int)
|
||||
* @see java.awt.event.KeyEvent
|
||||
*/
|
||||
@Override
|
||||
public synchronized void keyPress(int keycode)
|
||||
{
|
||||
peer.keyPress(keycode);
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Presses a given key. The key should be released using the
|
||||
* <code>keyRelease</code> method.
|
||||
* <p>
|
||||
* Key codes that have more than one physical key associated with them
|
||||
* (e.g. <code>KeyEvent.VK_SHIFT</code> could mean either the
|
||||
* left or right shift key) will map to the left key.
|
||||
*
|
||||
* @param keycode Key to press (e.g. <code>KeyEvent.VK_A</code>)
|
||||
* @throws IllegalArgumentException if <code>keycode</code> is not
|
||||
* a valid key
|
||||
* @see #keyRelease(int)
|
||||
* @see java.awt.event.KeyEvent
|
||||
*/
|
||||
@Override
|
||||
public synchronized void keyPress(int keycode) {
|
||||
peer.keyPress(keycode);
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
@Override
|
||||
public synchronized void keyRelease(int keycode)
|
||||
{
|
||||
peer.keyRelease(keycode);
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void keyRelease(int keycode) {
|
||||
peer.keyRelease(keycode);
|
||||
this.delay(getMinDelay());
|
||||
}
|
||||
public synchronized void holdKey(int keycode, int timeMS)
|
||||
{
|
||||
new Thread(() ->
|
||||
{
|
||||
peer.keyPress(keycode);
|
||||
long startTime = System.currentTimeMillis();
|
||||
while ((startTime + timeMS) > System.currentTimeMillis())
|
||||
{
|
||||
}
|
||||
peer.keyRelease(keycode);
|
||||
this.delay(getMinDelay());
|
||||
}).start();
|
||||
}
|
||||
|
||||
public synchronized void holdKey(int keycode, int timeMS) {
|
||||
new Thread(() -> {
|
||||
peer.keyPress(keycode);
|
||||
long startTime = System.currentTimeMillis();
|
||||
while ((startTime + timeMS) > System.currentTimeMillis()) { }
|
||||
peer.keyRelease(keycode);
|
||||
this.delay(getMinDelay());
|
||||
}).start();
|
||||
}
|
||||
public synchronized void holdKeyIndefinitely(int keycode)
|
||||
{
|
||||
holdKeyThread = new Thread(() ->
|
||||
{
|
||||
pausedIndefinitely = true;
|
||||
peer.keyPress(keycode);
|
||||
while (pausedIndefinitely)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
peer.keyRelease(keycode);
|
||||
this.delay(getMinDelay());
|
||||
});
|
||||
holdKeyThread.start();
|
||||
|
||||
public synchronized void holdKeyIndefinitely(int keycode) {
|
||||
holdKeyThread = new Thread(() -> {
|
||||
pausedIndefinitely = true;
|
||||
peer.keyPress(keycode);
|
||||
while (pausedIndefinitely) {
|
||||
try {
|
||||
holdKeyThread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
peer.keyRelease(keycode);
|
||||
this.delay(getMinDelay());
|
||||
});
|
||||
holdKeyThread.start();
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public Color getPixelColor(int x, int y)
|
||||
{
|
||||
Color color = new Color(peer.getRGBPixel(x, y));
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getPixelColor(int x, int y) {
|
||||
Color color = new Color(peer.getRGBPixel(x, y));
|
||||
return color;
|
||||
}
|
||||
@Override
|
||||
public void delay(int ms)
|
||||
{
|
||||
pauseMS(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delay(int ms) {
|
||||
pauseMS(ms);
|
||||
}
|
||||
|
||||
public int determineHorizontalOffset() {
|
||||
return clientUI.getCanvasOffset().getX();
|
||||
}
|
||||
|
||||
public int determineVerticalOffset() {
|
||||
return clientUI.getCanvasOffset().getY();
|
||||
}
|
||||
public int determineHorizontalOffset()
|
||||
{
|
||||
return clientUI.getCanvasOffset().getX();
|
||||
}
|
||||
|
||||
public int determineVerticalOffset()
|
||||
{
|
||||
return clientUI.getCanvasOffset().getY();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,163 +28,198 @@
|
||||
|
||||
package net.runelite.client.flexo;
|
||||
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
|
||||
public class FlexoMouse {
|
||||
public class FlexoMouse
|
||||
{
|
||||
|
||||
/*
|
||||
Should pass unstretched coords, handles all conversions here.
|
||||
*/
|
||||
public static Point getClickPoint(Rectangle rect)
|
||||
{
|
||||
if (rect!=null) {
|
||||
Random r = new Random();
|
||||
int x = -1;
|
||||
int y = -1;
|
||||
x = rect.x+r.nextInt(rect.width);
|
||||
y = rect.y+r.nextInt(rect.height);
|
||||
/*
|
||||
Should pass unstretched coords, handles all conversions here.
|
||||
*/
|
||||
public static Point getClickPoint(Rectangle rect)
|
||||
{
|
||||
if (rect != null)
|
||||
{
|
||||
Random r = new Random();
|
||||
int x = -1;
|
||||
int y = -1;
|
||||
x = rect.x + r.nextInt(rect.width);
|
||||
y = rect.y + r.nextInt(rect.height);
|
||||
|
||||
if (Flexo.isStretched) {
|
||||
double wScale;
|
||||
double hScale;
|
||||
if (Flexo.isStretched)
|
||||
{
|
||||
double wScale;
|
||||
double hScale;
|
||||
|
||||
if (Flexo.client.isResized()) {
|
||||
wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
|
||||
hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
|
||||
int newX = (int)(x*wScale);
|
||||
int newY = (int)(y*hScale);
|
||||
if (newX>0 && newX< ClientUI.frame.getWidth()) {
|
||||
if (newY>0 && newY< ClientUI.frame.getHeight()) {
|
||||
return new Point(newX, newY);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
} else {
|
||||
if (x>0 && x< ClientUI.frame.getWidth()) {
|
||||
if (y>0 && y< ClientUI.frame.getHeight()) {
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
if (Flexo.client.isResized())
|
||||
{
|
||||
wScale = (Flexo.client.getStretchedDimensions().width / (double) Flexo.client.getRealDimensions().width);
|
||||
hScale = (Flexo.client.getStretchedDimensions().height / (double) Flexo.client.getRealDimensions().height);
|
||||
int newX = (int) (x * wScale);
|
||||
int newY = (int) (y * hScale);
|
||||
if (newX > 0 && newX < ClientUI.frame.getWidth())
|
||||
{
|
||||
if (newY > 0 && newY < ClientUI.frame.getHeight())
|
||||
{
|
||||
return new Point(newX, newY);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > 0 && x < ClientUI.frame.getWidth())
|
||||
{
|
||||
if (y > 0 && y < ClientUI.frame.getHeight())
|
||||
{
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
|
||||
} else if (!Flexo.client.isResized()) {
|
||||
int fixedWidth = 765;
|
||||
int widthDif = ClientUI.frame.getWidth();
|
||||
}
|
||||
else if (!Flexo.client.isResized())
|
||||
{
|
||||
final int fixedWidth = Constants.GAME_FIXED_WIDTH;
|
||||
int widthDif = ClientUI.frame.getWidth();
|
||||
|
||||
if (ClientUI.pluginToolbar.isVisible()) {
|
||||
widthDif -= ClientUI.pluginToolbar.getWidth();
|
||||
}
|
||||
if (ClientUI.pluginPanel!=null)
|
||||
widthDif -= ClientUI.pluginPanel.getWidth();
|
||||
if (ClientUI.pluginToolbar.isVisible())
|
||||
{
|
||||
widthDif -= ClientUI.pluginToolbar.getWidth();
|
||||
}
|
||||
if (ClientUI.pluginPanel != null)
|
||||
{
|
||||
widthDif -= ClientUI.pluginPanel.getWidth();
|
||||
}
|
||||
|
||||
widthDif -= fixedWidth;
|
||||
if (x+(widthDif/2)>0 && x+(widthDif/2)< ClientUI.frame.getWidth()) {
|
||||
if (y>0 && y< ClientUI.frame.getHeight()) {
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
if (x>0 && x< ClientUI.frame.getWidth()) {
|
||||
if (y>0 && y< ClientUI.frame.getHeight()) {
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
widthDif -= fixedWidth;
|
||||
if (x + (widthDif / 2) > 0 && x + (widthDif / 2) < ClientUI.frame.getWidth())
|
||||
{
|
||||
if (y > 0 && y < ClientUI.frame.getHeight())
|
||||
{
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > 0 && x < ClientUI.frame.getWidth())
|
||||
{
|
||||
if (y > 0 && y < ClientUI.frame.getHeight())
|
||||
{
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
Logger.getAnonymousLogger().warning("[RuneLit]Flexo - Off screen point attempted. Split the step, or rotate the screen.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Rectangle getClickArea(Rectangle rect)
|
||||
{
|
||||
if (Flexo.isStretched)
|
||||
{
|
||||
double wScale;
|
||||
double hScale;
|
||||
public static Rectangle getClickArea(Rectangle rect)
|
||||
{
|
||||
if (Flexo.isStretched)
|
||||
{
|
||||
double wScale;
|
||||
double hScale;
|
||||
|
||||
if (Flexo.client.isResized()) {
|
||||
wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
|
||||
hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
|
||||
} else {
|
||||
wScale = ((double) Flexo.client.getStretchedDimensions().width) / Flexo.fixedWidth;
|
||||
hScale = ((double) Flexo.client.getStretchedDimensions().height) / Flexo.fixedHeight;
|
||||
}
|
||||
if (Flexo.client.isResized())
|
||||
{
|
||||
wScale = (Flexo.client.getStretchedDimensions().width / (double) Flexo.client.getRealDimensions().width);
|
||||
hScale = (Flexo.client.getStretchedDimensions().height / (double) Flexo.client.getRealDimensions().height);
|
||||
}
|
||||
else
|
||||
{
|
||||
wScale = (Flexo.client.getStretchedDimensions().width) / (double) Flexo.fixedWidth;
|
||||
hScale = (Flexo.client.getStretchedDimensions().height) / (double) Flexo.fixedHeight;
|
||||
}
|
||||
|
||||
int xPadding = (int)rect.getWidth()/5;
|
||||
int yPadding = (int)rect.getHeight()/5;
|
||||
Random r = new Random();
|
||||
Rectangle clickRect = new Rectangle();
|
||||
clickRect.width = rect.width-xPadding*2;
|
||||
clickRect.height = rect.height-yPadding*2;
|
||||
clickRect.x = rect.x+xPadding;
|
||||
clickRect.y = rect.y+yPadding;
|
||||
if (clickRect.width>0&&clickRect.height>0) {
|
||||
int x = clickRect.x+r.nextInt(clickRect.width);
|
||||
int y = clickRect.y+r.nextInt(clickRect.height);
|
||||
double tScale = 1 + (Flexo.scale / 100);
|
||||
int xPadding = (int) rect.getWidth() / 5;
|
||||
int yPadding = (int) rect.getHeight() / 5;
|
||||
Random r = new Random();
|
||||
Rectangle clickRect = new Rectangle();
|
||||
clickRect.width = rect.width - xPadding * 2;
|
||||
clickRect.height = rect.height - yPadding * 2;
|
||||
clickRect.x = rect.x + xPadding;
|
||||
clickRect.y = rect.y + yPadding;
|
||||
if (clickRect.width > 0 && clickRect.height > 0)
|
||||
{
|
||||
int x = clickRect.x + r.nextInt(clickRect.width);
|
||||
int y = clickRect.y + r.nextInt(clickRect.height);
|
||||
double tScale = 1 + (Flexo.scale / 100);
|
||||
|
||||
if (Flexo.client.isResized()) {
|
||||
return new Rectangle((int)(clickRect.x * wScale), (int)(clickRect.y * wScale), (int)(clickRect.width * wScale), (int)(clickRect.getHeight()*hScale));
|
||||
} else {
|
||||
return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight()));
|
||||
}
|
||||
}
|
||||
if (Flexo.client.isResized())
|
||||
{
|
||||
return new Rectangle((int) (clickRect.x * wScale), (int) (clickRect.y * wScale), (int) (clickRect.width * wScale), (int) (clickRect.getHeight() * hScale));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Rectangle(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//Fixed, not stretched
|
||||
else if (!Flexo.client.isResized()) {
|
||||
int fixedWidth = 765;
|
||||
int widthDif = ClientUI.frame.getWidth();
|
||||
}
|
||||
//Fixed, not stretched
|
||||
else if (!Flexo.client.isResized())
|
||||
{
|
||||
int fixedWidth = 765;
|
||||
int widthDif = ClientUI.frame.getWidth();
|
||||
|
||||
if (ClientUI.pluginToolbar.isVisible()) {
|
||||
widthDif -= ClientUI.pluginToolbar.getWidth();
|
||||
}
|
||||
if (ClientUI.pluginPanel!=null)
|
||||
widthDif -= ClientUI.pluginPanel.getWidth();
|
||||
if (ClientUI.pluginToolbar.isVisible())
|
||||
{
|
||||
widthDif -= ClientUI.pluginToolbar.getWidth();
|
||||
}
|
||||
if (ClientUI.pluginPanel != null)
|
||||
{
|
||||
widthDif -= ClientUI.pluginPanel.getWidth();
|
||||
}
|
||||
|
||||
widthDif -= fixedWidth;
|
||||
int xPadding = (int)rect.getWidth()/5;
|
||||
int yPadding = (int)rect.getHeight()/5;
|
||||
Random r = new Random();
|
||||
Rectangle clickRect = new Rectangle();
|
||||
clickRect.width = rect.width-xPadding;
|
||||
clickRect.height = rect.height-yPadding;
|
||||
clickRect.x = rect.x+xPadding;
|
||||
clickRect.y = rect.y+yPadding;
|
||||
if (clickRect.height>0&&clickRect.width>0) {
|
||||
int x = clickRect.x + r.nextInt(clickRect.width);
|
||||
int y = clickRect.y + r.nextInt(clickRect.height);
|
||||
return new Rectangle((int) (clickRect.x), (int) (clickRect.y), (int) (clickRect.width), (int) (clickRect.getHeight()));
|
||||
}
|
||||
}
|
||||
//Resizable, not stretched
|
||||
else {
|
||||
int xPadding = (int)rect.getWidth()/5;
|
||||
int yPadding = (int)rect.getHeight()/5;
|
||||
Random r = new Random();
|
||||
Rectangle clickRect = new Rectangle();
|
||||
clickRect.width = rect.width-xPadding*2;
|
||||
clickRect.height = rect.height-yPadding*2;
|
||||
clickRect.x = rect.x+xPadding;
|
||||
clickRect.y = rect.y+yPadding;
|
||||
if (clickRect.height>0&&clickRect.width>0) {
|
||||
int x = clickRect.x+r.nextInt(clickRect.width);
|
||||
int y = clickRect.y+r.nextInt(clickRect.height);
|
||||
return new Rectangle((int)(clickRect.x), (int)(clickRect.y), (int)(clickRect.width), (int)(clickRect.getHeight()));
|
||||
}
|
||||
}
|
||||
widthDif -= fixedWidth;
|
||||
int xPadding = (int) rect.getWidth() / 5;
|
||||
int yPadding = (int) rect.getHeight() / 5;
|
||||
Random r = new Random();
|
||||
Rectangle clickRect = new Rectangle();
|
||||
clickRect.width = rect.width - xPadding;
|
||||
clickRect.height = rect.height - yPadding;
|
||||
clickRect.x = rect.x + xPadding;
|
||||
clickRect.y = rect.y + yPadding;
|
||||
if (clickRect.height > 0 && clickRect.width > 0)
|
||||
{
|
||||
int x = clickRect.x + r.nextInt(clickRect.width);
|
||||
int y = clickRect.y + r.nextInt(clickRect.height);
|
||||
return new Rectangle(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
|
||||
}
|
||||
}
|
||||
//Resizable, not stretched
|
||||
else
|
||||
{
|
||||
int xPadding = (int) rect.getWidth() / 5;
|
||||
int yPadding = (int) rect.getHeight() / 5;
|
||||
Random r = new Random();
|
||||
Rectangle clickRect = new Rectangle();
|
||||
clickRect.width = rect.width - xPadding * 2;
|
||||
clickRect.height = rect.height - yPadding * 2;
|
||||
clickRect.x = rect.x + xPadding;
|
||||
clickRect.y = rect.y + yPadding;
|
||||
if (clickRect.height > 0 && clickRect.width > 0)
|
||||
{
|
||||
int x = clickRect.x + r.nextInt(clickRect.width);
|
||||
int y = clickRect.y + r.nextInt(clickRect.height);
|
||||
return new Rectangle(clickRect.x, clickRect.y, clickRect.width, (int) (clickRect.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,54 +26,258 @@
|
||||
package net.runelite.client.game;
|
||||
|
||||
import lombok.Getter;
|
||||
import static net.runelite.api.NullObjectID.*;
|
||||
import static net.runelite.api.ObjectID.*;
|
||||
import static net.runelite.api.NullObjectID.NULL_25337;
|
||||
import static net.runelite.api.NullObjectID.NULL_26371;
|
||||
import static net.runelite.api.NullObjectID.NULL_26375;
|
||||
import static net.runelite.api.NullObjectID.NULL_26884;
|
||||
import static net.runelite.api.NullObjectID.NULL_26886;
|
||||
import static net.runelite.api.NullObjectID.NULL_29868;
|
||||
import static net.runelite.api.NullObjectID.NULL_29869;
|
||||
import static net.runelite.api.NullObjectID.NULL_29870;
|
||||
import static net.runelite.api.NullObjectID.NULL_31823;
|
||||
import static net.runelite.api.NullObjectID.NULL_31849;
|
||||
import static net.runelite.api.NullObjectID.NULL_33327;
|
||||
import static net.runelite.api.NullObjectID.NULL_33328;
|
||||
import static net.runelite.api.ObjectID.A_WOODEN_LOG;
|
||||
import static net.runelite.api.ObjectID.BALANCING_LEDGE_23548;
|
||||
import static net.runelite.api.ObjectID.BIG_WINDOW;
|
||||
import static net.runelite.api.ObjectID.BOULDER_27990;
|
||||
import static net.runelite.api.ObjectID.BROKEN_FENCE;
|
||||
import static net.runelite.api.ObjectID.BROKEN_FENCE_2618;
|
||||
import static net.runelite.api.ObjectID.BROKEN_RAFT;
|
||||
import static net.runelite.api.ObjectID.BROKEN_WALL_33344;
|
||||
import static net.runelite.api.ObjectID.CASTLE_WALL;
|
||||
import static net.runelite.api.ObjectID.CLIMBING_ROCKS;
|
||||
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_11948;
|
||||
import static net.runelite.api.ObjectID.CLIMBING_ROCKS_11949;
|
||||
import static net.runelite.api.ObjectID.CREVICE_16465;
|
||||
import static net.runelite.api.ObjectID.CREVICE_16539;
|
||||
import static net.runelite.api.ObjectID.CREVICE_16543;
|
||||
import static net.runelite.api.ObjectID.CREVICE_19043;
|
||||
import static net.runelite.api.ObjectID.CREVICE_30198;
|
||||
import static net.runelite.api.ObjectID.CREVICE_9739;
|
||||
import static net.runelite.api.ObjectID.CREVICE_9740;
|
||||
import static net.runelite.api.ObjectID.CROSSBOW_TREE_17062;
|
||||
import static net.runelite.api.ObjectID.CRUMBLING_WALL_24222;
|
||||
import static net.runelite.api.ObjectID.DARK_TUNNEL_10047;
|
||||
import static net.runelite.api.ObjectID.DENSE_FOREST;
|
||||
import static net.runelite.api.ObjectID.DENSE_FOREST_3938;
|
||||
import static net.runelite.api.ObjectID.DENSE_FOREST_3939;
|
||||
import static net.runelite.api.ObjectID.DENSE_FOREST_3998;
|
||||
import static net.runelite.api.ObjectID.DENSE_FOREST_3999;
|
||||
import static net.runelite.api.ObjectID.FALLEN_TREE_33192;
|
||||
import static net.runelite.api.ObjectID.FENCE_16518;
|
||||
import static net.runelite.api.ObjectID.GAP;
|
||||
import static net.runelite.api.ObjectID.GAP_2831;
|
||||
import static net.runelite.api.ObjectID.GAP_29326;
|
||||
import static net.runelite.api.ObjectID.HOLE_16520;
|
||||
import static net.runelite.api.ObjectID.HOLE_30966;
|
||||
import static net.runelite.api.ObjectID.HOLE_31481;
|
||||
import static net.runelite.api.ObjectID.HOLE_31482;
|
||||
import static net.runelite.api.ObjectID.ICE_CHUNKS_31822;
|
||||
import static net.runelite.api.ObjectID.ICE_CHUNKS_31990;
|
||||
import static net.runelite.api.ObjectID.JUTTING_WALL_17002;
|
||||
import static net.runelite.api.ObjectID.LADDER_30938;
|
||||
import static net.runelite.api.ObjectID.LADDER_30939;
|
||||
import static net.runelite.api.ObjectID.LADDER_30940;
|
||||
import static net.runelite.api.ObjectID.LADDER_30941;
|
||||
import static net.runelite.api.ObjectID.LEAVES;
|
||||
import static net.runelite.api.ObjectID.LEAVES_3924;
|
||||
import static net.runelite.api.ObjectID.LEAVES_3925;
|
||||
import static net.runelite.api.ObjectID.LEDGE_33190;
|
||||
import static net.runelite.api.ObjectID.LITTLE_BOULDER;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_16540;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_16541;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_16542;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_16546;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_16547;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_16548;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_20882;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_20884;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_23274;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_3929;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_3930;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_3931;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_3932;
|
||||
import static net.runelite.api.ObjectID.LOG_BALANCE_3933;
|
||||
import static net.runelite.api.ObjectID.LOOSE_RAILING;
|
||||
import static net.runelite.api.ObjectID.LOOSE_RAILING_2186;
|
||||
import static net.runelite.api.ObjectID.LOOSE_RAILING_28849;
|
||||
import static net.runelite.api.ObjectID.LOW_FENCE;
|
||||
import static net.runelite.api.ObjectID.MONKEYBARS_23566;
|
||||
import static net.runelite.api.ObjectID.MONKEYBARS_23567;
|
||||
import static net.runelite.api.ObjectID.MYSTERIOUS_PIPE;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_30767;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_30962;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_30964;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_16509;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_16511;
|
||||
import static net.runelite.api.ObjectID.OBSTACLE_PIPE_23140;
|
||||
import static net.runelite.api.ObjectID.ORNATE_RAILING;
|
||||
import static net.runelite.api.ObjectID.ORNATE_RAILING_17000;
|
||||
import static net.runelite.api.ObjectID.PILE_OF_RUBBLE_23563;
|
||||
import static net.runelite.api.ObjectID.PILE_OF_RUBBLE_23564;
|
||||
import static net.runelite.api.ObjectID.PILLAR_31561;
|
||||
import static net.runelite.api.ObjectID.PILLAR_31809;
|
||||
import static net.runelite.api.ObjectID.PIPE_21727;
|
||||
import static net.runelite.api.ObjectID.PIPE_21728;
|
||||
import static net.runelite.api.ObjectID.ROCKS;
|
||||
import static net.runelite.api.ObjectID.ROCKSLIDE_33184;
|
||||
import static net.runelite.api.ObjectID.ROCKSLIDE_33185;
|
||||
import static net.runelite.api.ObjectID.ROCKSLIDE_33191;
|
||||
import static net.runelite.api.ObjectID.ROCKS_14106;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16464;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16514;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16515;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16521;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16522;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16523;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16524;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16534;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16535;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16545;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16549;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16550;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16998;
|
||||
import static net.runelite.api.ObjectID.ROCKS_16999;
|
||||
import static net.runelite.api.ObjectID.ROCKS_17042;
|
||||
import static net.runelite.api.ObjectID.ROCKS_19849;
|
||||
import static net.runelite.api.ObjectID.ROCKS_2231;
|
||||
import static net.runelite.api.ObjectID.ROCKS_27984;
|
||||
import static net.runelite.api.ObjectID.ROCKS_27985;
|
||||
import static net.runelite.api.ObjectID.ROCKS_27987;
|
||||
import static net.runelite.api.ObjectID.ROCKS_27988;
|
||||
import static net.runelite.api.ObjectID.ROCKS_31757;
|
||||
import static net.runelite.api.ObjectID.ROCKS_31758;
|
||||
import static net.runelite.api.ObjectID.ROCKS_31759;
|
||||
import static net.runelite.api.ObjectID.ROCKS_34396;
|
||||
import static net.runelite.api.ObjectID.ROCKS_34397;
|
||||
import static net.runelite.api.ObjectID.ROCKS_34741;
|
||||
import static net.runelite.api.ObjectID.ROCKS_3748;
|
||||
import static net.runelite.api.ObjectID.ROCKS_3790;
|
||||
import static net.runelite.api.ObjectID.ROCKS_3791;
|
||||
import static net.runelite.api.ObjectID.ROCKS_3803;
|
||||
import static net.runelite.api.ObjectID.ROCKS_3804;
|
||||
import static net.runelite.api.ObjectID.ROCKS_6673;
|
||||
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26400;
|
||||
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26401;
|
||||
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26402;
|
||||
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26404;
|
||||
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26405;
|
||||
import static net.runelite.api.ObjectID.ROCKY_HANDHOLDS_26406;
|
||||
import static net.runelite.api.ObjectID.ROCK_16115;
|
||||
import static net.runelite.api.ObjectID.ROPESWING_23568;
|
||||
import static net.runelite.api.ObjectID.ROPESWING_23569;
|
||||
import static net.runelite.api.ObjectID.ROPE_ANCHOR;
|
||||
import static net.runelite.api.ObjectID.ROPE_ANCHOR_30917;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21306;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21307;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21308;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21309;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21310;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21311;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21312;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21313;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21314;
|
||||
import static net.runelite.api.ObjectID.ROPE_BRIDGE_21315;
|
||||
import static net.runelite.api.ObjectID.RUBBER_CAP_MUSHROOM;
|
||||
import static net.runelite.api.ObjectID.SPIKEY_CHAIN;
|
||||
import static net.runelite.api.ObjectID.SPIKEY_CHAIN_16538;
|
||||
import static net.runelite.api.ObjectID.STAIRS_31485;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONES;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONES_23646;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONES_23647;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_10663;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_11768;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_13504;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_14917;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_14918;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_16466;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_16513;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_16533;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_19040;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_19042;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21738;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_21739;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_29728;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_29729;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_29730;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_5948;
|
||||
import static net.runelite.api.ObjectID.STEPPING_STONE_5949;
|
||||
import static net.runelite.api.ObjectID.STEPS;
|
||||
import static net.runelite.api.ObjectID.STEPS_29993;
|
||||
import static net.runelite.api.ObjectID.STICKS;
|
||||
import static net.runelite.api.ObjectID.STILE;
|
||||
import static net.runelite.api.ObjectID.STILE_12982;
|
||||
import static net.runelite.api.ObjectID.STRANGE_FLOOR;
|
||||
import static net.runelite.api.ObjectID.STRANGE_FLOOR_16544;
|
||||
import static net.runelite.api.ObjectID.STRONG_TREE_17074;
|
||||
import static net.runelite.api.ObjectID.TIGHTGAP;
|
||||
import static net.runelite.api.ObjectID.TRELLIS_20056;
|
||||
import static net.runelite.api.ObjectID.TRIPWIRE;
|
||||
import static net.runelite.api.ObjectID.TUNNEL_30174;
|
||||
import static net.runelite.api.ObjectID.TUNNEL_30175;
|
||||
import static net.runelite.api.ObjectID.TUNNEL_30959;
|
||||
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL;
|
||||
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16528;
|
||||
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16529;
|
||||
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_16530;
|
||||
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_19032;
|
||||
import static net.runelite.api.ObjectID.UNDERWALL_TUNNEL_19036;
|
||||
import static net.runelite.api.ObjectID.VINE_26880;
|
||||
import static net.runelite.api.ObjectID.VINE_26882;
|
||||
import static net.runelite.api.ObjectID.WALL_17047;
|
||||
import static net.runelite.api.ObjectID.WALL_17049;
|
||||
import static net.runelite.api.ObjectID.WALL_17050;
|
||||
import static net.runelite.api.ObjectID.WEATHERED_WALL;
|
||||
import static net.runelite.api.ObjectID.WEATHERED_WALL_16526;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Getter
|
||||
public enum AgilityShortcut
|
||||
{
|
||||
GENERIC_SHORTCUT(1, "Shortcut", null,
|
||||
// Trollheim
|
||||
ROCKS_3790, ROCKS_3791,
|
||||
// Fremennik Slayer Cave
|
||||
STEPS_29993,
|
||||
// Fossil Island
|
||||
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
|
||||
// Brimhaven dungeon
|
||||
CREVICE_30198,
|
||||
// Lumbridge
|
||||
STILE_12982,
|
||||
// Gu'Tanoth Bridge
|
||||
GAP, GAP_2831,
|
||||
// Lumbridge Swamp Caves
|
||||
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
|
||||
// Morytania Pirate Ship
|
||||
ROCK_16115,
|
||||
// Lumber Yard
|
||||
BROKEN_FENCE_2618,
|
||||
// McGrubor's Wood
|
||||
LOOSE_RAILING,
|
||||
// Underwater Area Fossil Island
|
||||
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962,
|
||||
// Tree Gnome Village
|
||||
LOOSE_RAILING_2186,
|
||||
// Burgh de Rott
|
||||
LOW_FENCE,
|
||||
// Taverley
|
||||
STILE,
|
||||
// Asgarnian Ice Dungeon
|
||||
STEPS,
|
||||
// Fossil Island Wyvern Cave
|
||||
STAIRS_31485),
|
||||
// Trollheim
|
||||
ROCKS_3790, ROCKS_3791,
|
||||
// Fremennik Slayer Cave
|
||||
STEPS_29993,
|
||||
// Fossil Island
|
||||
LADDER_30938, LADDER_30939, LADDER_30940, LADDER_30941, RUBBER_CAP_MUSHROOM,
|
||||
// Brimhaven dungeon
|
||||
CREVICE_30198,
|
||||
// Lumbridge
|
||||
STILE_12982,
|
||||
// Gu'Tanoth Bridge
|
||||
GAP, GAP_2831,
|
||||
// Lumbridge Swamp Caves
|
||||
STEPPING_STONE_5948, STEPPING_STONE_5949, ROCKS_6673,
|
||||
// Morytania Pirate Ship
|
||||
ROCK_16115,
|
||||
// Lumber Yard
|
||||
BROKEN_FENCE_2618,
|
||||
// McGrubor's Wood
|
||||
LOOSE_RAILING,
|
||||
// Underwater Area Fossil Island
|
||||
TUNNEL_30959, HOLE_30966, OBSTACLE, OBSTACLE_30767, OBSTACLE_30964, OBSTACLE_30962,
|
||||
// Tree Gnome Village
|
||||
LOOSE_RAILING_2186,
|
||||
// Burgh de Rott
|
||||
LOW_FENCE,
|
||||
// Taverley
|
||||
STILE,
|
||||
// Asgarnian Ice Dungeon
|
||||
STEPS,
|
||||
// Fossil Island Wyvern Cave
|
||||
STAIRS_31485),
|
||||
BRIMHAVEN_DUNGEON_MEDIUM_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2698, 9491, 0), PIPE_21727),
|
||||
BRIMHAVEN_DUNGEON_PIPE_RETURN(1, "Pipe Squeeze", null, new WorldPoint(2655, 9573, 0), PIPE_21728),
|
||||
BRIMHAVEN_DUNGEON_STEPPING_STONES_RETURN(1, "Pipe Squeeze", null, STEPPING_STONE_21739),
|
||||
BRIMHAVEN_DUNGEON_LOG_BALANCE_RETURN(1, "Log Balance", null, LOG_BALANCE_20884),
|
||||
AGILITY_PYRAMID_ROCKS_WEST(1, "Rocks", null, CLIMBING_ROCKS_11948),
|
||||
CAIRN_ISLE_CLIMBING_ROCKS(1, "Rocks", null, CLIMBING_ROCKS),
|
||||
KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG ),
|
||||
FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222 ),
|
||||
KARAMJA_GLIDER_LOG(1, "Log Balance", new WorldPoint(2906, 3050, 0), A_WOODEN_LOG),
|
||||
FALADOR_CRUMBLING_WALL(5, "Crumbling Wall", new WorldPoint(2936, 3357, 0), CRUMBLING_WALL_24222),
|
||||
RIVER_LUM_GRAPPLE_WEST(8, "Grapple Broken Raft", new WorldPoint(3245, 3179, 0), BROKEN_RAFT),
|
||||
RIVER_LUM_GRAPPLE_EAST(8, "Grapple Broken Raft", new WorldPoint(3258, 3179, 0), BROKEN_RAFT),
|
||||
CORSAIR_COVE_ROCKS(10, "Rocks", new WorldPoint(2545, 2871, 0), ROCKS_31757),
|
||||
@@ -84,7 +288,7 @@ public enum AgilityShortcut
|
||||
GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP),
|
||||
CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809),
|
||||
EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566),
|
||||
TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15
|
||||
TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15
|
||||
YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL),
|
||||
YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056),
|
||||
COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274),
|
||||
@@ -128,7 +332,7 @@ public enum AgilityShortcut
|
||||
DEEP_WILDERNESS_DUNGEON_CREVICE_SOUTH(46, "Narrow Crevice", new WorldPoint(3045, 10327, 0), CREVICE_19043),
|
||||
TROLLHEIM_HARD_CLIFF_SCRAMBLE(47, "Rocks", new WorldPoint(2902, 3680, 0), ROCKS_16524),
|
||||
FREMENNIK_LOG_BALANCE(48, "Log Balance", new WorldPoint(2721, 3591, 0), LOG_BALANCE_16540, LOG_BALANCE_16541, LOG_BALANCE_16542),
|
||||
YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140),
|
||||
YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140),
|
||||
ARCEUUS_ESSENCE_MINE_BOULDER(49, "Boulder", new WorldPoint(1774, 3888, 0), BOULDER_27990),
|
||||
MORYTANIA_STEPPING_STONE(50, "Stepping Stone", new WorldPoint(3418, 3326, 0), STEPPING_STONE_13504),
|
||||
VARROCK_SEWERS_PIPE_SQUEEZE(51, "Pipe Squeeze", new WorldPoint(3152, 9905, 0), OBSTACLE_PIPE_16511),
|
||||
@@ -141,7 +345,7 @@ public enum AgilityShortcut
|
||||
ISAFDAR_FOREST_OBSTACLES(56, "Trap", null, DENSE_FOREST_3938, DENSE_FOREST_3939, DENSE_FOREST_3998, DENSE_FOREST_3999, DENSE_FOREST, LEAVES, LEAVES_3924, LEAVES_3925, STICKS, TRIPWIRE),
|
||||
RELEKKA_EAST_FENCE(57, "Fence", new WorldPoint(2688, 3697, 0), BROKEN_FENCE),
|
||||
YANILLE_DUNGEON_MONKEY_BARS(57, "Monkey Bars", null, MONKEYBARS_23567),
|
||||
PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null , WEATHERED_WALL, WEATHERED_WALL_16526),
|
||||
PHASMATYS_ECTOPOOL_SHORTCUT(58, "Weathered Wall", null, WEATHERED_WALL, WEATHERED_WALL_16526),
|
||||
ELVEN_OVERPASS_CLIFF_SCRAMBLE(59, "Rocks", new WorldPoint(2345, 3300, 0), ROCKS_16514, ROCKS_16515),
|
||||
WILDERNESS_GWD_CLIMB_EAST(60, "Rocks", new WorldPoint(2943, 3770, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
|
||||
WILDERNESS_GWD_CLIMB_WEST(60, "Rocks", new WorldPoint(2928, 3760, 0), ROCKY_HANDHOLDS_26400, ROCKY_HANDHOLDS_26401, ROCKY_HANDHOLDS_26402, ROCKY_HANDHOLDS_26404, ROCKY_HANDHOLDS_26405, ROCKY_HANDHOLDS_26406),
|
||||
@@ -169,22 +373,22 @@ public enum AgilityShortcut
|
||||
TAVERLEY_DUNGEON_PIPE_BLUE_DRAGON(70, "Pipe Squeeze", new WorldPoint(2886, 9798, 0), OBSTACLE_PIPE_16509),
|
||||
TAVERLEY_DUNGEON_ROCKS_NORTH(70, "Rocks", new WorldPoint(2887, 9823, 0), ROCKS, ROCKS_14106),
|
||||
TAVERLEY_DUNGEON_ROCKS_SOUTH(70, "Rocks", new WorldPoint(2887, 9631, 0), ROCKS, ROCKS_14106),
|
||||
FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole" , new WorldPoint(3713, 3827, 0), HOLE_31481, HOLE_31482),
|
||||
FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole" , new WorldPoint(3715, 3817, 0), HOLE_31481, HOLE_31482),
|
||||
FOSSIL_ISLAND_HARDWOOD_NORTH(70, "Hole", new WorldPoint(3713, 3827, 0), HOLE_31481, HOLE_31482),
|
||||
FOSSIL_ISLAND_HARDWOOD_SOUTH(70, "Hole", new WorldPoint(3715, 3817, 0), HOLE_31481, HOLE_31482),
|
||||
AL_KHARID_WINDOW(70, "Window", new WorldPoint(3293, 3158, 0), BROKEN_WALL_33344, BIG_WINDOW),
|
||||
GWD_SARADOMIN_ROPE_NORTH(70, "Rope Descent", new WorldPoint(2912, 5300, 0), NULL_26371),
|
||||
GWD_SARADOMIN_ROPE_SOUTH(70, "Rope Descent", new WorldPoint(2951, 5267, 0), NULL_26375),
|
||||
SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN ),
|
||||
SLAYER_TOWER_ADVANCED_CHAIN_FIRST(71, "Spiked Chain (Floor 2)", new WorldPoint(3447, 3578, 0), SPIKEY_CHAIN),
|
||||
SLAYER_TOWER_ADVANCED_CHAIN_SECOND(71, "Spiked Chain (Floor 3)", new WorldPoint(3446, 3576, 0), SPIKEY_CHAIN_16538),
|
||||
STRONGHOLD_SLAYER_CAVE_TUNNEL(72, "Tunnel", new WorldPoint(2431, 9806, 0), TUNNEL_30174, TUNNEL_30175),
|
||||
TROLL_STRONGHOLD_WALL_CLIMB(73, "Rocks", new WorldPoint(2841, 3694, 0), ROCKS_16464),
|
||||
ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985 ),
|
||||
ARCEUUS_ESSENSE_MINE_WEST(73, "Rock Climb", new WorldPoint(1742, 3853, 0), ROCKS_27984, ROCKS_27985),
|
||||
LAVA_DRAGON_ISLE_JUMP(74, "Stepping Stone", new WorldPoint(3200, 3807, 0), STEPPING_STONE_14918),
|
||||
REVENANT_CAVES_DEMONS_JUMP(75, "Jump", new WorldPoint(3199, 10135, 0), PILLAR_31561),
|
||||
REVENANT_CAVES_ANKOU_EAST(75, "Jump", new WorldPoint(3201, 10195, 0), PILLAR_31561),
|
||||
REVENANT_CAVES_ANKOU_NORTH(75, "Jump", new WorldPoint(3180, 10209, 0), PILLAR_31561),
|
||||
ZUL_ANDRA_ISLAND_CROSSING(76, "Stepping Stone", new WorldPoint(2156, 3073, 0), STEPPING_STONE_10663),
|
||||
SHILO_VILLAGE_STEPPING_STONES( 77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466),
|
||||
SHILO_VILLAGE_STEPPING_STONES(77, "Stepping Stones", new WorldPoint(2863, 2974, 0), STEPPING_STONE_16466),
|
||||
KHARAZI_JUNGLE_VINE_CLIMB(79, "Vine", new WorldPoint(2897, 2939, 0), NULL_26884, NULL_26886),
|
||||
TAVERLEY_DUNGEON_SPIKED_BLADES(80, "Strange Floor", new WorldPoint(2877, 9813, 0), STRANGE_FLOOR),
|
||||
SLAYER_DUNGEON_CHASM_JUMP(81, "Spiked Blades", new WorldPoint(2770, 10003, 0), STRANGE_FLOOR_16544),
|
||||
|
||||
@@ -1,84 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.game;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
public class AsyncBufferedImage extends BufferedImage
|
||||
{
|
||||
private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
|
||||
public AsyncBufferedImage(int width, int height, int imageType)
|
||||
{
|
||||
super(width, height, imageType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when the buffer has been changed
|
||||
*/
|
||||
public void changed()
|
||||
{
|
||||
for (Runnable r : listeners)
|
||||
{
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a function to be ran when the buffer has changed
|
||||
*/
|
||||
public void onChanged(Runnable r)
|
||||
{
|
||||
listeners.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls setIcon on c, ensuring it is repainted when this changes
|
||||
*/
|
||||
public void addTo(JButton c)
|
||||
{
|
||||
c.setIcon(makeIcon(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls setIcon on c, ensuring it is repainted when this changes
|
||||
*/
|
||||
public void addTo(JLabel c)
|
||||
{
|
||||
c.setIcon(makeIcon(c));
|
||||
}
|
||||
|
||||
private ImageIcon makeIcon(JComponent c)
|
||||
{
|
||||
listeners.add(c::repaint);
|
||||
return new ImageIcon(this);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.game;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
public class AsyncBufferedImage extends BufferedImage
|
||||
{
|
||||
private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
public AsyncBufferedImage(int width, int height, int imageType)
|
||||
{
|
||||
super(width, height, imageType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when the buffer has been changed
|
||||
*/
|
||||
public void changed()
|
||||
{
|
||||
for (Runnable r : listeners)
|
||||
{
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a function to be ran when the buffer has changed
|
||||
*/
|
||||
public void onChanged(Runnable r)
|
||||
{
|
||||
listeners.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls setIcon on c, ensuring it is repainted when this changes
|
||||
*/
|
||||
public void addTo(JButton c)
|
||||
{
|
||||
c.setIcon(makeIcon(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls setIcon on c, ensuring it is repainted when this changes
|
||||
*/
|
||||
public void addTo(JLabel c)
|
||||
{
|
||||
c.setIcon(makeIcon(c));
|
||||
}
|
||||
|
||||
private ImageIcon makeIcon(JComponent c)
|
||||
{
|
||||
listeners.add(c::repaint);
|
||||
return new ImageIcon(this);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,271 +1,675 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* 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.game;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import static net.runelite.api.ItemID.*;
|
||||
|
||||
/**
|
||||
* Converts untradeable items to it's tradeable counterparts
|
||||
*/
|
||||
public enum ItemMapping
|
||||
{
|
||||
// Barrows equipment
|
||||
ITEM_AHRIMS_HOOD(AHRIMS_HOOD, AHRIMS_HOOD_25, AHRIMS_HOOD_50, AHRIMS_HOOD_75, AHRIMS_HOOD_100),
|
||||
ITEM_AHRIMS_ROBETOP(AHRIMS_ROBETOP, AHRIMS_ROBETOP_25, AHRIMS_ROBETOP_50, AHRIMS_ROBETOP_75, AHRIMS_ROBETOP_100),
|
||||
ITEM_AHRIMS_ROBEBOTTOM(AHRIMS_ROBESKIRT, AHRIMS_ROBESKIRT_25, AHRIMS_ROBESKIRT_50, AHRIMS_ROBESKIRT_75, AHRIMS_ROBESKIRT_100),
|
||||
ITEM_AHRIMS_STAFF(AHRIMS_STAFF, AHRIMS_STAFF_25, AHRIMS_STAFF_50, AHRIMS_STAFF_75, AHRIMS_STAFF_100),
|
||||
ITEM_KARILS_COIF(KARILS_COIF, KARILS_COIF_25, KARILS_COIF_50, KARILS_COIF_75, KARILS_COIF_100),
|
||||
ITEM_KARILS_LEATHERTOP(KARILS_LEATHERTOP, KARILS_LEATHERTOP_25, KARILS_LEATHERTOP_50, KARILS_LEATHERTOP_75, KARILS_LEATHERTOP_100),
|
||||
ITEM_KARILS_LEATHERSKIRT(KARILS_LEATHERSKIRT, KARILS_LEATHERSKIRT_25, KARILS_LEATHERSKIRT_50, KARILS_LEATHERSKIRT_75, KARILS_LEATHERSKIRT_100),
|
||||
ITEM_KARILS_CROSSBOW(KARILS_CROSSBOW, KARILS_CROSSBOW_25, KARILS_CROSSBOW_50, KARILS_CROSSBOW_75, KARILS_CROSSBOW_100),
|
||||
ITEM_DHAROKS_HELM(DHAROKS_HELM, DHAROKS_HELM_25, DHAROKS_HELM_50, DHAROKS_HELM_75, DHAROKS_HELM_100),
|
||||
ITEM_DHAROKS_PLATEBODY(DHAROKS_PLATEBODY, DHAROKS_PLATEBODY_25, DHAROKS_PLATEBODY_50, DHAROKS_PLATEBODY_75, DHAROKS_PLATEBODY_100),
|
||||
ITEM_DHAROKS_PLATELEGS(DHAROKS_PLATELEGS, DHAROKS_PLATELEGS_25, DHAROKS_PLATELEGS_50, DHAROKS_PLATELEGS_75, DHAROKS_PLATELEGS_100),
|
||||
ITEM_DHARKS_GREATEAXE(DHAROKS_GREATAXE, DHAROKS_GREATAXE_25, DHAROKS_GREATAXE_50, DHAROKS_GREATAXE_75, DHAROKS_GREATAXE_100),
|
||||
ITEM_GUTHANS_HELM(GUTHANS_HELM, GUTHANS_HELM_25, GUTHANS_HELM_50, GUTHANS_HELM_75, GUTHANS_HELM_100),
|
||||
ITEM_GUTHANS_PLATEBODY(GUTHANS_PLATEBODY, GUTHANS_PLATEBODY_25, GUTHANS_PLATEBODY_50, GUTHANS_PLATEBODY_75, GUTHANS_PLATEBODY_100),
|
||||
ITEM_GUTHANS_CHAINSKIRT(GUTHANS_CHAINSKIRT, GUTHANS_CHAINSKIRT_25, GUTHANS_CHAINSKIRT_50, GUTHANS_CHAINSKIRT_75, GUTHANS_CHAINSKIRT_100),
|
||||
ITEM_GUTHANS_WARSPEAR(GUTHANS_WARSPEAR, GUTHANS_WARSPEAR_25, GUTHANS_WARSPEAR_50, GUTHANS_WARSPEAR_75, GUTHANS_WARSPEAR_100),
|
||||
ITEM_TORAGS_HELM(TORAGS_HELM, TORAGS_HELM_25, TORAGS_HELM_50, TORAGS_HELM_75, TORAGS_HELM_100),
|
||||
ITEM_TORAGS_PLATEBODY(TORAGS_PLATEBODY, TORAGS_PLATEBODY_25, TORAGS_PLATEBODY_50, TORAGS_PLATEBODY_75, TORAGS_PLATEBODY_100),
|
||||
ITEM_TORAGS_PLATELEGS(TORAGS_PLATELEGS, TORAGS_PLATELEGS_25, TORAGS_PLATELEGS_50, TORAGS_PLATELEGS_75, TORAGS_PLATELEGS_100),
|
||||
ITEM_TORAGS_HAMMERS(TORAGS_HAMMERS, TORAGS_HAMMERS_25, TORAGS_HAMMERS_50, TORAGS_HAMMERS_75, TORAGS_HAMMERS_100),
|
||||
ITEM_VERACS_HELM(VERACS_HELM, VERACS_HELM_25, VERACS_HELM_50, VERACS_HELM_75, VERACS_HELM_100),
|
||||
ITEM_VERACS_BRASSARD(VERACS_BRASSARD, VERACS_BRASSARD_25, VERACS_BRASSARD_50, VERACS_BRASSARD_75, VERACS_BRASSARD_100),
|
||||
ITEM_VERACS_PLATESKIRT(VERACS_PLATESKIRT, VERACS_PLATESKIRT_25, VERACS_PLATESKIRT_50, VERACS_PLATESKIRT_75, VERACS_PLATESKIRT_100),
|
||||
ITEM_VERACS_FLAIL(VERACS_FLAIL, VERACS_FLAIL_25, VERACS_FLAIL_50, VERACS_FLAIL_75, VERACS_FLAIL_100),
|
||||
|
||||
// Dragon equipment ornament kits
|
||||
ITEM_DRAGON_SCIMITAR(DRAGON_SCIMITAR, DRAGON_SCIMITAR_OR),
|
||||
ITEM_DRAGON_SCIMITAR_ORNAMENT_KIT(DRAGON_SCIMITAR_ORNAMENT_KIT, DRAGON_SCIMITAR_OR),
|
||||
ITEM_DRAGON_DEFENDER(DRAGON_DEFENDER_ORNAMENT_KIT, DRAGON_DEFENDER_T),
|
||||
ITEM_DRAGON_PICKAXE(DRAGON_PICKAXE, DRAGON_PICKAXE_12797),
|
||||
ITEM_DRAGON_KITESHIELD(DRAGON_KITESHIELD, DRAGON_KITESHIELD_G),
|
||||
ITEM_DRAGON_KITESHIELD_ORNAMENT_KIT(DRAGON_KITESHIELD_ORNAMENT_KIT, DRAGON_KITESHIELD_G),
|
||||
ITEM_DRAGON_FULL_HELM(DRAGON_FULL_HELM, DRAGON_FULL_HELM_G),
|
||||
ITEM_DRAGON_FULL_HELM_ORNAMENT_KIT(DRAGON_FULL_HELM_ORNAMENT_KIT, DRAGON_FULL_HELM_G),
|
||||
ITEM_DRAGON_CHAINBODY(DRAGON_CHAINBODY_3140, DRAGON_CHAINBODY_G),
|
||||
ITEM_DRAGON_CHAINBODY_ORNAMENT_KIT(DRAGON_CHAINBODY_ORNAMENT_KIT, DRAGON_CHAINBODY_G),
|
||||
ITEM_DRAGON_PLATEBODY(DRAGON_PLATEBODY, DRAGON_PLATEBODY_G),
|
||||
ITEM_DRAGON_PLATEBODY_ORNAMENT_KIT(DRAGON_PLATEBODY_ORNAMENT_KIT, DRAGON_PLATEBODY_G),
|
||||
ITEM_DRAGON_PLATESKIRT(DRAGON_PLATESKIRT, DRAGON_PLATESKIRT_G),
|
||||
ITEM_DRAGON_SKIRT_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATESKIRT_G),
|
||||
ITEM_DRAGON_PLATELEGS(DRAGON_PLATELEGS, DRAGON_PLATELEGS_G),
|
||||
ITEM_DRAGON_LEGS_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATELEGS_G),
|
||||
ITEM_DRAGON_SQ_SHIELD(DRAGON_SQ_SHIELD, DRAGON_SQ_SHIELD_G),
|
||||
ITEM_DRAGON_SQ_SHIELD_ORNAMENT_KIT(DRAGON_SQ_SHIELD_ORNAMENT_KIT, DRAGON_SQ_SHIELD_G),
|
||||
ITEM_DRAGON_BOOTS(DRAGON_BOOTS, DRAGON_BOOTS_G),
|
||||
ITEM_DRAGON_BOOTS_ORNAMENT_KIT(DRAGON_BOOTS_ORNAMENT_KIT, DRAGON_BOOTS_G),
|
||||
|
||||
// Godsword ornament kits
|
||||
ITEM_ARMADYL_GODSWORD(ARMADYL_GODSWORD, ARMADYL_GODSWORD_OR),
|
||||
ITEM_ARMADYL_GODSWORD_ORNAMENT_KIT(ARMADYL_GODSWORD_ORNAMENT_KIT, ARMADYL_GODSWORD_OR),
|
||||
ITEM_BANDOS_GODSWORD(BANDOS_GODSWORD, BANDOS_GODSWORD_OR),
|
||||
ITEM_BANDOS_GODSWORD_ORNAMENT_KIT(BANDOS_GODSWORD_ORNAMENT_KIT, BANDOS_GODSWORD_OR),
|
||||
ITEM_ZAMORAK_GODSWORD(ZAMORAK_GODSWORD, ZAMORAK_GODSWORD_OR),
|
||||
ITEM_ZAMORAK_GODSWORD_ORNAMENT_KIT(ZAMORAK_GODSWORD_ORNAMENT_KIT, ZAMORAK_GODSWORD_OR),
|
||||
ITEM_SARADOMIN_GODSWORD(SARADOMIN_GODSWORD, SARADOMIN_GODSWORD_OR),
|
||||
ITEM_SARADOMIN_GODSWORD_ORNAMENT_KIT(SARADOMIN_GODSWORD_ORNAMENT_KIT, SARADOMIN_GODSWORD_OR),
|
||||
|
||||
// Jewellery ornament kits
|
||||
ITEM_AMULET_OF_TORTURE(AMULET_OF_TORTURE, AMULET_OF_TORTURE_OR),
|
||||
ITEM_TORTURE_ORNAMENT_KIT(TORTURE_ORNAMENT_KIT, AMULET_OF_TORTURE_OR),
|
||||
ITEM_NECKLACE_OF_ANGUISH(NECKLACE_OF_ANGUISH, NECKLACE_OF_ANGUISH_OR),
|
||||
ITEM_ANGUISH_ORNAMENT_KIT(ANGUISH_ORNAMENT_KIT, NECKLACE_OF_ANGUISH_OR),
|
||||
ITEM_OCCULT_NECKLACE(OCCULT_NECKLACE, OCCULT_NECKLACE_OR),
|
||||
ITEM_OCCULT_ORNAMENT_KIT(OCCULT_ORNAMENT_KIT, OCCULT_NECKLACE_OR),
|
||||
ITE_AMULET_OF_FURY(AMULET_OF_FURY, AMULET_OF_FURY_OR),
|
||||
ITE_FURY_ORNAMENT_KIT(FURY_ORNAMENT_KIT, AMULET_OF_FURY_OR),
|
||||
|
||||
// Ensouled heads
|
||||
ITEM_ENSOULED_GOBLIN_HEAD(ENSOULED_GOBLIN_HEAD_13448, ENSOULED_GOBLIN_HEAD),
|
||||
ITEM_ENSOULED_MONKEY_HEAD(ENSOULED_MONKEY_HEAD_13451, ENSOULED_MONKEY_HEAD),
|
||||
ITEM_ENSOULED_IMP_HEAD(ENSOULED_IMP_HEAD_13454, ENSOULED_IMP_HEAD),
|
||||
ITEM_ENSOULED_MINOTAUR_HEAD(ENSOULED_MINOTAUR_HEAD_13457, ENSOULED_MINOTAUR_HEAD),
|
||||
ITEM_ENSOULED_SCORPION_HEAD(ENSOULED_SCORPION_HEAD_13460, ENSOULED_SCORPION_HEAD),
|
||||
ITEM_ENSOULED_BEAR_HEAD(ENSOULED_BEAR_HEAD_13463, ENSOULED_BEAR_HEAD),
|
||||
ITEM_ENSOULED_UNICORN_HEAD(ENSOULED_UNICORN_HEAD_13466, ENSOULED_UNICORN_HEAD),
|
||||
ITEM_ENSOULED_DOG_HEAD(ENSOULED_DOG_HEAD_13469, ENSOULED_DOG_HEAD),
|
||||
ITEM_ENSOULED_CHAOS_DRUID_HEAD(ENSOULED_CHAOS_DRUID_HEAD_13472, ENSOULED_CHAOS_DRUID_HEAD),
|
||||
ITEM_ENSOULED_GIANT_HEAD(ENSOULED_GIANT_HEAD_13475, ENSOULED_GIANT_HEAD),
|
||||
ITEM_ENSOULED_OGRE_HEAD(ENSOULED_OGRE_HEAD_13478, ENSOULED_OGRE_HEAD),
|
||||
ITEM_ENSOULED_ELF_HEAD(ENSOULED_ELF_HEAD_13481, ENSOULED_ELF_HEAD),
|
||||
ITEM_ENSOULED_TROLL_HEAD(ENSOULED_TROLL_HEAD_13484, ENSOULED_TROLL_HEAD),
|
||||
ITEM_ENSOULED_HORROR_HEAD(ENSOULED_HORROR_HEAD_13487, ENSOULED_HORROR_HEAD),
|
||||
ITEM_ENSOULED_KALPHITE_HEAD(ENSOULED_KALPHITE_HEAD_13490, ENSOULED_KALPHITE_HEAD),
|
||||
ITEM_ENSOULED_DAGANNOTH_HEAD(ENSOULED_DAGANNOTH_HEAD_13493, ENSOULED_DAGANNOTH_HEAD),
|
||||
ITEM_ENSOULED_BLOODVELD_HEAD(ENSOULED_BLOODVELD_HEAD_13496, ENSOULED_BLOODVELD_HEAD),
|
||||
ITEM_ENSOULED_TZHAAR_HEAD(ENSOULED_TZHAAR_HEAD_13499, ENSOULED_TZHAAR_HEAD),
|
||||
ITEM_ENSOULED_DEMON_HEAD(ENSOULED_DEMON_HEAD_13502, ENSOULED_DEMON_HEAD),
|
||||
ITEM_ENSOULED_AVIANSIE_HEAD(ENSOULED_AVIANSIE_HEAD_13505, ENSOULED_AVIANSIE_HEAD),
|
||||
ITEM_ENSOULED_ABYSSAL_HEAD(ENSOULED_ABYSSAL_HEAD_13508, ENSOULED_ABYSSAL_HEAD),
|
||||
ITEM_ENSOULED_DRAGON_HEAD(ENSOULED_DRAGON_HEAD_13511, ENSOULED_DRAGON_HEAD),
|
||||
|
||||
// Imbued rings
|
||||
ITEM_BERSERKER_RING(BERSERKER_RING, BERSERKER_RING_I),
|
||||
ITEM_SEERS_RING(SEERS_RING, SEERS_RING_I),
|
||||
ITEM_WARRIOR_RING(WARRIOR_RING, WARRIOR_RING_I),
|
||||
ITEM_ARCHERS_RING(ARCHERS_RING, ARCHERS_RING_I),
|
||||
ITEM_TREASONOUS_RING(TREASONOUS_RING, TREASONOUS_RING_I),
|
||||
ITEM_TYRANNICAL_RING(TYRANNICAL_RING, TYRANNICAL_RING_I),
|
||||
ITEM_RING_OF_THE_GODS(RING_OF_THE_GODS, RING_OF_THE_GODS_I),
|
||||
ITEM_RING_OF_SUFFERING(RING_OF_SUFFERING, RING_OF_SUFFERING_I, RING_OF_SUFFERING_R, RING_OF_SUFFERING_RI),
|
||||
ITEM_GRANITE_RING(GRANITE_RING, GRANITE_RING_I),
|
||||
|
||||
// Bounty hunter
|
||||
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848),
|
||||
ITEM_MAGIC_SHORTBOW(MAGIC_SHORTBOW, MAGIC_SHORTBOW_I),
|
||||
ITEM_SARADOMINS_BLESSED_SWORD(SARADOMINS_TEAR, SARADOMINS_BLESSED_SWORD),
|
||||
|
||||
// Jewellery with charges
|
||||
ITEM_RING_OF_WEALTH(RING_OF_WEALTH, RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
|
||||
ITEM_AMULET_OF_GLORY(AMULET_OF_GLORY, AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5),
|
||||
ITEM_AMULET_OF_GLORY_T(AMULET_OF_GLORY_T, AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5),
|
||||
ITEM_SKILLS_NECKLACE(SKILLS_NECKLACE, SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5),
|
||||
ITEM_RING_OF_DUELING(RING_OF_DUELING8, RING_OF_DUELING1, RING_OF_DUELING2, RING_OF_DUELING3, RING_OF_DUELING4, RING_OF_DUELING5, RING_OF_DUELING6, RING_OF_DUELING7),
|
||||
ITEM_GAMES_NECKLACE(GAMES_NECKLACE8, GAMES_NECKLACE1, GAMES_NECKLACE2, GAMES_NECKLACE3, GAMES_NECKLACE4, GAMES_NECKLACE5, GAMES_NECKLACE6, GAMES_NECKLACE7),
|
||||
|
||||
// Degradable/charged weaponry/armour
|
||||
ITEM_ABYSSAL_WHIP(ABYSSAL_WHIP, VOLCANIC_ABYSSAL_WHIP, FROZEN_ABYSSAL_WHIP),
|
||||
ITEM_KRAKEN_TENTACLE(KRAKEN_TENTACLE, ABYSSAL_TENTACLE),
|
||||
ITEM_TRIDENT_OF_THE_SEAS(UNCHARGED_TRIDENT, TRIDENT_OF_THE_SEAS),
|
||||
ITEM_TRIDENT_OF_THE_SEAS_E(UNCHARGED_TRIDENT_E, TRIDENT_OF_THE_SEAS_E),
|
||||
ITEM_TRIDENT_OF_THE_SWAMP(UNCHARGED_TOXIC_TRIDENT, TRIDENT_OF_THE_SWAMP),
|
||||
ITEM_TRIDENT_OF_THE_SWAMP_E(UNCHARGED_TOXIC_TRIDENT_E, TRIDENT_OF_THE_SWAMP_E),
|
||||
ITEM_TOXIC_BLOWPIPE(TOXIC_BLOWPIPE_EMPTY, TOXIC_BLOWPIPE),
|
||||
ITEM_TOXIC_STAFF_OFF_THE_DEAD(TOXIC_STAFF_UNCHARGED, TOXIC_STAFF_OF_THE_DEAD),
|
||||
ITEM_SERPENTINE_HELM(SERPENTINE_HELM_UNCHARGED, SERPENTINE_HELM, TANZANITE_HELM_UNCHARGED, TANZANITE_HELM, MAGMA_HELM_UNCHARGED, MAGMA_HELM),
|
||||
ITEM_DRAGONFIRE_SHIELD(DRAGONFIRE_SHIELD_11284, DRAGONFIRE_SHIELD),
|
||||
ITEM_DRAGONFIRE_WARD(DRAGONFIRE_WARD_22003, DRAGONFIRE_WARD),
|
||||
ITEM_ANCIENT_WYVERN_SHIELD(ANCIENT_WYVERN_SHIELD_21634, ANCIENT_WYVERN_SHIELD),
|
||||
ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF),
|
||||
ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR),
|
||||
ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE),
|
||||
ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW),
|
||||
ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE),
|
||||
ITEM_THAMMARONS_SCEPTRE(THAMMARONS_SCEPTRE_U, THAMMARONS_SCEPTRE),
|
||||
|
||||
// Infinity colour kits
|
||||
ITEM_INFINITY_TOP(INFINITY_TOP, INFINITY_TOP_10605, INFINITY_TOP_20574, DARK_INFINITY_TOP, LIGHT_INFINITY_TOP),
|
||||
ITEM_INFINITY_TOP_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_TOP),
|
||||
ITEM_INFINITY_TOP_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_TOP),
|
||||
ITEM_INFINITY_BOTTOMS(INFINITY_BOTTOMS, INFINITY_BOTTOMS_20575, DARK_INFINITY_BOTTOMS, LIGHT_INFINITY_BOTTOMS),
|
||||
ITEM_INFINITY_BOTTOMS_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_BOTTOMS),
|
||||
ITEM_INFINITY_BOTTOMS_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_BOTTOMS),
|
||||
ITEM_INFINITY_HAT(INFINITY_HAT, DARK_INFINITY_HAT, LIGHT_INFINITY_HAT),
|
||||
ITEM_INFINITY_HAT_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_HAT),
|
||||
ITEM_INFINITY_HAT_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_HAT),
|
||||
|
||||
// Miscellaneous ornament kits
|
||||
ITEM_DARK_BOW(DARK_BOW, DARK_BOW_12765, DARK_BOW_12766, DARK_BOW_12767, DARK_BOW_12768, DARK_BOW_20408),
|
||||
ITEM_ODIUM_WARD(ODIUM_WARD, ODIUM_WARD_12807),
|
||||
ITEM_MALEDICTION_WARD(MALEDICTION_WARD, MALEDICTION_WARD_12806),
|
||||
ITEM_STEAM_BATTLESTAFF(STEAM_BATTLESTAFF, STEAM_BATTLESTAFF_12795),
|
||||
ITEM_LAVA_BATTLESTAFF(LAVA_BATTLESTAFF, LAVA_BATTLESTAFF_21198),
|
||||
|
||||
// Slayer helm/black mask
|
||||
ITEM_BLACK_MASK(
|
||||
BLACK_MASK, BLACK_MASK_I, BLACK_MASK_1, BLACK_MASK_1_I, BLACK_MASK_2, BLACK_MASK_2_I, BLACK_MASK_3, BLACK_MASK_3_I, BLACK_MASK_4, BLACK_MASK_4_I, BLACK_MASK_5,
|
||||
BLACK_MASK_5_I, BLACK_MASK_6, BLACK_MASK_6_I, BLACK_MASK_7, BLACK_MASK_7_I, BLACK_MASK_8, BLACK_MASK_8_I, BLACK_MASK_9, BLACK_MASK_9_I, BLACK_MASK_10_I,
|
||||
SLAYER_HELMET, SLAYER_HELMET_I, BLACK_SLAYER_HELMET, BLACK_SLAYER_HELMET_I, PURPLE_SLAYER_HELMET, PURPLE_SLAYER_HELMET_I, RED_SLAYER_HELMET, RED_SLAYER_HELMET_I,
|
||||
GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I),
|
||||
|
||||
// Pharaoh's Sceptres
|
||||
ITEM_PHARAOHS_SCEPTRE_1(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_1),
|
||||
ITEM_PHARAOHS_SCEPTRE_2(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_2),
|
||||
ITEM_PHARAOHS_SCEPTRE_4(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_4),
|
||||
ITEM_PHARAOHS_SCEPTRE_5(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_5),
|
||||
ITEM_PHARAOHS_SCEPTRE_6(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_6),
|
||||
ITEM_PHARAOHS_SCEPTRE_7(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_7),
|
||||
ITEM_PHARAOHS_SCEPTRE_8(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_8),
|
||||
|
||||
// Revertible items
|
||||
ITEM_HYDRA_LEATHER(HYDRA_LEATHER, FEROCIOUS_GLOVES),
|
||||
ITEM_HYDRA_TAIL(HYDRA_TAIL, BONECRUSHER_NECKLACE),
|
||||
ITEM_DRAGONBONE_NECKLACE(DRAGONBONE_NECKLACE, BONECRUSHER_NECKLACE),
|
||||
ITEM_BOTTOMLESS_COMPOST_BUCKET(BOTTOMLESS_COMPOST_BUCKET, BOTTOMLESS_COMPOST_BUCKET_22997);
|
||||
|
||||
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create();
|
||||
private final int tradeableItem;
|
||||
private final int[] untradableItems;
|
||||
|
||||
static
|
||||
{
|
||||
for (final ItemMapping item : values())
|
||||
{
|
||||
for (int itemId : item.untradableItems)
|
||||
{
|
||||
MAPPINGS.put(itemId, item.tradeableItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemMapping(int tradeableItem, int... untradableItems)
|
||||
{
|
||||
this.tradeableItem = tradeableItem;
|
||||
this.untradableItems = untradableItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection of items that are mapped from single item id.
|
||||
*
|
||||
* @param itemId the item id
|
||||
* @return the collection
|
||||
*/
|
||||
public static Collection<Integer> map(int itemId)
|
||||
{
|
||||
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
||||
|
||||
if (mapping == null || mapping.isEmpty())
|
||||
{
|
||||
return Collections.singleton(itemId);
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map an item from its untradeable version to its tradeable version
|
||||
*
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
public static int mapFirst(int itemId)
|
||||
{
|
||||
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
||||
|
||||
if (mapping == null || mapping.isEmpty())
|
||||
{
|
||||
return itemId;
|
||||
}
|
||||
|
||||
return mapping.iterator().next();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* 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.game;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import static net.runelite.api.ItemID.ABYSSAL_TENTACLE;
|
||||
import static net.runelite.api.ItemID.ABYSSAL_WHIP;
|
||||
import static net.runelite.api.ItemID.AHRIMS_HOOD;
|
||||
import static net.runelite.api.ItemID.AHRIMS_HOOD_100;
|
||||
import static net.runelite.api.ItemID.AHRIMS_HOOD_25;
|
||||
import static net.runelite.api.ItemID.AHRIMS_HOOD_50;
|
||||
import static net.runelite.api.ItemID.AHRIMS_HOOD_75;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_100;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_25;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_50;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBESKIRT_75;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBETOP;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_100;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_25;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_50;
|
||||
import static net.runelite.api.ItemID.AHRIMS_ROBETOP_75;
|
||||
import static net.runelite.api.ItemID.AHRIMS_STAFF;
|
||||
import static net.runelite.api.ItemID.AHRIMS_STAFF_100;
|
||||
import static net.runelite.api.ItemID.AHRIMS_STAFF_25;
|
||||
import static net.runelite.api.ItemID.AHRIMS_STAFF_50;
|
||||
import static net.runelite.api.ItemID.AHRIMS_STAFF_75;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_FURY;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_FURY_OR;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY1;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY2;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY3;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY5;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T1;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T2;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T3;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_GLORY_T5;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_TORTURE;
|
||||
import static net.runelite.api.ItemID.AMULET_OF_TORTURE_OR;
|
||||
import static net.runelite.api.ItemID.ANCIENT_WYVERN_SHIELD;
|
||||
import static net.runelite.api.ItemID.ANCIENT_WYVERN_SHIELD_21634;
|
||||
import static net.runelite.api.ItemID.ANGUISH_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.ARCHERS_RING;
|
||||
import static net.runelite.api.ItemID.ARCHERS_RING_I;
|
||||
import static net.runelite.api.ItemID.ARMADYL_GODSWORD;
|
||||
import static net.runelite.api.ItemID.ARMADYL_GODSWORD_OR;
|
||||
import static net.runelite.api.ItemID.ARMADYL_GODSWORD_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.BANDOS_GODSWORD;
|
||||
import static net.runelite.api.ItemID.BANDOS_GODSWORD_OR;
|
||||
import static net.runelite.api.ItemID.BANDOS_GODSWORD_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.BERSERKER_RING;
|
||||
import static net.runelite.api.ItemID.BERSERKER_RING_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_1;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_10_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_1_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_2;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_2_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_3;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_3_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_4;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_4_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_5;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_5_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_6;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_6_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_7;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_7_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_8;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_8_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_9;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_9_I;
|
||||
import static net.runelite.api.ItemID.BLACK_MASK_I;
|
||||
import static net.runelite.api.ItemID.BLACK_SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.BLACK_SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.BONECRUSHER_NECKLACE;
|
||||
import static net.runelite.api.ItemID.BOTTOMLESS_COMPOST_BUCKET;
|
||||
import static net.runelite.api.ItemID.BOTTOMLESS_COMPOST_BUCKET_22997;
|
||||
import static net.runelite.api.ItemID.CRAWS_BOW;
|
||||
import static net.runelite.api.ItemID.CRAWS_BOW_U;
|
||||
import static net.runelite.api.ItemID.DARK_BOW;
|
||||
import static net.runelite.api.ItemID.DARK_BOW_12765;
|
||||
import static net.runelite.api.ItemID.DARK_BOW_12766;
|
||||
import static net.runelite.api.ItemID.DARK_BOW_12767;
|
||||
import static net.runelite.api.ItemID.DARK_BOW_12768;
|
||||
import static net.runelite.api.ItemID.DARK_BOW_20408;
|
||||
import static net.runelite.api.ItemID.DARK_INFINITY_BOTTOMS;
|
||||
import static net.runelite.api.ItemID.DARK_INFINITY_COLOUR_KIT;
|
||||
import static net.runelite.api.ItemID.DARK_INFINITY_HAT;
|
||||
import static net.runelite.api.ItemID.DARK_INFINITY_TOP;
|
||||
import static net.runelite.api.ItemID.DHAROKS_GREATAXE;
|
||||
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_100;
|
||||
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_25;
|
||||
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_50;
|
||||
import static net.runelite.api.ItemID.DHAROKS_GREATAXE_75;
|
||||
import static net.runelite.api.ItemID.DHAROKS_HELM;
|
||||
import static net.runelite.api.ItemID.DHAROKS_HELM_100;
|
||||
import static net.runelite.api.ItemID.DHAROKS_HELM_25;
|
||||
import static net.runelite.api.ItemID.DHAROKS_HELM_50;
|
||||
import static net.runelite.api.ItemID.DHAROKS_HELM_75;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_100;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_25;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_50;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATEBODY_75;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_100;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_25;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_50;
|
||||
import static net.runelite.api.ItemID.DHAROKS_PLATELEGS_75;
|
||||
import static net.runelite.api.ItemID.DRAGONBONE_NECKLACE;
|
||||
import static net.runelite.api.ItemID.DRAGONFIRE_SHIELD;
|
||||
import static net.runelite.api.ItemID.DRAGONFIRE_SHIELD_11284;
|
||||
import static net.runelite.api.ItemID.DRAGONFIRE_WARD;
|
||||
import static net.runelite.api.ItemID.DRAGONFIRE_WARD_22003;
|
||||
import static net.runelite.api.ItemID.DRAGON_BOOTS;
|
||||
import static net.runelite.api.ItemID.DRAGON_BOOTS_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_BOOTS_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_CHAINBODY_3140;
|
||||
import static net.runelite.api.ItemID.DRAGON_CHAINBODY_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_CHAINBODY_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_DEFENDER_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_DEFENDER_T;
|
||||
import static net.runelite.api.ItemID.DRAGON_FULL_HELM;
|
||||
import static net.runelite.api.ItemID.DRAGON_FULL_HELM_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_FULL_HELM_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_KITESHIELD;
|
||||
import static net.runelite.api.ItemID.DRAGON_KITESHIELD_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_KITESHIELD_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_LEGSSKIRT_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_PICKAXE;
|
||||
import static net.runelite.api.ItemID.DRAGON_PICKAXE_12797;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATEBODY;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATEBODY_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATEBODY_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATELEGS;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATELEGS_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATESKIRT;
|
||||
import static net.runelite.api.ItemID.DRAGON_PLATESKIRT_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_SCIMITAR;
|
||||
import static net.runelite.api.ItemID.DRAGON_SCIMITAR_OR;
|
||||
import static net.runelite.api.ItemID.DRAGON_SCIMITAR_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD;
|
||||
import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD_G;
|
||||
import static net.runelite.api.ItemID.DRAGON_SQ_SHIELD_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.ENSOULED_ABYSSAL_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_ABYSSAL_HEAD_13508;
|
||||
import static net.runelite.api.ItemID.ENSOULED_AVIANSIE_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_AVIANSIE_HEAD_13505;
|
||||
import static net.runelite.api.ItemID.ENSOULED_BEAR_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_BEAR_HEAD_13463;
|
||||
import static net.runelite.api.ItemID.ENSOULED_BLOODVELD_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_BLOODVELD_HEAD_13496;
|
||||
import static net.runelite.api.ItemID.ENSOULED_CHAOS_DRUID_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DAGANNOTH_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DAGANNOTH_HEAD_13493;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DEMON_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DEMON_HEAD_13502;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DOG_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DOG_HEAD_13469;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DRAGON_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_DRAGON_HEAD_13511;
|
||||
import static net.runelite.api.ItemID.ENSOULED_ELF_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_ELF_HEAD_13481;
|
||||
import static net.runelite.api.ItemID.ENSOULED_GIANT_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_GIANT_HEAD_13475;
|
||||
import static net.runelite.api.ItemID.ENSOULED_GOBLIN_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_GOBLIN_HEAD_13448;
|
||||
import static net.runelite.api.ItemID.ENSOULED_HORROR_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_HORROR_HEAD_13487;
|
||||
import static net.runelite.api.ItemID.ENSOULED_IMP_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_IMP_HEAD_13454;
|
||||
import static net.runelite.api.ItemID.ENSOULED_KALPHITE_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_KALPHITE_HEAD_13490;
|
||||
import static net.runelite.api.ItemID.ENSOULED_MINOTAUR_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_MINOTAUR_HEAD_13457;
|
||||
import static net.runelite.api.ItemID.ENSOULED_MONKEY_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_MONKEY_HEAD_13451;
|
||||
import static net.runelite.api.ItemID.ENSOULED_OGRE_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_OGRE_HEAD_13478;
|
||||
import static net.runelite.api.ItemID.ENSOULED_SCORPION_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_SCORPION_HEAD_13460;
|
||||
import static net.runelite.api.ItemID.ENSOULED_TROLL_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_TROLL_HEAD_13484;
|
||||
import static net.runelite.api.ItemID.ENSOULED_TZHAAR_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_TZHAAR_HEAD_13499;
|
||||
import static net.runelite.api.ItemID.ENSOULED_UNICORN_HEAD;
|
||||
import static net.runelite.api.ItemID.ENSOULED_UNICORN_HEAD_13466;
|
||||
import static net.runelite.api.ItemID.FEROCIOUS_GLOVES;
|
||||
import static net.runelite.api.ItemID.FROZEN_ABYSSAL_WHIP;
|
||||
import static net.runelite.api.ItemID.FURY_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE1;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE2;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE3;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE4;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE5;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE6;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE7;
|
||||
import static net.runelite.api.ItemID.GAMES_NECKLACE8;
|
||||
import static net.runelite.api.ItemID.GRANITE_MAUL;
|
||||
import static net.runelite.api.ItemID.GRANITE_MAUL_12848;
|
||||
import static net.runelite.api.ItemID.GRANITE_RING;
|
||||
import static net.runelite.api.ItemID.GRANITE_RING_I;
|
||||
import static net.runelite.api.ItemID.GREEN_SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.GREEN_SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT;
|
||||
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_100;
|
||||
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_25;
|
||||
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_50;
|
||||
import static net.runelite.api.ItemID.GUTHANS_CHAINSKIRT_75;
|
||||
import static net.runelite.api.ItemID.GUTHANS_HELM;
|
||||
import static net.runelite.api.ItemID.GUTHANS_HELM_100;
|
||||
import static net.runelite.api.ItemID.GUTHANS_HELM_25;
|
||||
import static net.runelite.api.ItemID.GUTHANS_HELM_50;
|
||||
import static net.runelite.api.ItemID.GUTHANS_HELM_75;
|
||||
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY;
|
||||
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_100;
|
||||
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_25;
|
||||
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_50;
|
||||
import static net.runelite.api.ItemID.GUTHANS_PLATEBODY_75;
|
||||
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR;
|
||||
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_100;
|
||||
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_25;
|
||||
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_50;
|
||||
import static net.runelite.api.ItemID.GUTHANS_WARSPEAR_75;
|
||||
import static net.runelite.api.ItemID.HYDRA_LEATHER;
|
||||
import static net.runelite.api.ItemID.HYDRA_SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.HYDRA_SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.HYDRA_TAIL;
|
||||
import static net.runelite.api.ItemID.INFINITY_BOTTOMS;
|
||||
import static net.runelite.api.ItemID.INFINITY_BOTTOMS_20575;
|
||||
import static net.runelite.api.ItemID.INFINITY_HAT;
|
||||
import static net.runelite.api.ItemID.INFINITY_TOP;
|
||||
import static net.runelite.api.ItemID.INFINITY_TOP_10605;
|
||||
import static net.runelite.api.ItemID.INFINITY_TOP_20574;
|
||||
import static net.runelite.api.ItemID.KARILS_COIF;
|
||||
import static net.runelite.api.ItemID.KARILS_COIF_100;
|
||||
import static net.runelite.api.ItemID.KARILS_COIF_25;
|
||||
import static net.runelite.api.ItemID.KARILS_COIF_50;
|
||||
import static net.runelite.api.ItemID.KARILS_COIF_75;
|
||||
import static net.runelite.api.ItemID.KARILS_CROSSBOW;
|
||||
import static net.runelite.api.ItemID.KARILS_CROSSBOW_100;
|
||||
import static net.runelite.api.ItemID.KARILS_CROSSBOW_25;
|
||||
import static net.runelite.api.ItemID.KARILS_CROSSBOW_50;
|
||||
import static net.runelite.api.ItemID.KARILS_CROSSBOW_75;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_100;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_25;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_50;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERSKIRT_75;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERTOP;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_100;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_25;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_50;
|
||||
import static net.runelite.api.ItemID.KARILS_LEATHERTOP_75;
|
||||
import static net.runelite.api.ItemID.KRAKEN_TENTACLE;
|
||||
import static net.runelite.api.ItemID.LAVA_BATTLESTAFF;
|
||||
import static net.runelite.api.ItemID.LAVA_BATTLESTAFF_21198;
|
||||
import static net.runelite.api.ItemID.LIGHT_INFINITY_BOTTOMS;
|
||||
import static net.runelite.api.ItemID.LIGHT_INFINITY_COLOUR_KIT;
|
||||
import static net.runelite.api.ItemID.LIGHT_INFINITY_HAT;
|
||||
import static net.runelite.api.ItemID.LIGHT_INFINITY_TOP;
|
||||
import static net.runelite.api.ItemID.MAGIC_SHORTBOW;
|
||||
import static net.runelite.api.ItemID.MAGIC_SHORTBOW_I;
|
||||
import static net.runelite.api.ItemID.MAGMA_HELM;
|
||||
import static net.runelite.api.ItemID.MAGMA_HELM_UNCHARGED;
|
||||
import static net.runelite.api.ItemID.MALEDICTION_WARD;
|
||||
import static net.runelite.api.ItemID.MALEDICTION_WARD_12806;
|
||||
import static net.runelite.api.ItemID.NECKLACE_OF_ANGUISH;
|
||||
import static net.runelite.api.ItemID.NECKLACE_OF_ANGUISH_OR;
|
||||
import static net.runelite.api.ItemID.OCCULT_NECKLACE;
|
||||
import static net.runelite.api.ItemID.OCCULT_NECKLACE_OR;
|
||||
import static net.runelite.api.ItemID.OCCULT_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.ODIUM_WARD;
|
||||
import static net.runelite.api.ItemID.ODIUM_WARD_12807;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_1;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_2;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_4;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_5;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_6;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_7;
|
||||
import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_8;
|
||||
import static net.runelite.api.ItemID.PURPLE_SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.PURPLE_SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.RED_SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.RED_SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING1;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING2;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING3;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING4;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING5;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING6;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING7;
|
||||
import static net.runelite.api.ItemID.RING_OF_DUELING8;
|
||||
import static net.runelite.api.ItemID.RING_OF_SUFFERING;
|
||||
import static net.runelite.api.ItemID.RING_OF_SUFFERING_I;
|
||||
import static net.runelite.api.ItemID.RING_OF_SUFFERING_R;
|
||||
import static net.runelite.api.ItemID.RING_OF_SUFFERING_RI;
|
||||
import static net.runelite.api.ItemID.RING_OF_THE_GODS;
|
||||
import static net.runelite.api.ItemID.RING_OF_THE_GODS_I;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_1;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_2;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_3;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_4;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_I;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_I1;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_I2;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_I3;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_I4;
|
||||
import static net.runelite.api.ItemID.RING_OF_WEALTH_I5;
|
||||
import static net.runelite.api.ItemID.SANGUINESTI_STAFF;
|
||||
import static net.runelite.api.ItemID.SANGUINESTI_STAFF_UNCHARGED;
|
||||
import static net.runelite.api.ItemID.SARADOMINS_BLESSED_SWORD;
|
||||
import static net.runelite.api.ItemID.SARADOMINS_TEAR;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_GODSWORD;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_GODSWORD_OR;
|
||||
import static net.runelite.api.ItemID.SARADOMIN_GODSWORD_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.SCYTHE_OF_VITUR;
|
||||
import static net.runelite.api.ItemID.SCYTHE_OF_VITUR_UNCHARGED;
|
||||
import static net.runelite.api.ItemID.SEERS_RING;
|
||||
import static net.runelite.api.ItemID.SEERS_RING_I;
|
||||
import static net.runelite.api.ItemID.SERPENTINE_HELM;
|
||||
import static net.runelite.api.ItemID.SERPENTINE_HELM_UNCHARGED;
|
||||
import static net.runelite.api.ItemID.SKILLS_NECKLACE;
|
||||
import static net.runelite.api.ItemID.SKILLS_NECKLACE1;
|
||||
import static net.runelite.api.ItemID.SKILLS_NECKLACE2;
|
||||
import static net.runelite.api.ItemID.SKILLS_NECKLACE3;
|
||||
import static net.runelite.api.ItemID.SKILLS_NECKLACE5;
|
||||
import static net.runelite.api.ItemID.SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.STEAM_BATTLESTAFF;
|
||||
import static net.runelite.api.ItemID.STEAM_BATTLESTAFF_12795;
|
||||
import static net.runelite.api.ItemID.TANZANITE_HELM;
|
||||
import static net.runelite.api.ItemID.TANZANITE_HELM_UNCHARGED;
|
||||
import static net.runelite.api.ItemID.THAMMARONS_SCEPTRE;
|
||||
import static net.runelite.api.ItemID.THAMMARONS_SCEPTRE_U;
|
||||
import static net.runelite.api.ItemID.TOME_OF_FIRE;
|
||||
import static net.runelite.api.ItemID.TOME_OF_FIRE_EMPTY;
|
||||
import static net.runelite.api.ItemID.TORAGS_HAMMERS;
|
||||
import static net.runelite.api.ItemID.TORAGS_HAMMERS_100;
|
||||
import static net.runelite.api.ItemID.TORAGS_HAMMERS_25;
|
||||
import static net.runelite.api.ItemID.TORAGS_HAMMERS_50;
|
||||
import static net.runelite.api.ItemID.TORAGS_HAMMERS_75;
|
||||
import static net.runelite.api.ItemID.TORAGS_HELM;
|
||||
import static net.runelite.api.ItemID.TORAGS_HELM_100;
|
||||
import static net.runelite.api.ItemID.TORAGS_HELM_25;
|
||||
import static net.runelite.api.ItemID.TORAGS_HELM_50;
|
||||
import static net.runelite.api.ItemID.TORAGS_HELM_75;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATEBODY;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_100;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_25;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_50;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATEBODY_75;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATELEGS;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_100;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_25;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_50;
|
||||
import static net.runelite.api.ItemID.TORAGS_PLATELEGS_75;
|
||||
import static net.runelite.api.ItemID.TORTURE_ORNAMENT_KIT;
|
||||
import static net.runelite.api.ItemID.TOXIC_BLOWPIPE;
|
||||
import static net.runelite.api.ItemID.TOXIC_BLOWPIPE_EMPTY;
|
||||
import static net.runelite.api.ItemID.TOXIC_STAFF_OF_THE_DEAD;
|
||||
import static net.runelite.api.ItemID.TOXIC_STAFF_UNCHARGED;
|
||||
import static net.runelite.api.ItemID.TREASONOUS_RING;
|
||||
import static net.runelite.api.ItemID.TREASONOUS_RING_I;
|
||||
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SEAS;
|
||||
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SEAS_E;
|
||||
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SWAMP;
|
||||
import static net.runelite.api.ItemID.TRIDENT_OF_THE_SWAMP_E;
|
||||
import static net.runelite.api.ItemID.TURQUOISE_SLAYER_HELMET;
|
||||
import static net.runelite.api.ItemID.TURQUOISE_SLAYER_HELMET_I;
|
||||
import static net.runelite.api.ItemID.TYRANNICAL_RING;
|
||||
import static net.runelite.api.ItemID.TYRANNICAL_RING_I;
|
||||
import static net.runelite.api.ItemID.UNCHARGED_TOXIC_TRIDENT;
|
||||
import static net.runelite.api.ItemID.UNCHARGED_TOXIC_TRIDENT_E;
|
||||
import static net.runelite.api.ItemID.UNCHARGED_TRIDENT;
|
||||
import static net.runelite.api.ItemID.UNCHARGED_TRIDENT_E;
|
||||
import static net.runelite.api.ItemID.VERACS_BRASSARD;
|
||||
import static net.runelite.api.ItemID.VERACS_BRASSARD_100;
|
||||
import static net.runelite.api.ItemID.VERACS_BRASSARD_25;
|
||||
import static net.runelite.api.ItemID.VERACS_BRASSARD_50;
|
||||
import static net.runelite.api.ItemID.VERACS_BRASSARD_75;
|
||||
import static net.runelite.api.ItemID.VERACS_FLAIL;
|
||||
import static net.runelite.api.ItemID.VERACS_FLAIL_100;
|
||||
import static net.runelite.api.ItemID.VERACS_FLAIL_25;
|
||||
import static net.runelite.api.ItemID.VERACS_FLAIL_50;
|
||||
import static net.runelite.api.ItemID.VERACS_FLAIL_75;
|
||||
import static net.runelite.api.ItemID.VERACS_HELM;
|
||||
import static net.runelite.api.ItemID.VERACS_HELM_100;
|
||||
import static net.runelite.api.ItemID.VERACS_HELM_25;
|
||||
import static net.runelite.api.ItemID.VERACS_HELM_50;
|
||||
import static net.runelite.api.ItemID.VERACS_HELM_75;
|
||||
import static net.runelite.api.ItemID.VERACS_PLATESKIRT;
|
||||
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_100;
|
||||
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_25;
|
||||
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_50;
|
||||
import static net.runelite.api.ItemID.VERACS_PLATESKIRT_75;
|
||||
import static net.runelite.api.ItemID.VIGGORAS_CHAINMACE;
|
||||
import static net.runelite.api.ItemID.VIGGORAS_CHAINMACE_U;
|
||||
import static net.runelite.api.ItemID.VOLCANIC_ABYSSAL_WHIP;
|
||||
import static net.runelite.api.ItemID.WARRIOR_RING;
|
||||
import static net.runelite.api.ItemID.WARRIOR_RING_I;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_GODSWORD;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_GODSWORD_OR;
|
||||
import static net.runelite.api.ItemID.ZAMORAK_GODSWORD_ORNAMENT_KIT;
|
||||
|
||||
/**
|
||||
* Converts untradeable items to it's tradeable counterparts
|
||||
*/
|
||||
public enum ItemMapping
|
||||
{
|
||||
// Barrows equipment
|
||||
ITEM_AHRIMS_HOOD(AHRIMS_HOOD, AHRIMS_HOOD_25, AHRIMS_HOOD_50, AHRIMS_HOOD_75, AHRIMS_HOOD_100),
|
||||
ITEM_AHRIMS_ROBETOP(AHRIMS_ROBETOP, AHRIMS_ROBETOP_25, AHRIMS_ROBETOP_50, AHRIMS_ROBETOP_75, AHRIMS_ROBETOP_100),
|
||||
ITEM_AHRIMS_ROBEBOTTOM(AHRIMS_ROBESKIRT, AHRIMS_ROBESKIRT_25, AHRIMS_ROBESKIRT_50, AHRIMS_ROBESKIRT_75, AHRIMS_ROBESKIRT_100),
|
||||
ITEM_AHRIMS_STAFF(AHRIMS_STAFF, AHRIMS_STAFF_25, AHRIMS_STAFF_50, AHRIMS_STAFF_75, AHRIMS_STAFF_100),
|
||||
ITEM_KARILS_COIF(KARILS_COIF, KARILS_COIF_25, KARILS_COIF_50, KARILS_COIF_75, KARILS_COIF_100),
|
||||
ITEM_KARILS_LEATHERTOP(KARILS_LEATHERTOP, KARILS_LEATHERTOP_25, KARILS_LEATHERTOP_50, KARILS_LEATHERTOP_75, KARILS_LEATHERTOP_100),
|
||||
ITEM_KARILS_LEATHERSKIRT(KARILS_LEATHERSKIRT, KARILS_LEATHERSKIRT_25, KARILS_LEATHERSKIRT_50, KARILS_LEATHERSKIRT_75, KARILS_LEATHERSKIRT_100),
|
||||
ITEM_KARILS_CROSSBOW(KARILS_CROSSBOW, KARILS_CROSSBOW_25, KARILS_CROSSBOW_50, KARILS_CROSSBOW_75, KARILS_CROSSBOW_100),
|
||||
ITEM_DHAROKS_HELM(DHAROKS_HELM, DHAROKS_HELM_25, DHAROKS_HELM_50, DHAROKS_HELM_75, DHAROKS_HELM_100),
|
||||
ITEM_DHAROKS_PLATEBODY(DHAROKS_PLATEBODY, DHAROKS_PLATEBODY_25, DHAROKS_PLATEBODY_50, DHAROKS_PLATEBODY_75, DHAROKS_PLATEBODY_100),
|
||||
ITEM_DHAROKS_PLATELEGS(DHAROKS_PLATELEGS, DHAROKS_PLATELEGS_25, DHAROKS_PLATELEGS_50, DHAROKS_PLATELEGS_75, DHAROKS_PLATELEGS_100),
|
||||
ITEM_DHARKS_GREATEAXE(DHAROKS_GREATAXE, DHAROKS_GREATAXE_25, DHAROKS_GREATAXE_50, DHAROKS_GREATAXE_75, DHAROKS_GREATAXE_100),
|
||||
ITEM_GUTHANS_HELM(GUTHANS_HELM, GUTHANS_HELM_25, GUTHANS_HELM_50, GUTHANS_HELM_75, GUTHANS_HELM_100),
|
||||
ITEM_GUTHANS_PLATEBODY(GUTHANS_PLATEBODY, GUTHANS_PLATEBODY_25, GUTHANS_PLATEBODY_50, GUTHANS_PLATEBODY_75, GUTHANS_PLATEBODY_100),
|
||||
ITEM_GUTHANS_CHAINSKIRT(GUTHANS_CHAINSKIRT, GUTHANS_CHAINSKIRT_25, GUTHANS_CHAINSKIRT_50, GUTHANS_CHAINSKIRT_75, GUTHANS_CHAINSKIRT_100),
|
||||
ITEM_GUTHANS_WARSPEAR(GUTHANS_WARSPEAR, GUTHANS_WARSPEAR_25, GUTHANS_WARSPEAR_50, GUTHANS_WARSPEAR_75, GUTHANS_WARSPEAR_100),
|
||||
ITEM_TORAGS_HELM(TORAGS_HELM, TORAGS_HELM_25, TORAGS_HELM_50, TORAGS_HELM_75, TORAGS_HELM_100),
|
||||
ITEM_TORAGS_PLATEBODY(TORAGS_PLATEBODY, TORAGS_PLATEBODY_25, TORAGS_PLATEBODY_50, TORAGS_PLATEBODY_75, TORAGS_PLATEBODY_100),
|
||||
ITEM_TORAGS_PLATELEGS(TORAGS_PLATELEGS, TORAGS_PLATELEGS_25, TORAGS_PLATELEGS_50, TORAGS_PLATELEGS_75, TORAGS_PLATELEGS_100),
|
||||
ITEM_TORAGS_HAMMERS(TORAGS_HAMMERS, TORAGS_HAMMERS_25, TORAGS_HAMMERS_50, TORAGS_HAMMERS_75, TORAGS_HAMMERS_100),
|
||||
ITEM_VERACS_HELM(VERACS_HELM, VERACS_HELM_25, VERACS_HELM_50, VERACS_HELM_75, VERACS_HELM_100),
|
||||
ITEM_VERACS_BRASSARD(VERACS_BRASSARD, VERACS_BRASSARD_25, VERACS_BRASSARD_50, VERACS_BRASSARD_75, VERACS_BRASSARD_100),
|
||||
ITEM_VERACS_PLATESKIRT(VERACS_PLATESKIRT, VERACS_PLATESKIRT_25, VERACS_PLATESKIRT_50, VERACS_PLATESKIRT_75, VERACS_PLATESKIRT_100),
|
||||
ITEM_VERACS_FLAIL(VERACS_FLAIL, VERACS_FLAIL_25, VERACS_FLAIL_50, VERACS_FLAIL_75, VERACS_FLAIL_100),
|
||||
|
||||
// Dragon equipment ornament kits
|
||||
ITEM_DRAGON_SCIMITAR(DRAGON_SCIMITAR, DRAGON_SCIMITAR_OR),
|
||||
ITEM_DRAGON_SCIMITAR_ORNAMENT_KIT(DRAGON_SCIMITAR_ORNAMENT_KIT, DRAGON_SCIMITAR_OR),
|
||||
ITEM_DRAGON_DEFENDER(DRAGON_DEFENDER_ORNAMENT_KIT, DRAGON_DEFENDER_T),
|
||||
ITEM_DRAGON_PICKAXE(DRAGON_PICKAXE, DRAGON_PICKAXE_12797),
|
||||
ITEM_DRAGON_KITESHIELD(DRAGON_KITESHIELD, DRAGON_KITESHIELD_G),
|
||||
ITEM_DRAGON_KITESHIELD_ORNAMENT_KIT(DRAGON_KITESHIELD_ORNAMENT_KIT, DRAGON_KITESHIELD_G),
|
||||
ITEM_DRAGON_FULL_HELM(DRAGON_FULL_HELM, DRAGON_FULL_HELM_G),
|
||||
ITEM_DRAGON_FULL_HELM_ORNAMENT_KIT(DRAGON_FULL_HELM_ORNAMENT_KIT, DRAGON_FULL_HELM_G),
|
||||
ITEM_DRAGON_CHAINBODY(DRAGON_CHAINBODY_3140, DRAGON_CHAINBODY_G),
|
||||
ITEM_DRAGON_CHAINBODY_ORNAMENT_KIT(DRAGON_CHAINBODY_ORNAMENT_KIT, DRAGON_CHAINBODY_G),
|
||||
ITEM_DRAGON_PLATEBODY(DRAGON_PLATEBODY, DRAGON_PLATEBODY_G),
|
||||
ITEM_DRAGON_PLATEBODY_ORNAMENT_KIT(DRAGON_PLATEBODY_ORNAMENT_KIT, DRAGON_PLATEBODY_G),
|
||||
ITEM_DRAGON_PLATESKIRT(DRAGON_PLATESKIRT, DRAGON_PLATESKIRT_G),
|
||||
ITEM_DRAGON_SKIRT_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATESKIRT_G),
|
||||
ITEM_DRAGON_PLATELEGS(DRAGON_PLATELEGS, DRAGON_PLATELEGS_G),
|
||||
ITEM_DRAGON_LEGS_ORNAMENT_KIT(DRAGON_LEGSSKIRT_ORNAMENT_KIT, DRAGON_PLATELEGS_G),
|
||||
ITEM_DRAGON_SQ_SHIELD(DRAGON_SQ_SHIELD, DRAGON_SQ_SHIELD_G),
|
||||
ITEM_DRAGON_SQ_SHIELD_ORNAMENT_KIT(DRAGON_SQ_SHIELD_ORNAMENT_KIT, DRAGON_SQ_SHIELD_G),
|
||||
ITEM_DRAGON_BOOTS(DRAGON_BOOTS, DRAGON_BOOTS_G),
|
||||
ITEM_DRAGON_BOOTS_ORNAMENT_KIT(DRAGON_BOOTS_ORNAMENT_KIT, DRAGON_BOOTS_G),
|
||||
|
||||
// Godsword ornament kits
|
||||
ITEM_ARMADYL_GODSWORD(ARMADYL_GODSWORD, ARMADYL_GODSWORD_OR),
|
||||
ITEM_ARMADYL_GODSWORD_ORNAMENT_KIT(ARMADYL_GODSWORD_ORNAMENT_KIT, ARMADYL_GODSWORD_OR),
|
||||
ITEM_BANDOS_GODSWORD(BANDOS_GODSWORD, BANDOS_GODSWORD_OR),
|
||||
ITEM_BANDOS_GODSWORD_ORNAMENT_KIT(BANDOS_GODSWORD_ORNAMENT_KIT, BANDOS_GODSWORD_OR),
|
||||
ITEM_ZAMORAK_GODSWORD(ZAMORAK_GODSWORD, ZAMORAK_GODSWORD_OR),
|
||||
ITEM_ZAMORAK_GODSWORD_ORNAMENT_KIT(ZAMORAK_GODSWORD_ORNAMENT_KIT, ZAMORAK_GODSWORD_OR),
|
||||
ITEM_SARADOMIN_GODSWORD(SARADOMIN_GODSWORD, SARADOMIN_GODSWORD_OR),
|
||||
ITEM_SARADOMIN_GODSWORD_ORNAMENT_KIT(SARADOMIN_GODSWORD_ORNAMENT_KIT, SARADOMIN_GODSWORD_OR),
|
||||
|
||||
// Jewellery ornament kits
|
||||
ITEM_AMULET_OF_TORTURE(AMULET_OF_TORTURE, AMULET_OF_TORTURE_OR),
|
||||
ITEM_TORTURE_ORNAMENT_KIT(TORTURE_ORNAMENT_KIT, AMULET_OF_TORTURE_OR),
|
||||
ITEM_NECKLACE_OF_ANGUISH(NECKLACE_OF_ANGUISH, NECKLACE_OF_ANGUISH_OR),
|
||||
ITEM_ANGUISH_ORNAMENT_KIT(ANGUISH_ORNAMENT_KIT, NECKLACE_OF_ANGUISH_OR),
|
||||
ITEM_OCCULT_NECKLACE(OCCULT_NECKLACE, OCCULT_NECKLACE_OR),
|
||||
ITEM_OCCULT_ORNAMENT_KIT(OCCULT_ORNAMENT_KIT, OCCULT_NECKLACE_OR),
|
||||
ITE_AMULET_OF_FURY(AMULET_OF_FURY, AMULET_OF_FURY_OR),
|
||||
ITE_FURY_ORNAMENT_KIT(FURY_ORNAMENT_KIT, AMULET_OF_FURY_OR),
|
||||
|
||||
// Ensouled heads
|
||||
ITEM_ENSOULED_GOBLIN_HEAD(ENSOULED_GOBLIN_HEAD_13448, ENSOULED_GOBLIN_HEAD),
|
||||
ITEM_ENSOULED_MONKEY_HEAD(ENSOULED_MONKEY_HEAD_13451, ENSOULED_MONKEY_HEAD),
|
||||
ITEM_ENSOULED_IMP_HEAD(ENSOULED_IMP_HEAD_13454, ENSOULED_IMP_HEAD),
|
||||
ITEM_ENSOULED_MINOTAUR_HEAD(ENSOULED_MINOTAUR_HEAD_13457, ENSOULED_MINOTAUR_HEAD),
|
||||
ITEM_ENSOULED_SCORPION_HEAD(ENSOULED_SCORPION_HEAD_13460, ENSOULED_SCORPION_HEAD),
|
||||
ITEM_ENSOULED_BEAR_HEAD(ENSOULED_BEAR_HEAD_13463, ENSOULED_BEAR_HEAD),
|
||||
ITEM_ENSOULED_UNICORN_HEAD(ENSOULED_UNICORN_HEAD_13466, ENSOULED_UNICORN_HEAD),
|
||||
ITEM_ENSOULED_DOG_HEAD(ENSOULED_DOG_HEAD_13469, ENSOULED_DOG_HEAD),
|
||||
ITEM_ENSOULED_CHAOS_DRUID_HEAD(ENSOULED_CHAOS_DRUID_HEAD_13472, ENSOULED_CHAOS_DRUID_HEAD),
|
||||
ITEM_ENSOULED_GIANT_HEAD(ENSOULED_GIANT_HEAD_13475, ENSOULED_GIANT_HEAD),
|
||||
ITEM_ENSOULED_OGRE_HEAD(ENSOULED_OGRE_HEAD_13478, ENSOULED_OGRE_HEAD),
|
||||
ITEM_ENSOULED_ELF_HEAD(ENSOULED_ELF_HEAD_13481, ENSOULED_ELF_HEAD),
|
||||
ITEM_ENSOULED_TROLL_HEAD(ENSOULED_TROLL_HEAD_13484, ENSOULED_TROLL_HEAD),
|
||||
ITEM_ENSOULED_HORROR_HEAD(ENSOULED_HORROR_HEAD_13487, ENSOULED_HORROR_HEAD),
|
||||
ITEM_ENSOULED_KALPHITE_HEAD(ENSOULED_KALPHITE_HEAD_13490, ENSOULED_KALPHITE_HEAD),
|
||||
ITEM_ENSOULED_DAGANNOTH_HEAD(ENSOULED_DAGANNOTH_HEAD_13493, ENSOULED_DAGANNOTH_HEAD),
|
||||
ITEM_ENSOULED_BLOODVELD_HEAD(ENSOULED_BLOODVELD_HEAD_13496, ENSOULED_BLOODVELD_HEAD),
|
||||
ITEM_ENSOULED_TZHAAR_HEAD(ENSOULED_TZHAAR_HEAD_13499, ENSOULED_TZHAAR_HEAD),
|
||||
ITEM_ENSOULED_DEMON_HEAD(ENSOULED_DEMON_HEAD_13502, ENSOULED_DEMON_HEAD),
|
||||
ITEM_ENSOULED_AVIANSIE_HEAD(ENSOULED_AVIANSIE_HEAD_13505, ENSOULED_AVIANSIE_HEAD),
|
||||
ITEM_ENSOULED_ABYSSAL_HEAD(ENSOULED_ABYSSAL_HEAD_13508, ENSOULED_ABYSSAL_HEAD),
|
||||
ITEM_ENSOULED_DRAGON_HEAD(ENSOULED_DRAGON_HEAD_13511, ENSOULED_DRAGON_HEAD),
|
||||
|
||||
// Imbued rings
|
||||
ITEM_BERSERKER_RING(BERSERKER_RING, BERSERKER_RING_I),
|
||||
ITEM_SEERS_RING(SEERS_RING, SEERS_RING_I),
|
||||
ITEM_WARRIOR_RING(WARRIOR_RING, WARRIOR_RING_I),
|
||||
ITEM_ARCHERS_RING(ARCHERS_RING, ARCHERS_RING_I),
|
||||
ITEM_TREASONOUS_RING(TREASONOUS_RING, TREASONOUS_RING_I),
|
||||
ITEM_TYRANNICAL_RING(TYRANNICAL_RING, TYRANNICAL_RING_I),
|
||||
ITEM_RING_OF_THE_GODS(RING_OF_THE_GODS, RING_OF_THE_GODS_I),
|
||||
ITEM_RING_OF_SUFFERING(RING_OF_SUFFERING, RING_OF_SUFFERING_I, RING_OF_SUFFERING_R, RING_OF_SUFFERING_RI),
|
||||
ITEM_GRANITE_RING(GRANITE_RING, GRANITE_RING_I),
|
||||
|
||||
// Bounty hunter
|
||||
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848),
|
||||
ITEM_MAGIC_SHORTBOW(MAGIC_SHORTBOW, MAGIC_SHORTBOW_I),
|
||||
ITEM_SARADOMINS_BLESSED_SWORD(SARADOMINS_TEAR, SARADOMINS_BLESSED_SWORD),
|
||||
|
||||
// Jewellery with charges
|
||||
ITEM_RING_OF_WEALTH(RING_OF_WEALTH, RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
|
||||
ITEM_AMULET_OF_GLORY(AMULET_OF_GLORY, AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5),
|
||||
ITEM_AMULET_OF_GLORY_T(AMULET_OF_GLORY_T, AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5),
|
||||
ITEM_SKILLS_NECKLACE(SKILLS_NECKLACE, SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5),
|
||||
ITEM_RING_OF_DUELING(RING_OF_DUELING8, RING_OF_DUELING1, RING_OF_DUELING2, RING_OF_DUELING3, RING_OF_DUELING4, RING_OF_DUELING5, RING_OF_DUELING6, RING_OF_DUELING7),
|
||||
ITEM_GAMES_NECKLACE(GAMES_NECKLACE8, GAMES_NECKLACE1, GAMES_NECKLACE2, GAMES_NECKLACE3, GAMES_NECKLACE4, GAMES_NECKLACE5, GAMES_NECKLACE6, GAMES_NECKLACE7),
|
||||
|
||||
// Degradable/charged weaponry/armour
|
||||
ITEM_ABYSSAL_WHIP(ABYSSAL_WHIP, VOLCANIC_ABYSSAL_WHIP, FROZEN_ABYSSAL_WHIP),
|
||||
ITEM_KRAKEN_TENTACLE(KRAKEN_TENTACLE, ABYSSAL_TENTACLE),
|
||||
ITEM_TRIDENT_OF_THE_SEAS(UNCHARGED_TRIDENT, TRIDENT_OF_THE_SEAS),
|
||||
ITEM_TRIDENT_OF_THE_SEAS_E(UNCHARGED_TRIDENT_E, TRIDENT_OF_THE_SEAS_E),
|
||||
ITEM_TRIDENT_OF_THE_SWAMP(UNCHARGED_TOXIC_TRIDENT, TRIDENT_OF_THE_SWAMP),
|
||||
ITEM_TRIDENT_OF_THE_SWAMP_E(UNCHARGED_TOXIC_TRIDENT_E, TRIDENT_OF_THE_SWAMP_E),
|
||||
ITEM_TOXIC_BLOWPIPE(TOXIC_BLOWPIPE_EMPTY, TOXIC_BLOWPIPE),
|
||||
ITEM_TOXIC_STAFF_OFF_THE_DEAD(TOXIC_STAFF_UNCHARGED, TOXIC_STAFF_OF_THE_DEAD),
|
||||
ITEM_SERPENTINE_HELM(SERPENTINE_HELM_UNCHARGED, SERPENTINE_HELM, TANZANITE_HELM_UNCHARGED, TANZANITE_HELM, MAGMA_HELM_UNCHARGED, MAGMA_HELM),
|
||||
ITEM_DRAGONFIRE_SHIELD(DRAGONFIRE_SHIELD_11284, DRAGONFIRE_SHIELD),
|
||||
ITEM_DRAGONFIRE_WARD(DRAGONFIRE_WARD_22003, DRAGONFIRE_WARD),
|
||||
ITEM_ANCIENT_WYVERN_SHIELD(ANCIENT_WYVERN_SHIELD_21634, ANCIENT_WYVERN_SHIELD),
|
||||
ITEM_SANGUINESTI_STAFF(SANGUINESTI_STAFF_UNCHARGED, SANGUINESTI_STAFF),
|
||||
ITEM_SCYTHE_OF_VITUR(SCYTHE_OF_VITUR_UNCHARGED, SCYTHE_OF_VITUR),
|
||||
ITEM_TOME_OF_FIRE(TOME_OF_FIRE_EMPTY, TOME_OF_FIRE),
|
||||
ITEM_CRAWS_BOW(CRAWS_BOW_U, CRAWS_BOW),
|
||||
ITEM_VIGGORAS_CHAINMACE(VIGGORAS_CHAINMACE_U, VIGGORAS_CHAINMACE),
|
||||
ITEM_THAMMARONS_SCEPTRE(THAMMARONS_SCEPTRE_U, THAMMARONS_SCEPTRE),
|
||||
|
||||
// Infinity colour kits
|
||||
ITEM_INFINITY_TOP(INFINITY_TOP, INFINITY_TOP_10605, INFINITY_TOP_20574, DARK_INFINITY_TOP, LIGHT_INFINITY_TOP),
|
||||
ITEM_INFINITY_TOP_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_TOP),
|
||||
ITEM_INFINITY_TOP_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_TOP),
|
||||
ITEM_INFINITY_BOTTOMS(INFINITY_BOTTOMS, INFINITY_BOTTOMS_20575, DARK_INFINITY_BOTTOMS, LIGHT_INFINITY_BOTTOMS),
|
||||
ITEM_INFINITY_BOTTOMS_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_BOTTOMS),
|
||||
ITEM_INFINITY_BOTTOMS_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_BOTTOMS),
|
||||
ITEM_INFINITY_HAT(INFINITY_HAT, DARK_INFINITY_HAT, LIGHT_INFINITY_HAT),
|
||||
ITEM_INFINITY_HAT_LIGHT_COLOUR_KIT(LIGHT_INFINITY_COLOUR_KIT, LIGHT_INFINITY_HAT),
|
||||
ITEM_INFINITY_HAT_DARK_COLOUR_KIT(DARK_INFINITY_COLOUR_KIT, DARK_INFINITY_HAT),
|
||||
|
||||
// Miscellaneous ornament kits
|
||||
ITEM_DARK_BOW(DARK_BOW, DARK_BOW_12765, DARK_BOW_12766, DARK_BOW_12767, DARK_BOW_12768, DARK_BOW_20408),
|
||||
ITEM_ODIUM_WARD(ODIUM_WARD, ODIUM_WARD_12807),
|
||||
ITEM_MALEDICTION_WARD(MALEDICTION_WARD, MALEDICTION_WARD_12806),
|
||||
ITEM_STEAM_BATTLESTAFF(STEAM_BATTLESTAFF, STEAM_BATTLESTAFF_12795),
|
||||
ITEM_LAVA_BATTLESTAFF(LAVA_BATTLESTAFF, LAVA_BATTLESTAFF_21198),
|
||||
|
||||
// Slayer helm/black mask
|
||||
ITEM_BLACK_MASK(
|
||||
BLACK_MASK, BLACK_MASK_I, BLACK_MASK_1, BLACK_MASK_1_I, BLACK_MASK_2, BLACK_MASK_2_I, BLACK_MASK_3, BLACK_MASK_3_I, BLACK_MASK_4, BLACK_MASK_4_I, BLACK_MASK_5,
|
||||
BLACK_MASK_5_I, BLACK_MASK_6, BLACK_MASK_6_I, BLACK_MASK_7, BLACK_MASK_7_I, BLACK_MASK_8, BLACK_MASK_8_I, BLACK_MASK_9, BLACK_MASK_9_I, BLACK_MASK_10_I,
|
||||
SLAYER_HELMET, SLAYER_HELMET_I, BLACK_SLAYER_HELMET, BLACK_SLAYER_HELMET_I, PURPLE_SLAYER_HELMET, PURPLE_SLAYER_HELMET_I, RED_SLAYER_HELMET, RED_SLAYER_HELMET_I,
|
||||
GREEN_SLAYER_HELMET, GREEN_SLAYER_HELMET_I, TURQUOISE_SLAYER_HELMET, TURQUOISE_SLAYER_HELMET_I, HYDRA_SLAYER_HELMET, HYDRA_SLAYER_HELMET_I),
|
||||
|
||||
// Pharaoh's Sceptres
|
||||
ITEM_PHARAOHS_SCEPTRE_1(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_1),
|
||||
ITEM_PHARAOHS_SCEPTRE_2(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_2),
|
||||
ITEM_PHARAOHS_SCEPTRE_4(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_4),
|
||||
ITEM_PHARAOHS_SCEPTRE_5(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_5),
|
||||
ITEM_PHARAOHS_SCEPTRE_6(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_6),
|
||||
ITEM_PHARAOHS_SCEPTRE_7(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_7),
|
||||
ITEM_PHARAOHS_SCEPTRE_8(PHARAOHS_SCEPTRE, PHARAOHS_SCEPTRE_8),
|
||||
|
||||
// Revertible items
|
||||
ITEM_HYDRA_LEATHER(HYDRA_LEATHER, FEROCIOUS_GLOVES),
|
||||
ITEM_HYDRA_TAIL(HYDRA_TAIL, BONECRUSHER_NECKLACE),
|
||||
ITEM_DRAGONBONE_NECKLACE(DRAGONBONE_NECKLACE, BONECRUSHER_NECKLACE),
|
||||
ITEM_BOTTOMLESS_COMPOST_BUCKET(BOTTOMLESS_COMPOST_BUCKET, BOTTOMLESS_COMPOST_BUCKET_22997);
|
||||
|
||||
private static final Multimap<Integer, Integer> MAPPINGS = HashMultimap.create();
|
||||
private final int tradeableItem;
|
||||
private final int[] untradableItems;
|
||||
|
||||
static
|
||||
{
|
||||
for (final ItemMapping item : values())
|
||||
{
|
||||
for (int itemId : item.untradableItems)
|
||||
{
|
||||
MAPPINGS.put(itemId, item.tradeableItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemMapping(int tradeableItem, int... untradableItems)
|
||||
{
|
||||
this.tradeableItem = tradeableItem;
|
||||
this.untradableItems = untradableItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection of items that are mapped from single item id.
|
||||
*
|
||||
* @param itemId the item id
|
||||
* @return the collection
|
||||
*/
|
||||
public static Collection<Integer> map(int itemId)
|
||||
{
|
||||
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
||||
|
||||
if (mapping == null || mapping.isEmpty())
|
||||
{
|
||||
return Collections.singleton(itemId);
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map an item from its untradeable version to its tradeable version
|
||||
*
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
public static int mapFirst(int itemId)
|
||||
{
|
||||
final Collection<Integer> mapping = MAPPINGS.get(itemId);
|
||||
|
||||
if (mapping == null || mapping.isEmpty())
|
||||
{
|
||||
return itemId;
|
||||
}
|
||||
|
||||
return mapping.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +1,66 @@
|
||||
/*
|
||||
* 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.game;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class NPCManager
|
||||
{
|
||||
private final Map<String, Integer> healthMap;
|
||||
|
||||
@Inject
|
||||
private NPCManager()
|
||||
{
|
||||
final Gson gson = new Gson();
|
||||
final Type typeToken = new TypeToken<Map<String, Integer>>()
|
||||
{
|
||||
}.getType();
|
||||
|
||||
final InputStream healthFile = getClass().getResourceAsStream("/npc_health.json");
|
||||
healthMap = gson.fromJson(new InputStreamReader(healthFile), typeToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns health for target NPC based on it's combat level and name
|
||||
* @param name npc name
|
||||
* @param combatLevel npc combat level
|
||||
* @return health or null if HP is unknown
|
||||
*/
|
||||
@Nullable
|
||||
public Integer getHealth(final String name, final int combatLevel)
|
||||
{
|
||||
return healthMap.get(name + "_" + combatLevel);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.game;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class NPCManager
|
||||
{
|
||||
private final Map<String, Integer> healthMap;
|
||||
|
||||
@Inject
|
||||
private NPCManager()
|
||||
{
|
||||
final Gson gson = new Gson();
|
||||
final Type typeToken = new TypeToken<Map<String, Integer>>()
|
||||
{
|
||||
}.getType();
|
||||
|
||||
final InputStream healthFile = getClass().getResourceAsStream("/npc_health.json");
|
||||
healthMap = gson.fromJson(new InputStreamReader(healthFile), typeToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns health for target NPC based on it's combat level and name
|
||||
*
|
||||
* @param name npc name
|
||||
* @param combatLevel npc combat level
|
||||
* @return health or null if HP is unknown
|
||||
*/
|
||||
@Nullable
|
||||
public Integer getHealth(final String name, final int combatLevel)
|
||||
{
|
||||
return healthMap.get(name + "_" + combatLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,202 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game.chatbox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseListener;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.input.MouseWheelListener;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ChatboxPanelManager
|
||||
{
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private final KeyManager keyManager;
|
||||
private final MouseManager mouseManager;
|
||||
|
||||
private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider;
|
||||
private final Provider<ChatboxTextInput> chatboxTextInputProvider;
|
||||
|
||||
@Getter
|
||||
private ChatboxInput currentInput = null;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread,
|
||||
KeyManager keyManager, MouseManager mouseManager,
|
||||
Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
this.eventBus = eventBus;
|
||||
|
||||
this.keyManager = keyManager;
|
||||
this.mouseManager = mouseManager;
|
||||
|
||||
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
|
||||
this.chatboxTextInputProvider = chatboxTextInputProvider;
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
clientThread.invokeLater(this::unsafeCloseInput);
|
||||
}
|
||||
|
||||
private void unsafeCloseInput()
|
||||
{
|
||||
client.runScript(
|
||||
ScriptID.RESET_CHATBOX_INPUT,
|
||||
0,
|
||||
1
|
||||
);
|
||||
if (currentInput != null)
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
private void unsafeOpenInput(ChatboxInput input)
|
||||
{
|
||||
client.runScript(ScriptID.CLEAR_CHATBOX_PANEL);
|
||||
|
||||
eventBus.register(input);
|
||||
if (input instanceof KeyListener)
|
||||
{
|
||||
keyManager.registerKeyListener((KeyListener) input);
|
||||
}
|
||||
if (input instanceof MouseListener)
|
||||
{
|
||||
mouseManager.registerMouseListener((MouseListener) input);
|
||||
}
|
||||
if (input instanceof MouseWheelListener)
|
||||
{
|
||||
mouseManager.registerMouseWheelListener((MouseWheelListener) input);
|
||||
}
|
||||
|
||||
if (currentInput != null)
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
|
||||
currentInput = input;
|
||||
client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType());
|
||||
client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true);
|
||||
client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true);
|
||||
|
||||
Widget c = getContainerWidget();
|
||||
c.deleteAllChildren();
|
||||
c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput());
|
||||
input.open();
|
||||
}
|
||||
|
||||
public void openInput(ChatboxInput input)
|
||||
{
|
||||
clientThread.invokeLater(() -> unsafeOpenInput(input));
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput openTextMenuInput(String title)
|
||||
{
|
||||
return chatboxTextMenuInputProvider.get()
|
||||
.title(title);
|
||||
}
|
||||
|
||||
public ChatboxTextInput openTextInput(String prompt)
|
||||
{
|
||||
return chatboxTextInputProvider.get()
|
||||
.prompt(prompt);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent ev)
|
||||
{
|
||||
if (currentInput != null && "resetChatboxInput".equals(ev.getEventName()))
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged ev)
|
||||
{
|
||||
if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
private void killCurrentPanel()
|
||||
{
|
||||
try
|
||||
{
|
||||
currentInput.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("Exception closing {}", currentInput.getClass(), e);
|
||||
}
|
||||
|
||||
eventBus.unregister(currentInput);
|
||||
if (currentInput instanceof KeyListener)
|
||||
{
|
||||
keyManager.unregisterKeyListener((KeyListener) currentInput);
|
||||
}
|
||||
if (currentInput instanceof MouseListener)
|
||||
{
|
||||
mouseManager.unregisterMouseListener((MouseListener) currentInput);
|
||||
}
|
||||
if (currentInput instanceof MouseWheelListener)
|
||||
{
|
||||
mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput);
|
||||
}
|
||||
currentInput = null;
|
||||
}
|
||||
|
||||
public Widget getContainerWidget()
|
||||
{
|
||||
return client.getWidget(WidgetInfo.CHATBOX_CONTAINER);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game.chatbox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseListener;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.input.MouseWheelListener;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ChatboxPanelManager
|
||||
{
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private final KeyManager keyManager;
|
||||
private final MouseManager mouseManager;
|
||||
|
||||
private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider;
|
||||
private final Provider<ChatboxTextInput> chatboxTextInputProvider;
|
||||
|
||||
@Getter
|
||||
private ChatboxInput currentInput = null;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread,
|
||||
KeyManager keyManager, MouseManager mouseManager,
|
||||
Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
this.eventBus = eventBus;
|
||||
|
||||
this.keyManager = keyManager;
|
||||
this.mouseManager = mouseManager;
|
||||
|
||||
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
|
||||
this.chatboxTextInputProvider = chatboxTextInputProvider;
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
clientThread.invokeLater(this::unsafeCloseInput);
|
||||
}
|
||||
|
||||
private void unsafeCloseInput()
|
||||
{
|
||||
client.runScript(
|
||||
ScriptID.RESET_CHATBOX_INPUT,
|
||||
0,
|
||||
1
|
||||
);
|
||||
if (currentInput != null)
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
private void unsafeOpenInput(ChatboxInput input)
|
||||
{
|
||||
client.runScript(ScriptID.CLEAR_CHATBOX_PANEL);
|
||||
|
||||
eventBus.register(input);
|
||||
if (input instanceof KeyListener)
|
||||
{
|
||||
keyManager.registerKeyListener((KeyListener) input);
|
||||
}
|
||||
if (input instanceof MouseListener)
|
||||
{
|
||||
mouseManager.registerMouseListener((MouseListener) input);
|
||||
}
|
||||
if (input instanceof MouseWheelListener)
|
||||
{
|
||||
mouseManager.registerMouseWheelListener((MouseWheelListener) input);
|
||||
}
|
||||
|
||||
if (currentInput != null)
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
|
||||
currentInput = input;
|
||||
client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType());
|
||||
client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true);
|
||||
client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true);
|
||||
|
||||
Widget c = getContainerWidget();
|
||||
c.deleteAllChildren();
|
||||
c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput());
|
||||
input.open();
|
||||
}
|
||||
|
||||
public void openInput(ChatboxInput input)
|
||||
{
|
||||
clientThread.invokeLater(() -> unsafeOpenInput(input));
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput openTextMenuInput(String title)
|
||||
{
|
||||
return chatboxTextMenuInputProvider.get()
|
||||
.title(title);
|
||||
}
|
||||
|
||||
public ChatboxTextInput openTextInput(String prompt)
|
||||
{
|
||||
return chatboxTextInputProvider.get()
|
||||
.prompt(prompt);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent ev)
|
||||
{
|
||||
if (currentInput != null && "resetChatboxInput".equals(ev.getEventName()))
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged ev)
|
||||
{
|
||||
if (currentInput != null && ev.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
killCurrentPanel();
|
||||
}
|
||||
}
|
||||
|
||||
private void killCurrentPanel()
|
||||
{
|
||||
try
|
||||
{
|
||||
currentInput.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("Exception closing {}", currentInput.getClass(), e);
|
||||
}
|
||||
|
||||
eventBus.unregister(currentInput);
|
||||
if (currentInput instanceof KeyListener)
|
||||
{
|
||||
keyManager.unregisterKeyListener((KeyListener) currentInput);
|
||||
}
|
||||
if (currentInput instanceof MouseListener)
|
||||
{
|
||||
mouseManager.unregisterMouseListener((MouseListener) currentInput);
|
||||
}
|
||||
if (currentInput instanceof MouseWheelListener)
|
||||
{
|
||||
mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput);
|
||||
}
|
||||
currentInput = null;
|
||||
}
|
||||
|
||||
public Widget getContainerWidget()
|
||||
{
|
||||
return client.getWidget(WidgetInfo.CHATBOX_CONTAINER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,213 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game.chatbox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetPositionMode;
|
||||
import net.runelite.api.widgets.WidgetSizeMode;
|
||||
import net.runelite.api.widgets.WidgetTextAlignment;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
|
||||
@Slf4j
|
||||
public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener
|
||||
{
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
private static final class Entry
|
||||
{
|
||||
private String text;
|
||||
private Runnable callback;
|
||||
}
|
||||
|
||||
private final ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Getter
|
||||
private String title;
|
||||
|
||||
@Getter
|
||||
private List<Entry> options = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private Runnable onClose;
|
||||
|
||||
@Inject
|
||||
protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager)
|
||||
{
|
||||
this.chatboxPanelManager = chatboxPanelManager;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput title(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput option(String text, Runnable callback)
|
||||
{
|
||||
options.add(new Entry(text, callback));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput onClose(Runnable onClose)
|
||||
{
|
||||
this.onClose = onClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput build()
|
||||
{
|
||||
if (title == null)
|
||||
{
|
||||
throw new IllegalStateException("Title must be set");
|
||||
}
|
||||
|
||||
if (options.size() < 1)
|
||||
{
|
||||
throw new IllegalStateException("You must have atleast 1 option");
|
||||
}
|
||||
|
||||
chatboxPanelManager.openInput(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open()
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
|
||||
Widget prompt = container.createChild(-1, WidgetType.TEXT);
|
||||
prompt.setText(title);
|
||||
prompt.setTextColor(0x800000);
|
||||
prompt.setFontId(FontID.QUILL_8);
|
||||
prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
prompt.setOriginalX(0);
|
||||
prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
prompt.setOriginalY(8);
|
||||
prompt.setOriginalHeight(24);
|
||||
prompt.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
prompt.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
prompt.setWidthMode(WidgetSizeMode.MINUS);
|
||||
prompt.revalidate();
|
||||
|
||||
int y = prompt.getRelativeX() + prompt.getHeight() + 6;
|
||||
int height = container.getHeight() - y - 8;
|
||||
int step = height / options.size();
|
||||
int maxStep = options.size() >= 3 ? 25 : 30;
|
||||
if (step > maxStep)
|
||||
{
|
||||
int ds = step - maxStep;
|
||||
step = maxStep;
|
||||
y += (ds * options.size()) / 2;
|
||||
}
|
||||
|
||||
for (Entry option : options)
|
||||
{
|
||||
Widget optWidget = container.createChild(-1, WidgetType.TEXT);
|
||||
optWidget.setText(option.text);
|
||||
optWidget.setFontId(FontID.QUILL_8);
|
||||
optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
optWidget.setOriginalX(0);
|
||||
optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
optWidget.setOriginalY(y);
|
||||
optWidget.setOriginalHeight(24);
|
||||
optWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
optWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
optWidget.setWidthMode(WidgetSizeMode.MINUS);
|
||||
optWidget.setAction(0, "Continue");
|
||||
optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option));
|
||||
optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF));
|
||||
optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0));
|
||||
optWidget.setHasListener(true);
|
||||
optWidget.revalidate();
|
||||
|
||||
y += step;
|
||||
}
|
||||
}
|
||||
|
||||
private void callback(Entry entry)
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
container.setOnKeyListener((Object[]) null);
|
||||
|
||||
chatboxPanelManager.close();
|
||||
|
||||
entry.callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close()
|
||||
{
|
||||
if (onClose != null)
|
||||
{
|
||||
onClose.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
char c = e.getKeyChar();
|
||||
|
||||
if (c == '\033')
|
||||
{
|
||||
chatboxPanelManager.close();
|
||||
e.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
int n = c - '1';
|
||||
if (n >= 0 && n < options.size())
|
||||
{
|
||||
callback(options.get(n));
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
|
||||
{
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.game.chatbox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetPositionMode;
|
||||
import net.runelite.api.widgets.WidgetSizeMode;
|
||||
import net.runelite.api.widgets.WidgetTextAlignment;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
|
||||
@Slf4j
|
||||
public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener
|
||||
{
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
private static final class Entry
|
||||
{
|
||||
private String text;
|
||||
private Runnable callback;
|
||||
}
|
||||
|
||||
private final ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Getter
|
||||
private String title;
|
||||
|
||||
@Getter
|
||||
private List<Entry> options = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private Runnable onClose;
|
||||
|
||||
@Inject
|
||||
protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager)
|
||||
{
|
||||
this.chatboxPanelManager = chatboxPanelManager;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput title(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput option(String text, Runnable callback)
|
||||
{
|
||||
options.add(new Entry(text, callback));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput onClose(Runnable onClose)
|
||||
{
|
||||
this.onClose = onClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput build()
|
||||
{
|
||||
if (title == null)
|
||||
{
|
||||
throw new IllegalStateException("Title must be set");
|
||||
}
|
||||
|
||||
if (options.size() < 1)
|
||||
{
|
||||
throw new IllegalStateException("You must have atleast 1 option");
|
||||
}
|
||||
|
||||
chatboxPanelManager.openInput(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open()
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
|
||||
Widget prompt = container.createChild(-1, WidgetType.TEXT);
|
||||
prompt.setText(title);
|
||||
prompt.setTextColor(0x800000);
|
||||
prompt.setFontId(FontID.QUILL_8);
|
||||
prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
prompt.setOriginalX(0);
|
||||
prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
prompt.setOriginalY(8);
|
||||
prompt.setOriginalHeight(24);
|
||||
prompt.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
prompt.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
prompt.setWidthMode(WidgetSizeMode.MINUS);
|
||||
prompt.revalidate();
|
||||
|
||||
int y = prompt.getRelativeX() + prompt.getHeight() + 6;
|
||||
int height = container.getHeight() - y - 8;
|
||||
int step = height / options.size();
|
||||
int maxStep = options.size() >= 3 ? 25 : 30;
|
||||
if (step > maxStep)
|
||||
{
|
||||
int ds = step - maxStep;
|
||||
step = maxStep;
|
||||
y += (ds * options.size()) / 2;
|
||||
}
|
||||
|
||||
for (Entry option : options)
|
||||
{
|
||||
Widget optWidget = container.createChild(-1, WidgetType.TEXT);
|
||||
optWidget.setText(option.text);
|
||||
optWidget.setFontId(FontID.QUILL_8);
|
||||
optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
optWidget.setOriginalX(0);
|
||||
optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
optWidget.setOriginalY(y);
|
||||
optWidget.setOriginalHeight(24);
|
||||
optWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
optWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
optWidget.setWidthMode(WidgetSizeMode.MINUS);
|
||||
optWidget.setAction(0, "Continue");
|
||||
optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option));
|
||||
optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF));
|
||||
optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0));
|
||||
optWidget.setHasListener(true);
|
||||
optWidget.revalidate();
|
||||
|
||||
y += step;
|
||||
}
|
||||
}
|
||||
|
||||
private void callback(Entry entry)
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
container.setOnKeyListener((Object[]) null);
|
||||
|
||||
chatboxPanelManager.close();
|
||||
|
||||
entry.callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close()
|
||||
{
|
||||
if (onClose != null)
|
||||
{
|
||||
onClose.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
char c = e.getKeyChar();
|
||||
|
||||
if (c == '\033')
|
||||
{
|
||||
chatboxPanelManager.close();
|
||||
e.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
int n = c - '1';
|
||||
if (n >= 0 && n < options.size())
|
||||
{
|
||||
callback(options.get(n));
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
|
||||
{
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,7 +743,7 @@ public class ModelOutlineRenderer
|
||||
* @param outerColor The color of the pixels of the outline furthest away from the model
|
||||
*/
|
||||
private void renderOutline(BufferedImage image, int outlineWidth,
|
||||
Color innerColor, Color outerColor)
|
||||
Color innerColor, Color outerColor)
|
||||
{
|
||||
int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
List<PixelDistanceAlpha> ps = getPriorityList(outlineWidth);
|
||||
@@ -887,8 +887,8 @@ public class ModelOutlineRenderer
|
||||
* @param outerColor The color of the pixels of the outline furthest away from the model
|
||||
*/
|
||||
private void drawModelOutline(Model model,
|
||||
int localX, int localY, int localZ, int orientation,
|
||||
int outlineWidth, Color innerColor, Color outerColor)
|
||||
int localX, int localY, int localZ, int orientation,
|
||||
int outlineWidth, Color innerColor, Color outerColor)
|
||||
{
|
||||
if (outlineWidth <= 0)
|
||||
{
|
||||
|
||||
@@ -1,106 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Robin <robin.weymans@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.menus;
|
||||
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
public final class WidgetMenuOption
|
||||
{
|
||||
/**
|
||||
* The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop"
|
||||
*/
|
||||
private String menuOption;
|
||||
/**
|
||||
* The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones"
|
||||
*/
|
||||
private String menuTarget;
|
||||
/**
|
||||
* The color that the menuTarget should be. Defaults to the brownish color that most menu options have.
|
||||
*/
|
||||
private Color color = JagexColors.MENU_TARGET;
|
||||
|
||||
/**
|
||||
* The widget to add the option to
|
||||
*/
|
||||
private final WidgetInfo widget;
|
||||
|
||||
/**
|
||||
* Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options
|
||||
*
|
||||
* @param menuOption Option text of this right click option
|
||||
* @param menuTarget Target text of this right click option
|
||||
* @param widget The widget to attach this option to
|
||||
*/
|
||||
public WidgetMenuOption(String menuOption, String menuTarget, WidgetInfo widget)
|
||||
{
|
||||
this.menuOption = menuOption;
|
||||
setMenuTarget(menuTarget);
|
||||
this.widget = widget;
|
||||
}
|
||||
|
||||
public void setMenuOption(String option)
|
||||
{
|
||||
menuOption = option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target of the menu option. Color code will be added on to target
|
||||
*
|
||||
* @param target The target text without color code.
|
||||
*/
|
||||
public void setMenuTarget(String target)
|
||||
{
|
||||
menuTarget = ColorUtil.wrapWithColorTag(target, color);
|
||||
}
|
||||
|
||||
public String getMenuOption()
|
||||
{
|
||||
return menuOption;
|
||||
}
|
||||
|
||||
public String getMenuTarget()
|
||||
{
|
||||
return menuTarget;
|
||||
}
|
||||
|
||||
public WidgetInfo getWidget()
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
|
||||
public Color getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color col)
|
||||
{
|
||||
color = col;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Robin <robin.weymans@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.menus;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
public final class WidgetMenuOption
|
||||
{
|
||||
/**
|
||||
* The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop"
|
||||
*/
|
||||
private String menuOption;
|
||||
/**
|
||||
* The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones"
|
||||
*/
|
||||
private String menuTarget;
|
||||
/**
|
||||
* The color that the menuTarget should be. Defaults to the brownish color that most menu options have.
|
||||
*/
|
||||
private Color color = JagexColors.MENU_TARGET;
|
||||
|
||||
/**
|
||||
* The widget to add the option to
|
||||
*/
|
||||
private final WidgetInfo widget;
|
||||
|
||||
/**
|
||||
* Creates a menu to be added to right click menus. The menu will only be added if match is found within the menu options
|
||||
*
|
||||
* @param menuOption Option text of this right click option
|
||||
* @param menuTarget Target text of this right click option
|
||||
* @param widget The widget to attach this option to
|
||||
*/
|
||||
public WidgetMenuOption(String menuOption, String menuTarget, WidgetInfo widget)
|
||||
{
|
||||
this.menuOption = menuOption;
|
||||
setMenuTarget(menuTarget);
|
||||
this.widget = widget;
|
||||
}
|
||||
|
||||
public void setMenuOption(String option)
|
||||
{
|
||||
menuOption = option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target of the menu option. Color code will be added on to target
|
||||
*
|
||||
* @param target The target text without color code.
|
||||
*/
|
||||
public void setMenuTarget(String target)
|
||||
{
|
||||
menuTarget = ColorUtil.wrapWithColorTag(target, color);
|
||||
}
|
||||
|
||||
public String getMenuOption()
|
||||
{
|
||||
return menuOption;
|
||||
}
|
||||
|
||||
public String getMenuTarget()
|
||||
{
|
||||
return menuTarget;
|
||||
}
|
||||
|
||||
public WidgetInfo getWidget()
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
|
||||
public Color getColor()
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color col)
|
||||
{
|
||||
color = col;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,11 +59,11 @@ public class BlackjackPlugin extends Plugin
|
||||
@Inject
|
||||
Client client;
|
||||
|
||||
private static long timeSinceKnockout;
|
||||
private static long timeSinceAggro;
|
||||
private long timeSinceKnockout;
|
||||
private long timeSinceAggro;
|
||||
|
||||
@Getter
|
||||
private static long currentGameTick;
|
||||
private long currentGameTick;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
@@ -109,7 +109,7 @@ public class BlackjackPlugin extends Plugin
|
||||
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
|
||||
{
|
||||
String target = menuEntryAdded.getTarget().toLowerCase();
|
||||
if ((target.contains("bandit") | target.contains("menaphite thug")))
|
||||
if ((target.contains("bandit") || target.contains("menaphite thug")))
|
||||
{
|
||||
Quest quest = Quest.THE_FEUD;
|
||||
if (quest.getState(client) == QuestState.FINISHED)
|
||||
|
||||
@@ -99,7 +99,7 @@ class CombatLevelOverlay extends Overlay
|
||||
int prayerLevel = client.getRealSkillLevel(Skill.PRAYER);
|
||||
|
||||
// calculate initial required numbers
|
||||
double base = DEF_HP_MULT * (defenceLevel + hitpointsLevel + Math.floor(prayerLevel / 2));
|
||||
double base = DEF_HP_MULT * (defenceLevel + hitpointsLevel + Math.floor(prayerLevel / 2D));
|
||||
double melee = ATT_STR_MULT * (attackLevel + strengthLevel);
|
||||
double range = RANGE_MAGIC_MULT * Math.floor(rangedLevel * RANGE_MAGIC_LEVEL_MULT);
|
||||
double mage = RANGE_MAGIC_MULT * Math.floor(magicLevel * RANGE_MAGIC_LEVEL_MULT);
|
||||
|
||||
@@ -123,7 +123,7 @@ public class PluginListItem extends JPanel
|
||||
* if there is no configuration associated with the plugin.
|
||||
*/
|
||||
PluginListItem(ConfigPanel configPanel, ConfigManager configManager, Plugin plugin, PluginDescriptor descriptor,
|
||||
@Nullable Config config, @Nullable ConfigDescriptor configDescriptor)
|
||||
@Nullable Config config, @Nullable ConfigDescriptor configDescriptor)
|
||||
{
|
||||
this(configPanel, configManager, plugin, config, configDescriptor,
|
||||
descriptor.name(), descriptor.description(), descriptor.tags());
|
||||
@@ -133,13 +133,13 @@ public class PluginListItem extends JPanel
|
||||
* Creates a new {@code PluginListItem} for a core configuration.
|
||||
*/
|
||||
PluginListItem(ConfigPanel configPanel, ConfigManager configManager, Config config, ConfigDescriptor configDescriptor,
|
||||
String name, String description, String... tags)
|
||||
String name, String description, String... tags)
|
||||
{
|
||||
this(configPanel, configManager, null, config, configDescriptor, name, description, tags);
|
||||
}
|
||||
|
||||
private PluginListItem(ConfigPanel configPanel, ConfigManager configManager, @Nullable Plugin plugin, @Nullable Config config,
|
||||
@Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags)
|
||||
@Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags)
|
||||
{
|
||||
this.configPanel = configPanel;
|
||||
this.configManager = configManager;
|
||||
|
||||
@@ -156,7 +156,7 @@ public class DemonicGorillaPlugin extends Plugin
|
||||
}
|
||||
|
||||
private void checkGorillaAttackStyleSwitch(DemonicGorilla gorilla,
|
||||
final DemonicGorilla.AttackStyle... protectedStyles)
|
||||
final DemonicGorilla.AttackStyle... protectedStyles)
|
||||
{
|
||||
if (gorilla.getAttacksUntilSwitch() <= 0 ||
|
||||
gorilla.getNextPosibleAttackStyles().isEmpty())
|
||||
|
||||
@@ -357,11 +357,11 @@ public class EasyscapePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getGlory())
|
||||
{
|
||||
if (target.toLowerCase().contains("amulet of glory") || target.toLowerCase().contains("amulet of eternal glory"))
|
||||
{
|
||||
switch (config.getGloryMode())
|
||||
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);
|
||||
|
||||
@@ -66,10 +66,7 @@ public class PrayerTracker
|
||||
}
|
||||
if (actor instanceof Player)
|
||||
{
|
||||
if (actor instanceof Player)
|
||||
{
|
||||
newTick.get(actor).put("PrayerIcon", ((Player) actor).getOverheadIcon() == null ? -1 : ((Player) actor).getOverheadIcon().ordinal());
|
||||
}
|
||||
newTick.get(actor).put("PrayerIcon", ((Player) actor).getOverheadIcon() == null ? -1 : ((Player) actor).getOverheadIcon().ordinal());
|
||||
}
|
||||
newTick.get(actor).put("SpotAnim", actor.getGraphic());
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
)
|
||||
public class FriendTaggingPlugin extends Plugin
|
||||
{
|
||||
public static ConcurrentHashMap<String, String> taggedFriends = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentHashMap<String, String> taggedFriends = new ConcurrentHashMap<>();
|
||||
|
||||
private static final String CONFIG_GROUP = "friendtagging";
|
||||
private static final int CHARACTER_LIMIT = 30;
|
||||
|
||||
@@ -718,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)
|
||||
{
|
||||
@@ -744,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)
|
||||
{
|
||||
|
||||
@@ -214,7 +214,7 @@ class InstanceMapOverlay extends Overlay
|
||||
* @param graphics graphics to be drawn to
|
||||
*/
|
||||
private void drawPlayerDot(Graphics2D graphics, Player player,
|
||||
Color dotColor, Color outlineColor)
|
||||
Color dotColor, Color outlineColor)
|
||||
{
|
||||
LocalPoint playerLoc = player.getLocalLocation();
|
||||
|
||||
|
||||
@@ -1,130 +1,130 @@
|
||||
/*
|
||||
* 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.inventorysetups.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.ItemVariationMapping;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupConfig;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
|
||||
public abstract class InventorySetupContainerPanel extends JPanel
|
||||
{
|
||||
protected ItemManager itemManager;
|
||||
|
||||
private final InventorySetupPlugin plugin;
|
||||
|
||||
InventorySetupContainerPanel(final ItemManager itemManager, final InventorySetupPlugin plugin, String captionText)
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
this.plugin = plugin;
|
||||
JPanel containerPanel = new JPanel();
|
||||
|
||||
final JPanel containerSlotsPanel = new JPanel();
|
||||
|
||||
setupContainerPanel(containerSlotsPanel);
|
||||
|
||||
// caption
|
||||
final JLabel caption = new JLabel(captionText);
|
||||
caption.setHorizontalAlignment(JLabel.CENTER);
|
||||
caption.setVerticalAlignment(JLabel.CENTER);
|
||||
|
||||
// panel that holds the caption and any other graphics
|
||||
final JPanel captionPanel = new JPanel();
|
||||
captionPanel.add(caption);
|
||||
|
||||
containerPanel.setLayout(new BorderLayout());
|
||||
containerPanel.add(captionPanel, BorderLayout.NORTH);
|
||||
containerPanel.add(containerSlotsPanel, BorderLayout.CENTER);
|
||||
|
||||
add(containerPanel);
|
||||
}
|
||||
|
||||
void setContainerSlot(int index,
|
||||
final InventorySetupSlot containerSlot,
|
||||
final ArrayList<InventorySetupItem> items)
|
||||
{
|
||||
if (index >= items.size() || items.get(index).getId() == -1)
|
||||
{
|
||||
containerSlot.setImageLabel(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = items.get(index).getId();
|
||||
int quantity = items.get(index).getQuantity();
|
||||
final String itemName = items.get(index).getName();
|
||||
AsyncBufferedImage itemImg = itemManager.getImage(itemId, quantity, quantity > 1);
|
||||
String toolTip = itemName;
|
||||
if (quantity > 1)
|
||||
{
|
||||
toolTip += " (" + quantity + ")";
|
||||
}
|
||||
containerSlot.setImageLabel(toolTip, itemImg);
|
||||
}
|
||||
|
||||
void highlightDifferentSlotColor(InventorySetupItem savedItem,
|
||||
InventorySetupItem currItem,
|
||||
final InventorySetupSlot containerSlot)
|
||||
{
|
||||
// important note: do not use item names for comparisons
|
||||
// they are all empty to avoid clientThread usage when highlighting
|
||||
|
||||
final InventorySetupConfig config = plugin.getConfig();
|
||||
final Color highlightColor = config.getHighlightColor();
|
||||
|
||||
if (config.getStackDifference() && currItem.getQuantity() != savedItem.getQuantity())
|
||||
{
|
||||
containerSlot.setBackground(highlightColor);
|
||||
return;
|
||||
}
|
||||
|
||||
int currId = currItem.getId();
|
||||
int checkId = savedItem.getId();
|
||||
|
||||
if (!config.getVariationDifference())
|
||||
{
|
||||
currId = ItemVariationMapping.map(currId);
|
||||
checkId = ItemVariationMapping.map(checkId);
|
||||
}
|
||||
|
||||
if (currId != checkId)
|
||||
{
|
||||
containerSlot.setBackground(highlightColor);
|
||||
return;
|
||||
}
|
||||
|
||||
// set the color back to the original, because they match
|
||||
containerSlot.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
|
||||
abstract public void setupContainerPanel(final JPanel containerSlotsPanel);
|
||||
/*
|
||||
* 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.inventorysetups.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.ItemVariationMapping;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupConfig;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
|
||||
public abstract class InventorySetupContainerPanel extends JPanel
|
||||
{
|
||||
protected ItemManager itemManager;
|
||||
|
||||
private final InventorySetupPlugin plugin;
|
||||
|
||||
InventorySetupContainerPanel(final ItemManager itemManager, final InventorySetupPlugin plugin, String captionText)
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
this.plugin = plugin;
|
||||
JPanel containerPanel = new JPanel();
|
||||
|
||||
final JPanel containerSlotsPanel = new JPanel();
|
||||
|
||||
setupContainerPanel(containerSlotsPanel);
|
||||
|
||||
// caption
|
||||
final JLabel caption = new JLabel(captionText);
|
||||
caption.setHorizontalAlignment(JLabel.CENTER);
|
||||
caption.setVerticalAlignment(JLabel.CENTER);
|
||||
|
||||
// panel that holds the caption and any other graphics
|
||||
final JPanel captionPanel = new JPanel();
|
||||
captionPanel.add(caption);
|
||||
|
||||
containerPanel.setLayout(new BorderLayout());
|
||||
containerPanel.add(captionPanel, BorderLayout.NORTH);
|
||||
containerPanel.add(containerSlotsPanel, BorderLayout.CENTER);
|
||||
|
||||
add(containerPanel);
|
||||
}
|
||||
|
||||
void setContainerSlot(int index,
|
||||
final InventorySetupSlot containerSlot,
|
||||
final ArrayList<InventorySetupItem> items)
|
||||
{
|
||||
if (index >= items.size() || items.get(index).getId() == -1)
|
||||
{
|
||||
containerSlot.setImageLabel(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = items.get(index).getId();
|
||||
int quantity = items.get(index).getQuantity();
|
||||
final String itemName = items.get(index).getName();
|
||||
AsyncBufferedImage itemImg = itemManager.getImage(itemId, quantity, quantity > 1);
|
||||
String toolTip = itemName;
|
||||
if (quantity > 1)
|
||||
{
|
||||
toolTip += " (" + quantity + ")";
|
||||
}
|
||||
containerSlot.setImageLabel(toolTip, itemImg);
|
||||
}
|
||||
|
||||
void highlightDifferentSlotColor(InventorySetupItem savedItem,
|
||||
InventorySetupItem currItem,
|
||||
final InventorySetupSlot containerSlot)
|
||||
{
|
||||
// important note: do not use item names for comparisons
|
||||
// they are all empty to avoid clientThread usage when highlighting
|
||||
|
||||
final InventorySetupConfig config = plugin.getConfig();
|
||||
final Color highlightColor = config.getHighlightColor();
|
||||
|
||||
if (config.getStackDifference() && currItem.getQuantity() != savedItem.getQuantity())
|
||||
{
|
||||
containerSlot.setBackground(highlightColor);
|
||||
return;
|
||||
}
|
||||
|
||||
int currId = currItem.getId();
|
||||
int checkId = savedItem.getId();
|
||||
|
||||
if (!config.getVariationDifference())
|
||||
{
|
||||
currId = ItemVariationMapping.map(currId);
|
||||
checkId = ItemVariationMapping.map(checkId);
|
||||
}
|
||||
|
||||
if (currId != checkId)
|
||||
{
|
||||
containerSlot.setBackground(highlightColor);
|
||||
return;
|
||||
}
|
||||
|
||||
// set the color back to the original, because they match
|
||||
containerSlot.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
}
|
||||
|
||||
abstract public void setupContainerPanel(final JPanel containerSlotsPanel);
|
||||
}
|
||||
@@ -1,307 +1,307 @@
|
||||
/*
|
||||
* 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.inventorysetups.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetup;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.PluginErrorPanel;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
public class InventorySetupPluginPanel extends PluginPanel
|
||||
{
|
||||
private static ImageIcon ADD_ICON;
|
||||
private static ImageIcon ADD_HOVER_ICON;
|
||||
private static ImageIcon REMOVE_ICON;
|
||||
private static ImageIcon REMOVE_HOVER_ICON;
|
||||
|
||||
private final JPanel noSetupsPanel;
|
||||
private final JPanel invEqPanel;
|
||||
|
||||
private final InventorySetupInventoryPanel invPanel;
|
||||
private final InventorySetupEquipmentPanel eqpPanel;
|
||||
|
||||
private final JComboBox<String> setupComboBox;
|
||||
|
||||
private final JLabel removeMarker;
|
||||
|
||||
private final InventorySetupPlugin plugin;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "add_icon.png");
|
||||
ADD_ICON = new ImageIcon(addIcon);
|
||||
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
|
||||
|
||||
final BufferedImage removeIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "remove_icon.png");
|
||||
REMOVE_ICON = new ImageIcon(removeIcon);
|
||||
REMOVE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(removeIcon, 0.53f));
|
||||
}
|
||||
|
||||
public InventorySetupPluginPanel(final InventorySetupPlugin plugin, final ItemManager itemManager)
|
||||
{
|
||||
super(false);
|
||||
this.plugin = plugin;
|
||||
this.removeMarker = new JLabel(REMOVE_ICON);
|
||||
this.invPanel = new InventorySetupInventoryPanel(itemManager, plugin);
|
||||
this.eqpPanel = new InventorySetupEquipmentPanel(itemManager, plugin);
|
||||
this.noSetupsPanel = new JPanel();
|
||||
this.invEqPanel = new JPanel();
|
||||
this.setupComboBox = new JComboBox<>();
|
||||
|
||||
// setup the title
|
||||
final JLabel addMarker = new JLabel(ADD_ICON);
|
||||
final JLabel title = new JLabel();
|
||||
title.setText("Inventory Setups");
|
||||
title.setForeground(Color.WHITE);
|
||||
|
||||
// setup the add marker (+ sign in the top right)
|
||||
addMarker.setToolTipText("Add a new inventory setup");
|
||||
addMarker.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
plugin.addInventorySetup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
addMarker.setIcon(ADD_HOVER_ICON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
addMarker.setIcon(ADD_ICON);
|
||||
}
|
||||
});
|
||||
|
||||
// setup the remove marker (X sign in the top right)
|
||||
removeMarker.setToolTipText("Remove the current inventory setup");
|
||||
removeMarker.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
final String name = (String) setupComboBox.getSelectedItem();
|
||||
plugin.removeInventorySetup(name, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
if (removeMarker.isEnabled())
|
||||
{
|
||||
removeMarker.setIcon(REMOVE_HOVER_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
removeMarker.setIcon(REMOVE_ICON);
|
||||
}
|
||||
});
|
||||
|
||||
// setup the combo box for selection switching
|
||||
// add empty to indicate the empty position
|
||||
setupComboBox.addItem("");
|
||||
setupComboBox.setSelectedIndex(0);
|
||||
setupComboBox.addItemListener(e ->
|
||||
{
|
||||
if (e.getStateChange() == ItemEvent.SELECTED)
|
||||
{
|
||||
String selection = (String) e.getItem();
|
||||
setCurrentInventorySetup(selection);
|
||||
}
|
||||
});
|
||||
|
||||
// the panel on the top right that holds the add and delete buttons
|
||||
final JPanel markersPanel = new JPanel();
|
||||
markersPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 0));
|
||||
markersPanel.add(removeMarker);
|
||||
markersPanel.add(addMarker);
|
||||
|
||||
// the top panel that has the title and the buttons
|
||||
final JPanel titleAndMarkersPanel = new JPanel();
|
||||
titleAndMarkersPanel.setLayout(new BorderLayout());
|
||||
titleAndMarkersPanel.add(title, BorderLayout.WEST);
|
||||
titleAndMarkersPanel.add(markersPanel, BorderLayout.EAST);
|
||||
|
||||
// the panel that stays at the top and doesn't scroll
|
||||
// contains the title, buttons, and the combo box
|
||||
final JPanel northAnchoredPanel = new JPanel();
|
||||
northAnchoredPanel.setLayout(new BoxLayout(northAnchoredPanel, BoxLayout.Y_AXIS));
|
||||
northAnchoredPanel.setBorder(new EmptyBorder(0, 0, 10, 0));
|
||||
northAnchoredPanel.add(titleAndMarkersPanel);
|
||||
northAnchoredPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
northAnchoredPanel.add(setupComboBox);
|
||||
|
||||
// the panel that holds the inventory and equipment panels
|
||||
final BoxLayout invEqLayout = new BoxLayout(invEqPanel, BoxLayout.Y_AXIS);
|
||||
invEqPanel.setLayout(invEqLayout);
|
||||
invEqPanel.add(invPanel);
|
||||
invEqPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
invEqPanel.add(eqpPanel);
|
||||
|
||||
// setup the error panel. It's wrapped around a normal panel
|
||||
// so it doesn't stretch to fill the parent panel
|
||||
final PluginErrorPanel errorPanel = new PluginErrorPanel();
|
||||
errorPanel.setContent("Inventory Setups", "Select or create an inventory setup.");
|
||||
noSetupsPanel.add(errorPanel);
|
||||
|
||||
// the panel that holds the inventory panels, and the error panel
|
||||
final JPanel contentPanel = new JPanel();
|
||||
final BoxLayout contentLayout = new BoxLayout(contentPanel, BoxLayout.Y_AXIS);
|
||||
contentPanel.setLayout(contentLayout);
|
||||
contentPanel.add(invEqPanel);
|
||||
contentPanel.add(noSetupsPanel);
|
||||
|
||||
// wrapper for the main content panel to keep it from stretching
|
||||
final JPanel contentWrapper = new JPanel(new BorderLayout());
|
||||
contentWrapper.add(Box.createGlue(), BorderLayout.CENTER);
|
||||
contentWrapper.add(contentPanel, BorderLayout.NORTH);
|
||||
final JScrollPane contentWrapperPane = new JScrollPane(contentWrapper);
|
||||
contentWrapperPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
add(northAnchoredPanel, BorderLayout.NORTH);
|
||||
add(contentWrapperPane, BorderLayout.CENTER);
|
||||
|
||||
// show the no setups panel on startup
|
||||
showNoSetupsPanel();
|
||||
|
||||
}
|
||||
|
||||
public void showNoSetupsPanel()
|
||||
{
|
||||
setupComboBox.setSelectedIndex(0);
|
||||
removeMarker.setEnabled(false);
|
||||
noSetupsPanel.setVisible(true);
|
||||
invEqPanel.setVisible(false);
|
||||
}
|
||||
|
||||
private void showHasSetupPanel(final String name)
|
||||
{
|
||||
setupComboBox.setSelectedItem(name);
|
||||
removeMarker.setEnabled(true);
|
||||
noSetupsPanel.setVisible(false);
|
||||
invEqPanel.setVisible(true);
|
||||
}
|
||||
|
||||
public void setCurrentInventorySetup(final String name)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
showNoSetupsPanel();
|
||||
return;
|
||||
}
|
||||
|
||||
showHasSetupPanel(name);
|
||||
|
||||
final InventorySetup inventorySetup = plugin.getInventorySetup(name);
|
||||
|
||||
invPanel.setInventorySetupSlots(inventorySetup);
|
||||
eqpPanel.setEquipmentSetupSlots(inventorySetup);
|
||||
|
||||
if (plugin.getHighlightDifference())
|
||||
{
|
||||
final ArrayList<InventorySetupItem> normInv = plugin.getNormalizedContainer(InventoryID.INVENTORY);
|
||||
final ArrayList<InventorySetupItem> normEqp = plugin.getNormalizedContainer(InventoryID.EQUIPMENT);
|
||||
|
||||
highlightDifferences(normInv, inventorySetup, InventoryID.INVENTORY);
|
||||
highlightDifferences(normEqp, inventorySetup, InventoryID.EQUIPMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
invPanel.resetInventorySlotsColor();
|
||||
eqpPanel.resetEquipmentSlotsColor();
|
||||
}
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void addInventorySetup(final String name)
|
||||
{
|
||||
setupComboBox.addItem(name);
|
||||
}
|
||||
|
||||
public void removeInventorySetup(final String name)
|
||||
{
|
||||
setupComboBox.removeItem(name);
|
||||
showNoSetupsPanel();
|
||||
|
||||
invPanel.resetInventorySlotsColor();
|
||||
eqpPanel.resetEquipmentSlotsColor();
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void highlightDifferences(final ArrayList<InventorySetupItem> container,
|
||||
final InventorySetup setupToCheck,
|
||||
final InventoryID type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INVENTORY:
|
||||
invPanel.highlightDifferentSlots(container, setupToCheck);
|
||||
break;
|
||||
|
||||
case EQUIPMENT:
|
||||
eqpPanel.highlightDifferences(container, setupToCheck);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public final String getSelectedInventorySetup()
|
||||
{
|
||||
return (String) setupComboBox.getSelectedItem();
|
||||
}
|
||||
/*
|
||||
* 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.inventorysetups.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetup;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupItem;
|
||||
import net.runelite.client.plugins.inventorysetups.InventorySetupPlugin;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import net.runelite.client.ui.components.PluginErrorPanel;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
public class InventorySetupPluginPanel extends PluginPanel
|
||||
{
|
||||
private static ImageIcon ADD_ICON;
|
||||
private static ImageIcon ADD_HOVER_ICON;
|
||||
private static ImageIcon REMOVE_ICON;
|
||||
private static ImageIcon REMOVE_HOVER_ICON;
|
||||
|
||||
private final JPanel noSetupsPanel;
|
||||
private final JPanel invEqPanel;
|
||||
|
||||
private final InventorySetupInventoryPanel invPanel;
|
||||
private final InventorySetupEquipmentPanel eqpPanel;
|
||||
|
||||
private final JComboBox<String> setupComboBox;
|
||||
|
||||
private final JLabel removeMarker;
|
||||
|
||||
private final InventorySetupPlugin plugin;
|
||||
|
||||
static
|
||||
{
|
||||
final BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "add_icon.png");
|
||||
ADD_ICON = new ImageIcon(addIcon);
|
||||
ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
|
||||
|
||||
final BufferedImage removeIcon = ImageUtil.getResourceStreamFromClass(InventorySetupPlugin.class, "remove_icon.png");
|
||||
REMOVE_ICON = new ImageIcon(removeIcon);
|
||||
REMOVE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(removeIcon, 0.53f));
|
||||
}
|
||||
|
||||
public InventorySetupPluginPanel(final InventorySetupPlugin plugin, final ItemManager itemManager)
|
||||
{
|
||||
super(false);
|
||||
this.plugin = plugin;
|
||||
this.removeMarker = new JLabel(REMOVE_ICON);
|
||||
this.invPanel = new InventorySetupInventoryPanel(itemManager, plugin);
|
||||
this.eqpPanel = new InventorySetupEquipmentPanel(itemManager, plugin);
|
||||
this.noSetupsPanel = new JPanel();
|
||||
this.invEqPanel = new JPanel();
|
||||
this.setupComboBox = new JComboBox<>();
|
||||
|
||||
// setup the title
|
||||
final JLabel addMarker = new JLabel(ADD_ICON);
|
||||
final JLabel title = new JLabel();
|
||||
title.setText("Inventory Setups");
|
||||
title.setForeground(Color.WHITE);
|
||||
|
||||
// setup the add marker (+ sign in the top right)
|
||||
addMarker.setToolTipText("Add a new inventory setup");
|
||||
addMarker.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
plugin.addInventorySetup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
addMarker.setIcon(ADD_HOVER_ICON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
addMarker.setIcon(ADD_ICON);
|
||||
}
|
||||
});
|
||||
|
||||
// setup the remove marker (X sign in the top right)
|
||||
removeMarker.setToolTipText("Remove the current inventory setup");
|
||||
removeMarker.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
final String name = (String) setupComboBox.getSelectedItem();
|
||||
plugin.removeInventorySetup(name, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
if (removeMarker.isEnabled())
|
||||
{
|
||||
removeMarker.setIcon(REMOVE_HOVER_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
removeMarker.setIcon(REMOVE_ICON);
|
||||
}
|
||||
});
|
||||
|
||||
// setup the combo box for selection switching
|
||||
// add empty to indicate the empty position
|
||||
setupComboBox.addItem("");
|
||||
setupComboBox.setSelectedIndex(0);
|
||||
setupComboBox.addItemListener(e ->
|
||||
{
|
||||
if (e.getStateChange() == ItemEvent.SELECTED)
|
||||
{
|
||||
String selection = (String) e.getItem();
|
||||
setCurrentInventorySetup(selection);
|
||||
}
|
||||
});
|
||||
|
||||
// the panel on the top right that holds the add and delete buttons
|
||||
final JPanel markersPanel = new JPanel();
|
||||
markersPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 0));
|
||||
markersPanel.add(removeMarker);
|
||||
markersPanel.add(addMarker);
|
||||
|
||||
// the top panel that has the title and the buttons
|
||||
final JPanel titleAndMarkersPanel = new JPanel();
|
||||
titleAndMarkersPanel.setLayout(new BorderLayout());
|
||||
titleAndMarkersPanel.add(title, BorderLayout.WEST);
|
||||
titleAndMarkersPanel.add(markersPanel, BorderLayout.EAST);
|
||||
|
||||
// the panel that stays at the top and doesn't scroll
|
||||
// contains the title, buttons, and the combo box
|
||||
final JPanel northAnchoredPanel = new JPanel();
|
||||
northAnchoredPanel.setLayout(new BoxLayout(northAnchoredPanel, BoxLayout.Y_AXIS));
|
||||
northAnchoredPanel.setBorder(new EmptyBorder(0, 0, 10, 0));
|
||||
northAnchoredPanel.add(titleAndMarkersPanel);
|
||||
northAnchoredPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
northAnchoredPanel.add(setupComboBox);
|
||||
|
||||
// the panel that holds the inventory and equipment panels
|
||||
final BoxLayout invEqLayout = new BoxLayout(invEqPanel, BoxLayout.Y_AXIS);
|
||||
invEqPanel.setLayout(invEqLayout);
|
||||
invEqPanel.add(invPanel);
|
||||
invEqPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
invEqPanel.add(eqpPanel);
|
||||
|
||||
// setup the error panel. It's wrapped around a normal panel
|
||||
// so it doesn't stretch to fill the parent panel
|
||||
final PluginErrorPanel errorPanel = new PluginErrorPanel();
|
||||
errorPanel.setContent("Inventory Setups", "Select or create an inventory setup.");
|
||||
noSetupsPanel.add(errorPanel);
|
||||
|
||||
// the panel that holds the inventory panels, and the error panel
|
||||
final JPanel contentPanel = new JPanel();
|
||||
final BoxLayout contentLayout = new BoxLayout(contentPanel, BoxLayout.Y_AXIS);
|
||||
contentPanel.setLayout(contentLayout);
|
||||
contentPanel.add(invEqPanel);
|
||||
contentPanel.add(noSetupsPanel);
|
||||
|
||||
// wrapper for the main content panel to keep it from stretching
|
||||
final JPanel contentWrapper = new JPanel(new BorderLayout());
|
||||
contentWrapper.add(Box.createGlue(), BorderLayout.CENTER);
|
||||
contentWrapper.add(contentPanel, BorderLayout.NORTH);
|
||||
final JScrollPane contentWrapperPane = new JScrollPane(contentWrapper);
|
||||
contentWrapperPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
add(northAnchoredPanel, BorderLayout.NORTH);
|
||||
add(contentWrapperPane, BorderLayout.CENTER);
|
||||
|
||||
// show the no setups panel on startup
|
||||
showNoSetupsPanel();
|
||||
|
||||
}
|
||||
|
||||
public void showNoSetupsPanel()
|
||||
{
|
||||
setupComboBox.setSelectedIndex(0);
|
||||
removeMarker.setEnabled(false);
|
||||
noSetupsPanel.setVisible(true);
|
||||
invEqPanel.setVisible(false);
|
||||
}
|
||||
|
||||
private void showHasSetupPanel(final String name)
|
||||
{
|
||||
setupComboBox.setSelectedItem(name);
|
||||
removeMarker.setEnabled(true);
|
||||
noSetupsPanel.setVisible(false);
|
||||
invEqPanel.setVisible(true);
|
||||
}
|
||||
|
||||
public void setCurrentInventorySetup(final String name)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
showNoSetupsPanel();
|
||||
return;
|
||||
}
|
||||
|
||||
showHasSetupPanel(name);
|
||||
|
||||
final InventorySetup inventorySetup = plugin.getInventorySetup(name);
|
||||
|
||||
invPanel.setInventorySetupSlots(inventorySetup);
|
||||
eqpPanel.setEquipmentSetupSlots(inventorySetup);
|
||||
|
||||
if (plugin.getHighlightDifference())
|
||||
{
|
||||
final ArrayList<InventorySetupItem> normInv = plugin.getNormalizedContainer(InventoryID.INVENTORY);
|
||||
final ArrayList<InventorySetupItem> normEqp = plugin.getNormalizedContainer(InventoryID.EQUIPMENT);
|
||||
|
||||
highlightDifferences(normInv, inventorySetup, InventoryID.INVENTORY);
|
||||
highlightDifferences(normEqp, inventorySetup, InventoryID.EQUIPMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
invPanel.resetInventorySlotsColor();
|
||||
eqpPanel.resetEquipmentSlotsColor();
|
||||
}
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void addInventorySetup(final String name)
|
||||
{
|
||||
setupComboBox.addItem(name);
|
||||
}
|
||||
|
||||
public void removeInventorySetup(final String name)
|
||||
{
|
||||
setupComboBox.removeItem(name);
|
||||
showNoSetupsPanel();
|
||||
|
||||
invPanel.resetInventorySlotsColor();
|
||||
eqpPanel.resetEquipmentSlotsColor();
|
||||
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void highlightDifferences(final ArrayList<InventorySetupItem> container,
|
||||
final InventorySetup setupToCheck,
|
||||
final InventoryID type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INVENTORY:
|
||||
invPanel.highlightDifferentSlots(container, setupToCheck);
|
||||
break;
|
||||
|
||||
case EQUIPMENT:
|
||||
eqpPanel.highlightDifferences(container, setupToCheck);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public final String getSelectedInventorySetup()
|
||||
{
|
||||
return (String) setupComboBox.getSelectedItem();
|
||||
}
|
||||
}
|
||||
@@ -214,13 +214,9 @@ public class ItemStatPlugin extends Plugin
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL);
|
||||
closeButton.setAction(0, "Close");
|
||||
closeButton.setOnMouseOverListener((JavaScriptCallback) (ev) ->
|
||||
{
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL_HOVERED);
|
||||
});
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL_HOVERED));
|
||||
closeButton.setOnMouseLeaveListener((JavaScriptCallback) (ev) ->
|
||||
{
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL);
|
||||
});
|
||||
closeButton.setSpriteId(SpriteID.BOTTOM_LINE_MODE_WINDOW_CLOSE_BUTTON_SMALL));
|
||||
closeButton.setOnOpListener((JavaScriptCallback) (ev) -> resetGEInventory());
|
||||
closeButton.setHasListener(true);
|
||||
closeButton.revalidate();
|
||||
@@ -349,7 +345,7 @@ public class ItemStatPlugin extends Plugin
|
||||
}
|
||||
|
||||
private static Widget createText(Widget parent, String text, int fontId, int textColor,
|
||||
int x, int y, int width, int height)
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
final Widget widget = parent.createChild(-1, WidgetType.TEXT);
|
||||
widget.setText(text);
|
||||
|
||||
@@ -60,7 +60,7 @@ public class GraveyardRoom extends MTARoom
|
||||
|
||||
@Inject
|
||||
private GraveyardRoom(MTAConfig config, Client client, MTAPlugin plugin,
|
||||
ItemManager itemManager, InfoBoxManager infoBoxManager)
|
||||
ItemManager itemManager, InfoBoxManager infoBoxManager)
|
||||
{
|
||||
super(config);
|
||||
this.client = client;
|
||||
|
||||
@@ -266,9 +266,9 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
description = "The location of the skull icon for skulled players",
|
||||
group = "Target Indicator"
|
||||
)
|
||||
default PlayerIndicatorsPlugin.minimapSkullLocations skullLocation()
|
||||
default PlayerIndicatorsPlugin.MinimapSkullLocations skullLocation()
|
||||
{
|
||||
return PlayerIndicatorsPlugin.minimapSkullLocations.AFTER_NAME;
|
||||
return PlayerIndicatorsPlugin.MinimapSkullLocations.AFTER_NAME;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
|
||||
@@ -97,7 +97,7 @@ public class PlayerIndicatorsMinimapOverlay extends Overlay
|
||||
{
|
||||
int width = graphics.getFontMetrics().stringWidth(name);
|
||||
int height = graphics.getFontMetrics().getHeight();
|
||||
if (config.skullLocation().equals(PlayerIndicatorsPlugin.minimapSkullLocations.AFTER_NAME))
|
||||
if (config.skullLocation().equals(PlayerIndicatorsPlugin.MinimapSkullLocations.AFTER_NAME))
|
||||
{
|
||||
OverlayUtil.renderImageLocation(graphics, new Point(minimapLocation.getX()
|
||||
+ width, minimapLocation.getY() - height),
|
||||
|
||||
@@ -217,7 +217,7 @@ public class PlayerIndicatorsOverlay extends Overlay
|
||||
{
|
||||
int width = graphics.getFontMetrics().stringWidth(name);
|
||||
int height = graphics.getFontMetrics().getHeight();
|
||||
if (config.skullLocation().equals(PlayerIndicatorsPlugin.minimapSkullLocations.AFTER_NAME))
|
||||
if (config.skullLocation().equals(PlayerIndicatorsPlugin.MinimapSkullLocations.AFTER_NAME))
|
||||
{
|
||||
OverlayUtil.renderImageLocation(graphics, new Point(textLocation.getX()
|
||||
+ width, textLocation.getY() - height),
|
||||
|
||||
@@ -365,7 +365,7 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
public enum minimapSkullLocations
|
||||
public enum MinimapSkullLocations
|
||||
{
|
||||
BEFORE_NAME,
|
||||
AFTER_NAME
|
||||
|
||||
@@ -100,6 +100,7 @@ public class PlayerInfoCustomIndicator extends InfoBox
|
||||
break;
|
||||
case SPECIAL:
|
||||
currLvl = client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT) / 1000.0F;
|
||||
break;
|
||||
case WORLD:
|
||||
currLvl = 1000; // hacky
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ public class IDAStarMM extends IDAStar
|
||||
Point locSwap = new Point(locBlank.getX(), locBlank.getY() + 1);
|
||||
swap(locBlank, locSwap);
|
||||
}
|
||||
else if (distY <= -1)
|
||||
else
|
||||
{
|
||||
Point locSwap = new Point(locBlank.getX(), locBlank.getY() - 1);
|
||||
swap(locBlank, locSwap);
|
||||
@@ -252,7 +252,7 @@ public class IDAStarMM extends IDAStar
|
||||
Point locSwap = new Point(locBlank.getX() + 1, locBlank.getY());
|
||||
swap(locBlank, locSwap);
|
||||
}
|
||||
else if (distX <= -1)
|
||||
else
|
||||
{
|
||||
Point locSwap = new Point(locBlank.getX() - 1, locBlank.getY());
|
||||
swap(locBlank, locSwap);
|
||||
|
||||
@@ -162,6 +162,7 @@ public class PyramidPlunderPlugin extends Plugin
|
||||
break;
|
||||
case LOADING:
|
||||
obstacles.clear();
|
||||
break;
|
||||
case LOGGED_IN:
|
||||
if (!isInRegion())
|
||||
{
|
||||
|
||||
@@ -817,7 +817,7 @@ public class RaidsPlugin extends Plugin
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (seconds >= 3600)
|
||||
{
|
||||
builder.append((int) Math.floor(seconds / 3600) + ";");
|
||||
builder.append((int) Math.floor(seconds / 3600)).append(";");
|
||||
}
|
||||
seconds %= 3600;
|
||||
if (builder.toString().equals(""))
|
||||
@@ -842,7 +842,7 @@ public class RaidsPlugin extends Plugin
|
||||
tooltip = null;
|
||||
return;
|
||||
}
|
||||
builder.append("Upper level: " + secondsToTime(upperTime));
|
||||
builder.append("Upper level: ").append(secondsToTime(upperTime));
|
||||
if (middleTime == -1)
|
||||
{
|
||||
if (lowerTime == -1)
|
||||
@@ -852,12 +852,12 @@ public class RaidsPlugin extends Plugin
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("</br>Lower level: " + secondsToTime(lowerTime - upperTime));
|
||||
builder.append("</br>Lower level: ").append(secondsToTime(lowerTime - upperTime));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("</br>Middle level: " + secondsToTime(middleTime - upperTime));
|
||||
builder.append("</br>Middle level: ").append(secondsToTime(middleTime - upperTime));
|
||||
if (lowerTime == -1)
|
||||
{
|
||||
tooltip = builder.toString();
|
||||
@@ -865,7 +865,7 @@ public class RaidsPlugin extends Plugin
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("</br>Lower level: " + secondsToTime(lowerTime - middleTime));
|
||||
builder.append("</br>Lower level: ").append(secondsToTime(lowerTime - middleTime));
|
||||
}
|
||||
}
|
||||
if (raidTime == -1)
|
||||
@@ -873,7 +873,7 @@ public class RaidsPlugin extends Plugin
|
||||
tooltip = builder.toString();
|
||||
return;
|
||||
}
|
||||
builder.append("</br>Olm: " + secondsToTime(raidTime - lowerTime));
|
||||
builder.append("</br>Olm: ").append(secondsToTime(raidTime - lowerTime));
|
||||
tooltip = builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tim Lehner <Timothy.Lehner.2011@live.rhul.ac.uk>
|
||||
* 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.raidsthieving.BatSolver;
|
||||
|
||||
// There are three distinct Thieving rooms, distinguished by the position of the entrance relative to the exit
|
||||
// e.g. If you enter the room and must turn left to get to the exit and trough, this is a LEFT_TURN
|
||||
|
||||
import net.runelite.client.plugins.raidsthieving.InstancePoint;
|
||||
|
||||
public enum ThievingRoomType
|
||||
{
|
||||
LEFT_TURN(3271, 5389),
|
||||
RIGHT_TURN(3350, 5399),
|
||||
STRAIGHT(3317, 5397);
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
ThievingRoomType(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public static ThievingRoomType IdentifyByInstancePoint(InstancePoint point)
|
||||
{
|
||||
for (ThievingRoomType type : ThievingRoomType.values())
|
||||
{
|
||||
if (Math.abs(type.x - point.getX()) <= 1 &&
|
||||
Math.abs(type.y - point.getY()) <= 1)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Tim Lehner <Timothy.Lehner.2011@live.rhul.ac.uk>
|
||||
* 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.raidsthieving.BatSolver;
|
||||
|
||||
// There are three distinct Thieving rooms, distinguished by the position of the entrance relative to the exit
|
||||
// e.g. If you enter the room and must turn left to get to the exit and trough, this is a LEFT_TURN
|
||||
|
||||
import net.runelite.client.plugins.raidsthieving.InstancePoint;
|
||||
|
||||
public enum ThievingRoomType
|
||||
{
|
||||
LEFT_TURN(3271, 5389),
|
||||
RIGHT_TURN(3350, 5399),
|
||||
STRAIGHT(3317, 5397);
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
ThievingRoomType(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public static ThievingRoomType identifyByInstancePoint(InstancePoint point)
|
||||
{
|
||||
for (ThievingRoomType type : ThievingRoomType.values())
|
||||
{
|
||||
if (Math.abs(type.x - point.getX()) <= 1 &&
|
||||
Math.abs(type.y - point.getY()) <= 1)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class RaidsThievingPlugin extends Plugin
|
||||
|
||||
if (obj.getId() == RaidsThievingConstants.EMPTY_TROUGH)
|
||||
{
|
||||
ThievingRoomType type = ThievingRoomType.IdentifyByInstancePoint(absLoc);
|
||||
ThievingRoomType type = ThievingRoomType.identifyByInstancePoint(absLoc);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
|
||||
@@ -1,121 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.regenmeter;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.geom.Arc2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.VarPlayer;
|
||||
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;
|
||||
|
||||
public class RegenMeterOverlay extends Overlay
|
||||
{
|
||||
private static final Color HITPOINTS_COLOR = brighter(0x9B0703);
|
||||
private static final Color SPECIAL_COLOR = brighter(0x1E95B0);
|
||||
private static final Color OVERLAY_COLOR = new Color(255, 255, 255, 60);
|
||||
private static final double DIAMETER = 26D;
|
||||
private static final int OFFSET = 27;
|
||||
|
||||
private final Client client;
|
||||
private RegenMeterPlugin plugin;
|
||||
private RegenMeterConfig config;
|
||||
|
||||
private static Color brighter(int color)
|
||||
{
|
||||
float[] hsv = new float[3];
|
||||
Color.RGBtoHSB(color >>> 16, (color >> 8) & 0xFF, color & 0xFF, hsv);
|
||||
return Color.getHSBColor(hsv[0], 1.f, 1.f);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public RegenMeterOverlay(Client client, RegenMeterPlugin plugin, RegenMeterConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
|
||||
if (config.showHitpoints())
|
||||
{
|
||||
renderRegen(g, WidgetInfo.MINIMAP_HEALTH_ORB, plugin.getHitpointsPercentage(), HITPOINTS_COLOR);
|
||||
}
|
||||
|
||||
if (config.showSpecial())
|
||||
{
|
||||
if (client.getVar(VarPlayer.SPECIAL_ATTACK_ENABLED) == 1)
|
||||
{
|
||||
final Widget widget = client.getWidget(WidgetInfo.MINIMAP_SPEC_ORB);
|
||||
|
||||
if (widget != null && !widget.isHidden())
|
||||
{
|
||||
final Rectangle bounds = widget.getBounds();
|
||||
g.setColor(RegenMeterOverlay.OVERLAY_COLOR);
|
||||
g.fillOval(
|
||||
bounds.x + OFFSET,
|
||||
bounds.y + (int) (bounds.height / 2 - (DIAMETER) / 2),
|
||||
(int) DIAMETER, (int) DIAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
renderRegen(g, WidgetInfo.MINIMAP_SPEC_ORB, plugin.getSpecialPercentage(), SPECIAL_COLOR);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderRegen(Graphics2D g, WidgetInfo widgetInfo, double percent, Color color)
|
||||
{
|
||||
Widget widget = client.getWidget(widgetInfo);
|
||||
if (widget == null || widget.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Rectangle bounds = widget.getBounds();
|
||||
|
||||
Arc2D.Double arc = new Arc2D.Double(bounds.x + OFFSET, bounds.y + (bounds.height / 2 - DIAMETER / 2), DIAMETER, DIAMETER, 90.d, -360.d * percent, Arc2D.OPEN);
|
||||
final Stroke STROKE = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
||||
g.setStroke(STROKE);
|
||||
g.setColor(color);
|
||||
g.draw(arc);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.regenmeter;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.geom.Arc2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.VarPlayer;
|
||||
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;
|
||||
|
||||
public class RegenMeterOverlay extends Overlay
|
||||
{
|
||||
private static final Color HITPOINTS_COLOR = brighter(0x9B0703);
|
||||
private static final Color SPECIAL_COLOR = brighter(0x1E95B0);
|
||||
private static final Color OVERLAY_COLOR = new Color(255, 255, 255, 60);
|
||||
private static final double DIAMETER = 26D;
|
||||
private static final int OFFSET = 27;
|
||||
|
||||
private final Client client;
|
||||
private RegenMeterPlugin plugin;
|
||||
private RegenMeterConfig config;
|
||||
|
||||
private static Color brighter(int color)
|
||||
{
|
||||
float[] hsv = new float[3];
|
||||
Color.RGBtoHSB(color >>> 16, (color >> 8) & 0xFF, color & 0xFF, hsv);
|
||||
return Color.getHSBColor(hsv[0], 1.f, 1.f);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public RegenMeterOverlay(Client client, RegenMeterPlugin plugin, RegenMeterConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
|
||||
if (config.showHitpoints())
|
||||
{
|
||||
renderRegen(g, WidgetInfo.MINIMAP_HEALTH_ORB, plugin.getHitpointsPercentage(), HITPOINTS_COLOR);
|
||||
}
|
||||
|
||||
if (config.showSpecial())
|
||||
{
|
||||
if (client.getVar(VarPlayer.SPECIAL_ATTACK_ENABLED) == 1)
|
||||
{
|
||||
final Widget widget = client.getWidget(WidgetInfo.MINIMAP_SPEC_ORB);
|
||||
|
||||
if (widget != null && !widget.isHidden())
|
||||
{
|
||||
final Rectangle bounds = widget.getBounds();
|
||||
g.setColor(RegenMeterOverlay.OVERLAY_COLOR);
|
||||
g.fillOval(
|
||||
bounds.x + OFFSET,
|
||||
bounds.y + (int) (bounds.height / 2D - (DIAMETER) / 2D),
|
||||
(int) DIAMETER, (int) DIAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
renderRegen(g, WidgetInfo.MINIMAP_SPEC_ORB, plugin.getSpecialPercentage(), SPECIAL_COLOR);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderRegen(Graphics2D g, WidgetInfo widgetInfo, double percent, Color color)
|
||||
{
|
||||
Widget widget = client.getWidget(widgetInfo);
|
||||
if (widget == null || widget.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Rectangle bounds = widget.getBounds();
|
||||
|
||||
Arc2D.Double arc = new Arc2D.Double(bounds.x + OFFSET, bounds.y + (bounds.height / 2D - DIAMETER / 2D), DIAMETER, DIAMETER, 90.d, -360.d * percent, Arc2D.OPEN);
|
||||
final Stroke STROKE = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
||||
g.setStroke(STROKE);
|
||||
g.setColor(color);
|
||||
g.draw(arc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,11 +228,6 @@ public class RunecraftPlugin extends Plugin
|
||||
client.setMenuEntries(newEntries);
|
||||
}
|
||||
|
||||
private int searchIndex(MenuEntry[] entries, String option, String target)
|
||||
{
|
||||
return searchIndex(entries, option, target, false);
|
||||
}
|
||||
|
||||
private int searchIndex(MenuEntry[] entries, String option, String target, boolean contains)
|
||||
{
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
|
||||
@@ -100,16 +100,16 @@ class RunedokuOverlay extends Overlay
|
||||
{
|
||||
if (!util.makeSimple(util.createTable(client)).contains(0))
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, util.RectangleToPolygon(widget.getBounds()), Color.GREEN);
|
||||
OverlayUtil.renderPolygon(graphics, util.rectangleToPolygon(widget.getBounds()), Color.GREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, util.RectangleToPolygon(widget.getBounds()), util.referenceColors(i));
|
||||
OverlayUtil.renderPolygon(graphics, util.rectangleToPolygon(widget.getBounds()), util.referenceColors(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, util.RectangleToPolygon(widget.getBounds()), RED);
|
||||
OverlayUtil.renderPolygon(graphics, util.rectangleToPolygon(widget.getBounds()), RED);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -134,17 +134,17 @@ class RunedokuOverlay extends Overlay
|
||||
{
|
||||
if (!util.makeSimple(util.createTable(client)).contains(0))
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, util.RectangleToPolygon(squareToHighlight.getBounds()), Color.GREEN);
|
||||
OverlayUtil.renderPolygon(graphics, util.rectangleToPolygon(squareToHighlight.getBounds()), Color.GREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, util.RectangleToPolygon(squareToHighlight.getBounds()), util.sudokuPieceToColor(simpleArr.get(iteration)));
|
||||
OverlayUtil.renderPolygon(graphics, util.rectangleToPolygon(squareToHighlight.getBounds()), util.sudokuPieceToColor(simpleArr.get(iteration)));
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, util.RectangleToPolygon(squareToHighlight.getBounds()), RED);
|
||||
OverlayUtil.renderPolygon(graphics, util.rectangleToPolygon(squareToHighlight.getBounds()), RED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
|
||||
public class RunedokuUtil
|
||||
class RunedokuUtil
|
||||
{
|
||||
|
||||
private final RunedokuConfig config;
|
||||
@@ -20,7 +20,7 @@ public class RunedokuUtil
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
protected Color sudokuPieceToColor(int i)
|
||||
Color sudokuPieceToColor(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ public class RunedokuUtil
|
||||
}
|
||||
}
|
||||
|
||||
protected Color referenceColors(int i)
|
||||
Color referenceColors(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
@@ -80,7 +80,7 @@ public class RunedokuUtil
|
||||
* @param board
|
||||
* @return
|
||||
*/
|
||||
protected ArrayList<Integer> makeSimple(int[][] board)
|
||||
ArrayList<Integer> makeSimple(int[][] board)
|
||||
{
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
for (int i = 0; i < 9; i++)
|
||||
@@ -99,7 +99,7 @@ public class RunedokuUtil
|
||||
* @param rect
|
||||
* @return
|
||||
*/
|
||||
protected Polygon RectangleToPolygon(Rectangle rect)
|
||||
public static Polygon rectangleToPolygon(Rectangle rect)
|
||||
{
|
||||
int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x};
|
||||
int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height};
|
||||
@@ -113,7 +113,7 @@ public class RunedokuUtil
|
||||
* @return sudoku table that the client currently sees in a 2d array
|
||||
* @author gazivodag
|
||||
*/
|
||||
protected int[][] createTable(Client client)
|
||||
int[][] createTable(Client client)
|
||||
{
|
||||
int[][] myArr = new int[9][9];
|
||||
Widget sudokuScreen = client.getWidget(288, 131);
|
||||
|
||||
@@ -52,8 +52,8 @@ import net.runelite.client.ui.ClientUI;
|
||||
public class RuneLitePlusPlugin extends Plugin
|
||||
{
|
||||
public static boolean customPresenceEnabled = false;
|
||||
public static String rlPlusDiscordApp = "560644885250572289";
|
||||
public static String rlDiscordApp = "409416265891971072";
|
||||
public static final String rlPlusDiscordApp = "560644885250572289";
|
||||
public static final String rlDiscordApp = "409416265891971072";
|
||||
|
||||
@Inject
|
||||
public RuneLitePlusConfig config;
|
||||
|
||||
@@ -301,7 +301,8 @@ public class SlayerTaskPanel extends PluginPanel
|
||||
if (tasks.isEmpty() || isNewAssignment)
|
||||
{
|
||||
// new task so append it to the front of the list
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
TaskBox newBox = buildBox(slayerPlugin, tasksContainer, newData);
|
||||
newBox.update(true, newData.isPaused(), newData);
|
||||
});
|
||||
@@ -322,7 +323,8 @@ public class SlayerTaskPanel extends PluginPanel
|
||||
|
||||
// so this previous task is invalid so delete it then add in the new actually
|
||||
// correct task
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
tasksContainer.remove(tasks.get(0));
|
||||
tasks.remove(0);
|
||||
TaskBox newBox = buildBox(slayerPlugin, tasksContainer, newData);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class TargetClickboxOverlay extends Overlay
|
||||
|
||||
@Inject
|
||||
TargetClickboxOverlay(Client client, SlayerConfig config, SlayerPlugin plugin,
|
||||
ModelOutlineRenderer modelOutlineRenderer)
|
||||
ModelOutlineRenderer modelOutlineRenderer)
|
||||
{
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
|
||||
@@ -80,7 +80,8 @@ class TaskBox extends JPanel
|
||||
container.setLayout(new BorderLayout());
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
BufferedImage taskImg = slayerPlugin.getImageForTask(Task.getTask(taskData.getTaskName()));
|
||||
JLabel taskIcon = new JLabel(new ImageIcon(taskImg));
|
||||
taskIcon.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
@@ -42,7 +42,8 @@ public class TickCounterOverlay extends Overlay
|
||||
panelComponent.setBackgroundColor(config.bgColor());
|
||||
elems.add(TitleComponent.builder().text("Combat counter").color(config.titleColor()).build());
|
||||
List<Entry<String, Integer>> list = new ArrayList<>(plugin.activity.entrySet());
|
||||
list.sort((o1, o2) -> {
|
||||
list.sort((o1, o2) ->
|
||||
{
|
||||
int value = -Integer.compare(o1.getValue(), o2.getValue());
|
||||
if (value == 0)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ class OverviewTabPanel extends TabContentPanel
|
||||
private final OverviewItemPanel birdHouseOverview;
|
||||
|
||||
OverviewTabPanel(ItemManager itemManager, TimeTrackingConfig config, TimeTrackingPanel pluginPanel,
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager)
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager)
|
||||
{
|
||||
this.config = config;
|
||||
this.farmingTracker = farmingTracker;
|
||||
|
||||
@@ -64,7 +64,7 @@ class TimeTrackingPanel extends PluginPanel
|
||||
private TabContentPanel activeTabPanel = null;
|
||||
|
||||
TimeTrackingPanel(ItemManager itemManager, TimeTrackingConfig config,
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager)
|
||||
FarmingTracker farmingTracker, BirdHouseTracker birdHouseTracker, ClockManager clockManager)
|
||||
{
|
||||
super(false);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class FarmingTracker
|
||||
|
||||
@Inject
|
||||
private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager,
|
||||
TimeTrackingConfig config, FarmingWorld farmingWorld)
|
||||
TimeTrackingConfig config, FarmingWorld farmingWorld)
|
||||
{
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class BirdHouseTracker
|
||||
|
||||
@Inject
|
||||
private BirdHouseTracker(Client client, ItemManager itemManager, ConfigManager configManager,
|
||||
TimeTrackingConfig config, Notifier notifier)
|
||||
TimeTrackingConfig config, Notifier notifier)
|
||||
{
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
|
||||
@@ -121,7 +121,7 @@ public class WhaleWatchersPlugin extends Plugin
|
||||
{
|
||||
if (config.showDamageCounter())
|
||||
{
|
||||
if (!(event.getActor() == client.getLocalPlayer() |
|
||||
if (!(event.getActor() == client.getLocalPlayer() ||
|
||||
event.getActor() == client.getLocalPlayer().getInteracting()))
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -76,7 +76,7 @@ public class WikiSearchChatboxTextInput extends ChatboxTextInput
|
||||
|
||||
@Inject
|
||||
public WikiSearchChatboxTextInput(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread,
|
||||
ScheduledExecutorService scheduledExecutorService, @Named("developerMode") final boolean developerMode)
|
||||
ScheduledExecutorService scheduledExecutorService, @Named("developerMode") final boolean developerMode)
|
||||
{
|
||||
super(chatboxPanelManager, clientThread);
|
||||
this.chatboxPanelManager = chatboxPanelManager;
|
||||
|
||||
@@ -32,17 +32,14 @@ import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import io.sigpipe.jbsdiff.InvalidHeaderException;
|
||||
import io.sigpipe.jbsdiff.Patch;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Attributes;
|
||||
@@ -53,13 +50,10 @@ import java.util.jar.Manifest;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA;
|
||||
|
||||
import net.runelite.client.rs.mixins.MixinRunner;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Request;
|
||||
@@ -72,41 +66,42 @@ public class ClientLoader
|
||||
{
|
||||
private final ClientConfigLoader clientConfigLoader;
|
||||
private ClientUpdateCheckMode updateCheckMode;
|
||||
|
||||
@Inject
|
||||
private ClientLoader(
|
||||
@Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
|
||||
final ClientConfigLoader clientConfigLoader)
|
||||
@Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
|
||||
final ClientConfigLoader clientConfigLoader)
|
||||
{
|
||||
this.updateCheckMode = updateCheckMode;
|
||||
this.clientConfigLoader = clientConfigLoader;
|
||||
}
|
||||
|
||||
|
||||
public Applet load()
|
||||
{
|
||||
if (updateCheckMode == NONE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
RSConfig config = clientConfigLoader.fetch();
|
||||
|
||||
|
||||
Map<String, byte[]> zipFile = new HashMap<>();
|
||||
{
|
||||
String codebase = config.getCodeBase();
|
||||
String initialJar = config.getInitialJar();
|
||||
URL url = new URL(codebase + initialJar);
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
JarInputStream jis;
|
||||
|
||||
|
||||
jis = new JarInputStream(response.body().byteStream());
|
||||
byte[] tmp = new byte[4096];
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
||||
@@ -117,7 +112,7 @@ public class ClientLoader
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
buffer.reset();
|
||||
for (; ; )
|
||||
{
|
||||
@@ -128,12 +123,12 @@ public class ClientLoader
|
||||
}
|
||||
buffer.write(tmp, 0, n);
|
||||
}
|
||||
|
||||
|
||||
zipFile.put(metadata.getName(), buffer.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
Map<String, String> hashes;
|
||||
@@ -143,33 +138,33 @@ public class ClientLoader
|
||||
{
|
||||
}.getType());
|
||||
}
|
||||
|
||||
|
||||
for (Map.Entry<String, String> file : hashes.entrySet())
|
||||
{
|
||||
byte[] bytes = zipFile.get(file.getKey());
|
||||
|
||||
|
||||
String ourHash = null;
|
||||
if (bytes != null)
|
||||
{
|
||||
ourHash = Hashing.sha512().hashBytes(bytes).toString();
|
||||
}
|
||||
|
||||
|
||||
if (!file.getValue().equals(ourHash))
|
||||
{
|
||||
log.info("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(),
|
||||
file.getValue(), ourHash);
|
||||
file.getValue(), ourHash);
|
||||
log.info("Client is outdated!");
|
||||
updateCheckMode = VANILLA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024);
|
||||
int patchCount = 0;
|
||||
|
||||
|
||||
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
|
||||
{
|
||||
byte[] bytes;
|
||||
@@ -179,27 +174,27 @@ public class ClientLoader
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
bytes = ByteStreams.toByteArray(is);
|
||||
}
|
||||
|
||||
|
||||
patchOs.reset();
|
||||
Patch.patch(file.getValue(), bytes, patchOs);
|
||||
file.setValue(patchOs.toByteArray());
|
||||
|
||||
|
||||
++patchCount;
|
||||
}
|
||||
|
||||
|
||||
log.info("Patched {} classes", patchCount);
|
||||
}
|
||||
|
||||
|
||||
log.info("Patching for RuneLitePlus");
|
||||
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
|
||||
|
||||
HashMap<String, byte[]> patches = new HashMap<>();
|
||||
|
||||
|
||||
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
|
||||
{
|
||||
byte[] patchClass;
|
||||
@@ -209,20 +204,20 @@ public class ClientLoader
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
patchClass = ByteStreams.toByteArray(is);
|
||||
}
|
||||
|
||||
|
||||
patches.put(file.getKey(), patchClass);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
new MixinRunner(zipFile, patches).run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
String initialClass = config.getInitialClass();
|
||||
|
||||
|
||||
ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader())
|
||||
{
|
||||
@Override
|
||||
@@ -234,13 +229,13 @@ public class ClientLoader
|
||||
{
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
|
||||
return defineClass(name, data, 0, data.length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Class<?> clientClass = rsClassLoader.loadClass(initialClass);
|
||||
|
||||
|
||||
Applet rs = (Applet) clientClass.newInstance();
|
||||
rs.setStub(new RSAppletStub(config));
|
||||
return rs;
|
||||
@@ -250,15 +245,15 @@ public class ClientLoader
|
||||
if (e instanceof ClassNotFoundException)
|
||||
{
|
||||
log.error("Unable to load client - class not found. This means you"
|
||||
+ " are not running RuneLite with Maven as the client patch"
|
||||
+ " is not in your classpath.");
|
||||
+ " are not running RuneLite with Maven as the client patch"
|
||||
+ " is not in your classpath.");
|
||||
}
|
||||
|
||||
|
||||
log.error("Error loading RS!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void add(byte[] bytes, String entryName, JarOutputStream target) throws IOException
|
||||
{
|
||||
BufferedInputStream in = null;
|
||||
|
||||
@@ -25,8 +25,18 @@
|
||||
|
||||
package net.runelite.client.rs.mixins;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.client.rs.mixins.transformers.*;
|
||||
import net.runelite.client.rs.mixins.transformers.AppendTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.DoNothingTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.InjectTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.InterfaceTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.OverwriteSanityCheck;
|
||||
import net.runelite.client.rs.mixins.transformers.OverwriteTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.PrependTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.ProtectTransformer;
|
||||
import net.runelite.client.rs.mixins.transformers.SanityChecker;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
@@ -34,18 +44,15 @@ import org.objectweb.asm.commons.ClassRemapper;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class MixinRunner
|
||||
{
|
||||
|
||||
|
||||
private final Map<String, byte[]> classes;
|
||||
private final Map<String, byte[]> patches;
|
||||
|
||||
|
||||
public Map<String, byte[]> run()
|
||||
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
|
||||
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
runVisitor(InterfaceTransformer.class);
|
||||
runVisitor(OverwriteTransformer.class);
|
||||
@@ -55,11 +62,11 @@ public class MixinRunner
|
||||
// (test method: Projectile.rl$$init()V )
|
||||
runVisitor(PrependTransformer.class);
|
||||
runRemapper(ProtectTransformer.class);
|
||||
|
||||
|
||||
recalcMaxes();
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
private void runRemapper(Class<? extends Remapper> clazz) throws IllegalAccessException, InstantiationException
|
||||
{
|
||||
for (Map.Entry<String, byte[]> entry : classes.entrySet())
|
||||
@@ -72,19 +79,19 @@ public class MixinRunner
|
||||
ClassReader cr = new ClassReader(entry.getValue());
|
||||
ClassWriter cw = new ClassWriter(cr, 1);
|
||||
cr.accept(new ClassRemapper(cw, inst), 0);
|
||||
|
||||
|
||||
entry.setValue(cw.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void runVisitor(Class<? extends ClassVisitor> clazz)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
runVisitor(clazz, 1);
|
||||
}
|
||||
|
||||
|
||||
private void runVisitor(Class<? extends ClassVisitor> clazz, int flags)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
for (Map.Entry<String, byte[]> entry : classes.entrySet())
|
||||
{
|
||||
@@ -98,21 +105,21 @@ public class MixinRunner
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
ClassVisitor inst = clazz.getConstructor(ClassVisitor.class, byte[].class, ClassNode.class).newInstance(cw,
|
||||
patch, node);
|
||||
patch, node);
|
||||
cr.accept(inst, 0);
|
||||
|
||||
|
||||
entry.setValue(cw.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void runSanityChecker(Class<? extends SanityChecker> clazz)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
runSanityChecker(clazz, 1);
|
||||
}
|
||||
|
||||
|
||||
private void runSanityChecker(Class<? extends SanityChecker> clazz, int flags)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
for (Map.Entry<String, byte[]> entry : patches.entrySet())
|
||||
{
|
||||
@@ -124,11 +131,11 @@ public class MixinRunner
|
||||
cr.accept(inst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void recalcMaxes()
|
||||
throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException
|
||||
throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException
|
||||
{
|
||||
runVisitor(DoNothingTransformer.class, 3);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -40,25 +40,25 @@ import org.objectweb.asm.tree.MethodNode;
|
||||
@Slf4j
|
||||
public class AppendTransformer extends ClassVisitor implements Opcodes
|
||||
{
|
||||
|
||||
|
||||
private final byte[] patch;
|
||||
private String className;
|
||||
private ClassNode classNode;
|
||||
|
||||
|
||||
public AppendTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.classNode = node;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
@@ -73,44 +73,44 @@ public class AppendTransformer extends ClassVisitor implements Opcodes
|
||||
{
|
||||
MethodNode patchMethod = (MethodNode) obj;
|
||||
if ((patchMethod.access == access && patchMethod.name.equals("append$" + name) &&
|
||||
patchMethod.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(patchMethod, "Append"))
|
||||
patchMethod.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(patchMethod, "Append"))
|
||||
{
|
||||
MethodVisitor mv =
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
mv.visitCode();
|
||||
|
||||
|
||||
for (Object obj2 : classNode.methods)
|
||||
{
|
||||
MethodNode classMethod = (MethodNode) obj2;
|
||||
if (classMethod.access == access && classMethod.name.equals(name) &&
|
||||
classMethod.desc.equals(descriptor))
|
||||
classMethod.desc.equals(descriptor))
|
||||
{
|
||||
AbstractInsnNode inode = classMethod.instructions.getLast();
|
||||
|
||||
while(inode instanceof LabelNode || inode instanceof LineNumberNode)
|
||||
|
||||
while (inode instanceof LabelNode || inode instanceof LineNumberNode)
|
||||
{
|
||||
inode = inode.getPrevious();
|
||||
}
|
||||
|
||||
if(RefUtils.isReturn(inode.getOpcode(), true))
|
||||
|
||||
if (RefUtils.isReturn(inode.getOpcode(), true))
|
||||
{
|
||||
log.error("[Append] Can't append to {}.{}, requires typed return opcode", className, name);
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
|
||||
classMethod.instructions.remove(inode);
|
||||
|
||||
|
||||
classMethod.accept(new MethodReflector(mv));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
patchMethod.accept(new MethodReflector(mv));
|
||||
|
||||
|
||||
mv.visitEnd();
|
||||
return mv;
|
||||
}
|
||||
|
||||
@@ -36,26 +36,26 @@ import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class InjectTransformer extends ClassVisitor
|
||||
{
|
||||
|
||||
|
||||
private final byte[] patch;
|
||||
private ClassNode node;
|
||||
private String className;
|
||||
private boolean patching = false;
|
||||
|
||||
|
||||
public InjectTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
@@ -63,8 +63,8 @@ public class InjectTransformer extends ClassVisitor
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
if (name.startsWith("prepend$") || name.startsWith("append$")||
|
||||
(patching && name.startsWith("<")))
|
||||
if (name.startsWith("prepend$") || name.startsWith("append$") ||
|
||||
(patching && name.startsWith("<")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class InjectTransformer extends ClassVisitor
|
||||
{
|
||||
MethodNode node = (MethodNode) obj;
|
||||
if ((node.access == access && node.name.equals(name) && node.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(node, "Inject"))
|
||||
RefUtils.checkAnnotation(node, "Inject"))
|
||||
{
|
||||
mv.visitCode();
|
||||
node.accept(new MethodReflector(mv));
|
||||
@@ -85,17 +85,17 @@ public class InjectTransformer extends ClassVisitor
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
|
||||
|
||||
if (patch == null)
|
||||
{
|
||||
super.visitEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
@@ -106,10 +106,10 @@ public class InjectTransformer extends ClassVisitor
|
||||
if (RefUtils.checkAnnotation(node, "Inject"))
|
||||
{
|
||||
visitMethod(node.access, node.name, node.desc, node.signature,
|
||||
(String[]) node.exceptions.toArray(new String[0]));
|
||||
(String[]) node.exceptions.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (Object obj : patchNode.fields)
|
||||
{
|
||||
FieldNode node = (FieldNode) obj;
|
||||
@@ -121,5 +121,5 @@ public class InjectTransformer extends ClassVisitor
|
||||
patching = false;
|
||||
super.visitEnd();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -25,42 +25,41 @@
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
public class InterfaceTransformer extends ClassVisitor implements Opcodes
|
||||
{
|
||||
|
||||
|
||||
private final byte[] patch;
|
||||
private ClassNode node;
|
||||
private String className;
|
||||
|
||||
|
||||
public InterfaceTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
if(patch != null)
|
||||
if (patch != null)
|
||||
{
|
||||
ClassReader reader = new ClassReader(patch);
|
||||
ClassNode pNode = new ClassNode();
|
||||
reader.accept(pNode, 0);
|
||||
if(pNode.interfaces != null && pNode.interfaces.size() != 0)
|
||||
if (pNode.interfaces != null && pNode.interfaces.size() != 0)
|
||||
{
|
||||
if(interfaces == null)
|
||||
if (interfaces == null)
|
||||
{
|
||||
interfaces = (String[]) pNode.interfaces.toArray(new String[0]);
|
||||
}
|
||||
@@ -74,5 +73,5 @@ public class InterfaceTransformer extends ClassVisitor implements Opcodes
|
||||
}
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -35,15 +35,15 @@ import org.objectweb.asm.TypePath;
|
||||
|
||||
public class MethodReflector extends MethodVisitor
|
||||
{
|
||||
|
||||
|
||||
private MethodVisitor target;
|
||||
|
||||
|
||||
public MethodReflector(MethodVisitor target)
|
||||
{
|
||||
super(Opcodes.ASM6);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
|
||||
public void visitParameter(String var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -52,27 +52,27 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitParameter(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitAnnotationDefault()
|
||||
{
|
||||
return super.visitAnnotationDefault();
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String var1, boolean var2)
|
||||
{
|
||||
return super.visitAnnotation(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitTypeAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
return super.visitTypeAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(int var1, String var2, boolean var3)
|
||||
{
|
||||
return super.visitParameterAnnotation(var1, var2, var3);
|
||||
}
|
||||
|
||||
|
||||
public void visitAttribute(Attribute var1)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -81,7 +81,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitAttribute(var1);
|
||||
}
|
||||
|
||||
|
||||
public void visitFrame(int var1, int var2, Object[] var3, int var4, Object[] var5)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -90,7 +90,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitFrame(var1, var2, var3, var4, var5);
|
||||
}
|
||||
|
||||
|
||||
public void visitInsn(int var1)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -99,7 +99,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitInsn(var1);
|
||||
}
|
||||
|
||||
|
||||
public void visitIntInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -108,7 +108,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitIntInsn(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public void visitVarInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -117,7 +117,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitVarInsn(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public void visitTypeInsn(int var1, String var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -126,7 +126,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitTypeInsn(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public void visitFieldInsn(int var1, String var2, String var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -135,7 +135,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitFieldInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@@ -147,7 +147,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitMethodInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public void visitMethodInsn(int var1, String var2, String var3, String var4, boolean var5)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -156,7 +156,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitMethodInsn(var1, var2, var3, var4, var5);
|
||||
}
|
||||
|
||||
|
||||
public void visitInvokeDynamicInsn(String var1, String var2, Handle var3, Object... var4)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -165,7 +165,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitInvokeDynamicInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public void visitJumpInsn(int var1, Label var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -174,7 +174,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitJumpInsn(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public void visitLabel(Label var1)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -183,7 +183,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitLabel(var1);
|
||||
}
|
||||
|
||||
|
||||
public void visitLdcInsn(Object var1)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -192,7 +192,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitLdcInsn(var1);
|
||||
}
|
||||
|
||||
|
||||
public void visitIincInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -201,7 +201,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitIincInsn(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public void visitTableSwitchInsn(int var1, int var2, Label var3, Label... var4)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -210,7 +210,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitTableSwitchInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public void visitLookupSwitchInsn(Label var1, int[] var2, Label[] var3)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -219,7 +219,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitLookupSwitchInsn(var1, var2, var3);
|
||||
}
|
||||
|
||||
|
||||
public void visitMultiANewArrayInsn(String var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -228,7 +228,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitMultiANewArrayInsn(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitInsnAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -237,7 +237,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
return super.visitInsnAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public void visitTryCatchBlock(Label var1, Label var2, Label var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -246,7 +246,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitTryCatchBlock(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitTryCatchAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -255,7 +255,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
return super.visitTryCatchAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
|
||||
public void visitLocalVariable(String var1, String var2, String var3, Label var4, Label var5, int var6)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -264,7 +264,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitLocalVariable(var1, var2, var3, var4, var5, var6);
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitLocalVariableAnnotation(int var1, TypePath var2, Label[] var3, Label[] var4, int[] var5, String var6, boolean var7)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -273,7 +273,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
return super.visitLocalVariableAnnotation(var1, var2, var3, var4, var5, var6, var7);
|
||||
}
|
||||
|
||||
|
||||
public void visitLineNumber(int var1, Label var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -282,7 +282,7 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitLineNumber(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
public void visitMaxs(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -291,5 +291,5 @@ public class MethodReflector extends MethodVisitor
|
||||
}
|
||||
super.visitMaxs(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.util.RefUtils;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
@@ -33,51 +34,49 @@ import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Slf4j
|
||||
public class OverwriteSanityCheck extends SanityChecker implements Opcodes
|
||||
{
|
||||
|
||||
|
||||
private String className;
|
||||
private ClassNode patchNode;
|
||||
public static final ArrayList<String> methodsUsed = new ArrayList<>();
|
||||
|
||||
|
||||
public OverwriteSanityCheck(ClassVisitor classVisitor, ClassNode node)
|
||||
{
|
||||
super(ASM6, classVisitor);
|
||||
this.className = node.name;
|
||||
this.patchNode = node;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
String check = String.format("%s %s %s %s", className, name,
|
||||
descriptor, access);
|
||||
|
||||
descriptor, access);
|
||||
|
||||
MethodNode methodNode = null;
|
||||
for (Object obj2 : patchNode.methods)
|
||||
{
|
||||
MethodNode classMethod = (MethodNode) obj2;
|
||||
if (classMethod.access == access && classMethod.name.equals(name) &&
|
||||
classMethod.desc.equals(descriptor))
|
||||
classMethod.desc.equals(descriptor))
|
||||
{
|
||||
methodNode = classMethod;
|
||||
}
|
||||
}
|
||||
|
||||
if(methodNode == null)
|
||||
|
||||
if (methodNode == null)
|
||||
{
|
||||
log.error("[OverwriteSanity] Failed to find original patch method for {}", check);
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
|
||||
if (!RefUtils.checkAnnotation(methodNode, "Overwrite"))
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
|
||||
if (!methodsUsed.contains(check))
|
||||
{
|
||||
throw new RuntimeException("[OverwriteSanity] Overwrite target not found: " + check);
|
||||
|
||||
@@ -37,11 +37,11 @@ import org.objectweb.asm.tree.MethodNode;
|
||||
@Slf4j
|
||||
public class OverwriteTransformer extends ClassVisitor
|
||||
{
|
||||
|
||||
|
||||
private final byte[] patch;
|
||||
private ClassNode node;
|
||||
private String className;
|
||||
|
||||
|
||||
public OverwriteTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
@@ -49,14 +49,14 @@ public class OverwriteTransformer extends ClassVisitor
|
||||
this.node = node;
|
||||
this.className = node.name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
@@ -64,34 +64,34 @@ public class OverwriteTransformer extends ClassVisitor
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
|
||||
if (name.startsWith("prepend$") || name.startsWith("append$"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
|
||||
|
||||
for (Object obj : patchNode.methods)
|
||||
{
|
||||
MethodNode patchMethod = (MethodNode) obj;
|
||||
|
||||
|
||||
if (patchMethod.access == access && patchMethod.name.equals(name) && patchMethod.desc.equals(descriptor))
|
||||
{
|
||||
if (RefUtils.checkAnnotation(patchMethod, "Overwrite"))
|
||||
{
|
||||
MethodVisitor mv =
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
mv.visitCode();
|
||||
patchMethod.accept(new MethodReflector(mv));
|
||||
mv.visitEnd();
|
||||
String s = String.format("%s %s %s %s", className, patchMethod.name,
|
||||
patchMethod.desc, patchMethod.access);
|
||||
patchMethod.desc, patchMethod.access);
|
||||
OverwriteSanityCheck.methodsUsed.add(s);
|
||||
return mv;
|
||||
}
|
||||
|
||||
@@ -37,25 +37,25 @@ import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class PrependTransformer extends ClassVisitor
|
||||
{
|
||||
|
||||
|
||||
private final byte[] patch;
|
||||
private String className;
|
||||
private ClassNode classNode;
|
||||
|
||||
|
||||
public PrependTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.classNode = node;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
@@ -70,47 +70,47 @@ public class PrependTransformer extends ClassVisitor
|
||||
{
|
||||
MethodNode patchMethod = (MethodNode) obj;
|
||||
if ((patchMethod.access == access && patchMethod.name.equals("prepend$" + name) &&
|
||||
patchMethod.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(patchMethod, "Prepend"))
|
||||
patchMethod.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(patchMethod, "Prepend"))
|
||||
{
|
||||
MethodVisitor mv =
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
mv.visitCode();
|
||||
|
||||
|
||||
AbstractInsnNode node = patchMethod.instructions.getLast();
|
||||
while (!(node instanceof InsnNode))
|
||||
{
|
||||
node = node.getPrevious();
|
||||
}
|
||||
|
||||
|
||||
if (RefUtils.isReturn(node.getOpcode()))
|
||||
{
|
||||
patchMethod.instructions.remove(node);
|
||||
}
|
||||
|
||||
|
||||
patchMethod.accept(new MethodReflector(mv));
|
||||
|
||||
|
||||
for (Object obj2 : classNode.methods)
|
||||
{
|
||||
MethodNode classMethod = (MethodNode) obj2;
|
||||
if (classMethod.access == access && classMethod.name.equals(name) &&
|
||||
classMethod.desc.equals(descriptor))
|
||||
classMethod.desc.equals(descriptor))
|
||||
{
|
||||
classMethod.accept(new MethodReflector(mv));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mv.visitEnd();
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
@@ -121,5 +121,5 @@ public class PrependTransformer extends ClassVisitor
|
||||
}
|
||||
super.visitEnd();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
public class ProtectTransformer extends Remapper
|
||||
{
|
||||
|
||||
|
||||
public String mapFieldName(String owner, String name, String descriptor)
|
||||
{
|
||||
if (name.startsWith("1protect$"))
|
||||
@@ -38,7 +38,7 @@ public class ProtectTransformer extends Remapper
|
||||
}
|
||||
return super.mapFieldName(owner, name, descriptor);
|
||||
}
|
||||
|
||||
|
||||
public String mapMethodName(String owner, String name, String descriptor)
|
||||
{
|
||||
if (name.startsWith("1protect$"))
|
||||
@@ -47,5 +47,5 @@ public class ProtectTransformer extends Remapper
|
||||
}
|
||||
return super.mapMethodName(owner, name, descriptor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -34,5 +34,5 @@ public abstract class SanityChecker extends ClassVisitor implements Opcodes
|
||||
{
|
||||
super(i, classVisitor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.JPanel;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
|
||||
final class ClientPanel extends JPanel
|
||||
{
|
||||
public ClientPanel(@Nullable Applet client)
|
||||
{
|
||||
setSize(Constants.GAME_FIXED_SIZE);
|
||||
setMinimumSize(Constants.GAME_FIXED_SIZE);
|
||||
setPreferredSize(Constants.GAME_FIXED_SIZE);
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(Color.black);
|
||||
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.setLayout(null);
|
||||
client.setSize(Constants.GAME_FIXED_SIZE);
|
||||
|
||||
client.init();
|
||||
client.start();
|
||||
|
||||
add(client, BorderLayout.CENTER);
|
||||
|
||||
// This causes the whole game frame to be redrawn each frame instead
|
||||
// of only the viewport, so we can hook to MainBufferProvider#draw
|
||||
// and draw anywhere without it leaving artifacts
|
||||
if (client instanceof Client)
|
||||
{
|
||||
((Client)client).setGameDrawingMode(2);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.JPanel;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
|
||||
final class ClientPanel extends JPanel
|
||||
{
|
||||
public ClientPanel(@Nullable Applet client)
|
||||
{
|
||||
setSize(Constants.GAME_FIXED_SIZE);
|
||||
setMinimumSize(Constants.GAME_FIXED_SIZE);
|
||||
setPreferredSize(Constants.GAME_FIXED_SIZE);
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(Color.black);
|
||||
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.setLayout(null);
|
||||
client.setSize(Constants.GAME_FIXED_SIZE);
|
||||
|
||||
client.init();
|
||||
client.start();
|
||||
|
||||
add(client, BorderLayout.CENTER);
|
||||
|
||||
// This causes the whole game frame to be redrawn each frame instead
|
||||
// of only the viewport, so we can hook to MainBufferProvider#draw
|
||||
// and draw anywhere without it leaving artifacts
|
||||
if (client instanceof Client)
|
||||
{
|
||||
((Client) client).setGameDrawingMode(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,8 +174,8 @@ public class ClientUI
|
||||
{
|
||||
if (!event.getGroup().equals(CONFIG_GROUP)
|
||||
&& !(event.getGroup().equals(PLUS_CONFIG_GROUP)
|
||||
&& event.getKey().equals(CONFIG_OPACITY) ||
|
||||
event.getKey().equals(CONFIG_OPACITY_AMOUNT)) ||
|
||||
&& event.getKey().equals(CONFIG_OPACITY) ||
|
||||
event.getKey().equals(CONFIG_OPACITY_AMOUNT)) ||
|
||||
event.getKey().equals(CONFIG_CLIENT_MAXIMIZED) ||
|
||||
event.getKey().equals(CONFIG_CLIENT_BOUNDS))
|
||||
{
|
||||
@@ -278,7 +278,7 @@ public class ClientUI
|
||||
return;
|
||||
}
|
||||
|
||||
final Client client = (Client)this.client;
|
||||
final Client client = (Client) this.client;
|
||||
final ClientThread clientThread = clientThreadProvider.get();
|
||||
|
||||
// Keep scheduling event until we get our name
|
||||
@@ -615,8 +615,9 @@ public class ClientUI
|
||||
/**
|
||||
* Changes cursor for client window. Requires ${@link ClientUI#open(RuneLite)} to be called first.
|
||||
* FIXME: This is working properly only on Windows, Linux and Mac are displaying cursor incorrectly
|
||||
*
|
||||
* @param image cursor image
|
||||
* @param name cursor name
|
||||
* @param name cursor name
|
||||
*/
|
||||
public void setCursor(final BufferedImage image, final String name)
|
||||
{
|
||||
@@ -632,6 +633,7 @@ public class ClientUI
|
||||
|
||||
/**
|
||||
* Resets client window cursor to default one.
|
||||
*
|
||||
* @see ClientUI#setCursor(BufferedImage, String)
|
||||
*/
|
||||
public void resetCursor()
|
||||
@@ -666,6 +668,7 @@ public class ClientUI
|
||||
|
||||
/**
|
||||
* Paint UI related overlays to target graphics
|
||||
*
|
||||
* @param graphics target graphics
|
||||
*/
|
||||
public void paintOverlays(final Graphics2D graphics)
|
||||
@@ -845,7 +848,7 @@ public class ClientUI
|
||||
|
||||
if (config.usernameInTitle() && (client instanceof Client))
|
||||
{
|
||||
final Player player = ((Client)client).getLocalPlayer();
|
||||
final Player player = ((Client) client).getLocalPlayer();
|
||||
|
||||
if (player != null && player.getName() != null)
|
||||
{
|
||||
|
||||
@@ -1,200 +1,202 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.Rectangle;
|
||||
import javax.swing.JFrame;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.config.ExpandResizeType;
|
||||
|
||||
public class ContainableFrame extends JFrame
|
||||
{
|
||||
private static final int SCREEN_EDGE_CLOSE_DISTANCE = 40;
|
||||
|
||||
@Setter
|
||||
private ExpandResizeType expandResizeType;
|
||||
private boolean containedInScreen;
|
||||
private boolean expandedClientOppositeDirection;
|
||||
|
||||
public void setContainedInScreen(boolean value)
|
||||
{
|
||||
this.containedInScreen = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// Reposition the frame if it is intersecting with the bounds
|
||||
this.setLocation(this.getX(), this.getY());
|
||||
this.setBounds(this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(int x, int y)
|
||||
{
|
||||
if (containedInScreen)
|
||||
{
|
||||
Rectangle bounds = this.getGraphicsConfiguration().getBounds();
|
||||
x = Math.max(x, (int)bounds.getX());
|
||||
x = Math.min(x, (int)(bounds.getX() + bounds.getWidth() - this.getWidth()));
|
||||
y = Math.max(y, (int)bounds.getY());
|
||||
y = Math.min(y, (int)(bounds.getY() + bounds.getHeight() - this.getHeight()));
|
||||
}
|
||||
|
||||
super.setLocation(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int x, int y, int width, int height)
|
||||
{
|
||||
if (containedInScreen)
|
||||
{
|
||||
Rectangle bounds = this.getGraphicsConfiguration().getBounds();
|
||||
width = Math.min(width, width - (int)bounds.getX() + x);
|
||||
x = Math.max(x, (int)bounds.getX());
|
||||
height = Math.min(height, height - (int)bounds.getY() + y);
|
||||
y = Math.max(y, (int)bounds.getY());
|
||||
width = Math.min(width, (int)(bounds.getX() + bounds.getWidth()) - x);
|
||||
height = Math.min(height, (int)(bounds.getY() + bounds.getHeight()) - y);
|
||||
}
|
||||
|
||||
super.setBounds(x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand frame by specified value. If the frame is going to be expanded outside of screen push the frame to
|
||||
* the side.
|
||||
* @param value size to expand frame by
|
||||
*/
|
||||
public void expandBy(final int value)
|
||||
{
|
||||
if (isFullScreen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int increment = value;
|
||||
boolean forcedWidthIncrease = false;
|
||||
|
||||
if (expandResizeType == ExpandResizeType.KEEP_WINDOW_SIZE)
|
||||
{
|
||||
final int minimumWidth = getLayout().minimumLayoutSize(this).width;
|
||||
final int currentWidth = getWidth();
|
||||
|
||||
if (minimumWidth > currentWidth)
|
||||
{
|
||||
forcedWidthIncrease = true;
|
||||
increment = minimumWidth - currentWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (forcedWidthIncrease || expandResizeType == ExpandResizeType.KEEP_GAME_SIZE)
|
||||
{
|
||||
final int newWindowWidth = getWidth() + increment;
|
||||
final Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
final boolean wouldExpandThroughEdge = getX() + newWindowWidth > screenBounds.getX() + screenBounds.getWidth();
|
||||
int newWindowX = getX();
|
||||
|
||||
if (wouldExpandThroughEdge)
|
||||
{
|
||||
if (!isFrameCloseToRightEdge() || isFrameCloseToLeftEdge())
|
||||
{
|
||||
// Move the window to the edge
|
||||
newWindowX = (int)(screenBounds.getX() + screenBounds.getWidth()) - getWidth();
|
||||
}
|
||||
|
||||
// Expand the window to the left as the user probably don't want the
|
||||
// window to go through the screen
|
||||
newWindowX -= increment;
|
||||
|
||||
expandedClientOppositeDirection = true;
|
||||
}
|
||||
|
||||
setBounds(newWindowX, getY(), newWindowWidth, getHeight());
|
||||
}
|
||||
|
||||
revalidateMinimumSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Contract frame by specified value. If new frame size is less than it's minimum size, force the minimum size.
|
||||
* If the frame was pushed from side before, restore it's original position.
|
||||
* @param value value to contract frame by
|
||||
*/
|
||||
public void contractBy(final int value)
|
||||
{
|
||||
if (isFullScreen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
revalidateMinimumSize();
|
||||
final Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
final boolean wasCloseToLeftEdge = Math.abs(getX() - screenBounds.getX()) <= SCREEN_EDGE_CLOSE_DISTANCE;
|
||||
int newWindowX = getX();
|
||||
int newWindowWidth = getWidth() - value;
|
||||
|
||||
if (isFrameCloseToRightEdge() && (expandedClientOppositeDirection || !wasCloseToLeftEdge))
|
||||
{
|
||||
// Keep the distance to the right edge
|
||||
newWindowX += value;
|
||||
}
|
||||
|
||||
if (expandResizeType == ExpandResizeType.KEEP_WINDOW_SIZE && newWindowWidth > getMinimumSize().width)
|
||||
{
|
||||
// The sidebar fits inside the window, do not resize and move
|
||||
newWindowWidth = getWidth();
|
||||
newWindowX = getX();
|
||||
}
|
||||
|
||||
setBounds(newWindowX, getY(), newWindowWidth, getHeight());
|
||||
expandedClientOppositeDirection = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force minimum size of frame to be it's layout manager's minimum size
|
||||
*/
|
||||
public void revalidateMinimumSize()
|
||||
{
|
||||
setMinimumSize(getLayout().minimumLayoutSize(this));
|
||||
}
|
||||
|
||||
private boolean isFullScreen()
|
||||
{
|
||||
return (getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH;
|
||||
}
|
||||
|
||||
private boolean isFrameCloseToLeftEdge()
|
||||
{
|
||||
Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
return Math.abs(getX() - screenBounds.getX()) <= SCREEN_EDGE_CLOSE_DISTANCE;
|
||||
}
|
||||
|
||||
private boolean isFrameCloseToRightEdge()
|
||||
{
|
||||
Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
return Math.abs((getX() + getWidth()) - (screenBounds.getX() + screenBounds.getWidth())) <= SCREEN_EDGE_CLOSE_DISTANCE;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.Rectangle;
|
||||
import javax.swing.JFrame;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.config.ExpandResizeType;
|
||||
|
||||
public class ContainableFrame extends JFrame
|
||||
{
|
||||
private static final int SCREEN_EDGE_CLOSE_DISTANCE = 40;
|
||||
|
||||
@Setter
|
||||
private ExpandResizeType expandResizeType;
|
||||
private boolean containedInScreen;
|
||||
private boolean expandedClientOppositeDirection;
|
||||
|
||||
public void setContainedInScreen(boolean value)
|
||||
{
|
||||
this.containedInScreen = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// Reposition the frame if it is intersecting with the bounds
|
||||
this.setLocation(this.getX(), this.getY());
|
||||
this.setBounds(this.getX(), this.getY(), this.getWidth(), this.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(int x, int y)
|
||||
{
|
||||
if (containedInScreen)
|
||||
{
|
||||
Rectangle bounds = this.getGraphicsConfiguration().getBounds();
|
||||
x = Math.max(x, (int) bounds.getX());
|
||||
x = Math.min(x, (int) (bounds.getX() + bounds.getWidth() - this.getWidth()));
|
||||
y = Math.max(y, (int) bounds.getY());
|
||||
y = Math.min(y, (int) (bounds.getY() + bounds.getHeight() - this.getHeight()));
|
||||
}
|
||||
|
||||
super.setLocation(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int x, int y, int width, int height)
|
||||
{
|
||||
if (containedInScreen)
|
||||
{
|
||||
Rectangle bounds = this.getGraphicsConfiguration().getBounds();
|
||||
width = Math.min(width, width - (int) bounds.getX() + x);
|
||||
x = Math.max(x, (int) bounds.getX());
|
||||
height = Math.min(height, height - (int) bounds.getY() + y);
|
||||
y = Math.max(y, (int) bounds.getY());
|
||||
width = Math.min(width, (int) (bounds.getX() + bounds.getWidth()) - x);
|
||||
height = Math.min(height, (int) (bounds.getY() + bounds.getHeight()) - y);
|
||||
}
|
||||
|
||||
super.setBounds(x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand frame by specified value. If the frame is going to be expanded outside of screen push the frame to
|
||||
* the side.
|
||||
*
|
||||
* @param value size to expand frame by
|
||||
*/
|
||||
public void expandBy(final int value)
|
||||
{
|
||||
if (isFullScreen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int increment = value;
|
||||
boolean forcedWidthIncrease = false;
|
||||
|
||||
if (expandResizeType == ExpandResizeType.KEEP_WINDOW_SIZE)
|
||||
{
|
||||
final int minimumWidth = getLayout().minimumLayoutSize(this).width;
|
||||
final int currentWidth = getWidth();
|
||||
|
||||
if (minimumWidth > currentWidth)
|
||||
{
|
||||
forcedWidthIncrease = true;
|
||||
increment = minimumWidth - currentWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (forcedWidthIncrease || expandResizeType == ExpandResizeType.KEEP_GAME_SIZE)
|
||||
{
|
||||
final int newWindowWidth = getWidth() + increment;
|
||||
final Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
final boolean wouldExpandThroughEdge = getX() + newWindowWidth > screenBounds.getX() + screenBounds.getWidth();
|
||||
int newWindowX = getX();
|
||||
|
||||
if (wouldExpandThroughEdge)
|
||||
{
|
||||
if (!isFrameCloseToRightEdge() || isFrameCloseToLeftEdge())
|
||||
{
|
||||
// Move the window to the edge
|
||||
newWindowX = (int) (screenBounds.getX() + screenBounds.getWidth()) - getWidth();
|
||||
}
|
||||
|
||||
// Expand the window to the left as the user probably don't want the
|
||||
// window to go through the screen
|
||||
newWindowX -= increment;
|
||||
|
||||
expandedClientOppositeDirection = true;
|
||||
}
|
||||
|
||||
setBounds(newWindowX, getY(), newWindowWidth, getHeight());
|
||||
}
|
||||
|
||||
revalidateMinimumSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Contract frame by specified value. If new frame size is less than it's minimum size, force the minimum size.
|
||||
* If the frame was pushed from side before, restore it's original position.
|
||||
*
|
||||
* @param value value to contract frame by
|
||||
*/
|
||||
public void contractBy(final int value)
|
||||
{
|
||||
if (isFullScreen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
revalidateMinimumSize();
|
||||
final Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
final boolean wasCloseToLeftEdge = Math.abs(getX() - screenBounds.getX()) <= SCREEN_EDGE_CLOSE_DISTANCE;
|
||||
int newWindowX = getX();
|
||||
int newWindowWidth = getWidth() - value;
|
||||
|
||||
if (isFrameCloseToRightEdge() && (expandedClientOppositeDirection || !wasCloseToLeftEdge))
|
||||
{
|
||||
// Keep the distance to the right edge
|
||||
newWindowX += value;
|
||||
}
|
||||
|
||||
if (expandResizeType == ExpandResizeType.KEEP_WINDOW_SIZE && newWindowWidth > getMinimumSize().width)
|
||||
{
|
||||
// The sidebar fits inside the window, do not resize and move
|
||||
newWindowWidth = getWidth();
|
||||
newWindowX = getX();
|
||||
}
|
||||
|
||||
setBounds(newWindowX, getY(), newWindowWidth, getHeight());
|
||||
expandedClientOppositeDirection = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force minimum size of frame to be it's layout manager's minimum size
|
||||
*/
|
||||
public void revalidateMinimumSize()
|
||||
{
|
||||
setMinimumSize(getLayout().minimumLayoutSize(this));
|
||||
}
|
||||
|
||||
private boolean isFullScreen()
|
||||
{
|
||||
return (getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH;
|
||||
}
|
||||
|
||||
private boolean isFrameCloseToLeftEdge()
|
||||
{
|
||||
Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
return Math.abs(getX() - screenBounds.getX()) <= SCREEN_EDGE_CLOSE_DISTANCE;
|
||||
}
|
||||
|
||||
private boolean isFrameCloseToRightEdge()
|
||||
{
|
||||
Rectangle screenBounds = getGraphicsConfiguration().getBounds();
|
||||
return Math.abs((getX() + getWidth()) - (screenBounds.getX() + screenBounds.getWidth())) <= SCREEN_EDGE_CLOSE_DISTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,215 +1,216 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Insets;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Grid layout implementation with support for cells with unequal size.
|
||||
*
|
||||
* See https://www.javaworld.com/article/2077486/core-java/java-tip-121--flex-your-grid-layout.html
|
||||
*/
|
||||
public class DynamicGridLayout extends GridLayout
|
||||
{
|
||||
public DynamicGridLayout()
|
||||
{
|
||||
this(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
public DynamicGridLayout(int rows, int cols)
|
||||
{
|
||||
this(rows, cols, 0, 0);
|
||||
}
|
||||
|
||||
public DynamicGridLayout(int rows, int cols, int hgap, int vgap)
|
||||
{
|
||||
super(rows, cols, hgap, vgap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container parent)
|
||||
{
|
||||
synchronized (parent.getTreeLock())
|
||||
{
|
||||
return calculateSize(parent, Component::getPreferredSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize(Container parent)
|
||||
{
|
||||
synchronized (parent.getTreeLock())
|
||||
{
|
||||
return calculateSize(parent, Component::getMinimumSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container parent)
|
||||
{
|
||||
synchronized (parent.getTreeLock())
|
||||
{
|
||||
final Insets insets = parent.getInsets();
|
||||
final int ncomponents = parent.getComponentCount();
|
||||
int nrows = getRows();
|
||||
int ncols = getColumns();
|
||||
|
||||
if (ncomponents == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (nrows > 0)
|
||||
{
|
||||
ncols = (ncomponents + nrows - 1) / nrows;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrows = (ncomponents + ncols - 1) / ncols;
|
||||
}
|
||||
|
||||
final int hgap = getHgap();
|
||||
final int vgap = getVgap();
|
||||
|
||||
// scaling factors
|
||||
final Dimension pd = preferredLayoutSize(parent);
|
||||
final double sw = (1.0 * parent.getWidth()) / pd.width;
|
||||
final double sh = (1.0 * parent.getHeight()) / pd.height;
|
||||
|
||||
final int[] w = new int[ncols];
|
||||
final int[] h = new int[nrows];
|
||||
|
||||
// calculate dimensions for all components + apply scaling
|
||||
for (int i = 0; i < ncomponents; i++)
|
||||
{
|
||||
final int r = i / ncols;
|
||||
final int c = i % ncols;
|
||||
final Component comp = parent.getComponent(i);
|
||||
final Dimension d = comp.getPreferredSize();
|
||||
d.width = (int) (sw * d.width);
|
||||
d.height = (int) (sh * d.height);
|
||||
|
||||
if (w[c] < d.width)
|
||||
{
|
||||
w[c] = d.width;
|
||||
}
|
||||
|
||||
if (h[r] < d.height)
|
||||
{
|
||||
h[r] = d.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply new bounds to all child components
|
||||
for (int c = 0, x = insets.left; c < ncols; c++)
|
||||
{
|
||||
for (int r = 0, y = insets.top; r < nrows; r++)
|
||||
{
|
||||
int i = r * ncols + c;
|
||||
|
||||
if (i < ncomponents)
|
||||
{
|
||||
parent.getComponent(i).setBounds(x, y, w[c], h[r]);
|
||||
}
|
||||
|
||||
y += h[r] + vgap;
|
||||
}
|
||||
|
||||
x += w[c] + hgap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate outer size of the layout based on it's children and sizer
|
||||
* @param parent parent component
|
||||
* @param sizer functioning returning dimension of the child component
|
||||
* @return outer size
|
||||
*/
|
||||
private Dimension calculateSize(final Container parent, final Function<Component, Dimension> sizer)
|
||||
{
|
||||
final int ncomponents = parent.getComponentCount();
|
||||
int nrows = getRows();
|
||||
int ncols = getColumns();
|
||||
|
||||
if (nrows > 0)
|
||||
{
|
||||
ncols = (ncomponents + nrows - 1) / nrows;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrows = (ncomponents + ncols - 1) / ncols;
|
||||
}
|
||||
|
||||
final int[] w = new int[ncols];
|
||||
final int[] h = new int[nrows];
|
||||
|
||||
// Calculate dimensions for all components
|
||||
for (int i = 0; i < ncomponents; i++)
|
||||
{
|
||||
final int r = i / ncols;
|
||||
final int c = i % ncols;
|
||||
final Component comp = parent.getComponent(i);
|
||||
final Dimension d = sizer.apply(comp);
|
||||
|
||||
if (w[c] < d.width)
|
||||
{
|
||||
w[c] = d.width;
|
||||
}
|
||||
|
||||
if (h[r] < d.height)
|
||||
{
|
||||
h[r] = d.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total width and height of the layout
|
||||
int nw = 0;
|
||||
|
||||
for (int j = 0; j < ncols; j++)
|
||||
{
|
||||
nw += w[j];
|
||||
}
|
||||
|
||||
int nh = 0;
|
||||
|
||||
for (int i = 0; i < nrows; i++)
|
||||
{
|
||||
nh += h[i];
|
||||
}
|
||||
|
||||
final Insets insets = parent.getInsets();
|
||||
|
||||
// Apply insets and horizontal and vertical gap to layout
|
||||
return new Dimension(
|
||||
insets.left + insets.right + nw + (ncols - 1) * getHgap(),
|
||||
insets.top + insets.bottom + nh + (nrows - 1) * getVgap());
|
||||
}
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Insets;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Grid layout implementation with support for cells with unequal size.
|
||||
* <p>
|
||||
* See https://www.javaworld.com/article/2077486/core-java/java-tip-121--flex-your-grid-layout.html
|
||||
*/
|
||||
public class DynamicGridLayout extends GridLayout
|
||||
{
|
||||
public DynamicGridLayout()
|
||||
{
|
||||
this(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
public DynamicGridLayout(int rows, int cols)
|
||||
{
|
||||
this(rows, cols, 0, 0);
|
||||
}
|
||||
|
||||
public DynamicGridLayout(int rows, int cols, int hgap, int vgap)
|
||||
{
|
||||
super(rows, cols, hgap, vgap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container parent)
|
||||
{
|
||||
synchronized (parent.getTreeLock())
|
||||
{
|
||||
return calculateSize(parent, Component::getPreferredSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize(Container parent)
|
||||
{
|
||||
synchronized (parent.getTreeLock())
|
||||
{
|
||||
return calculateSize(parent, Component::getMinimumSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container parent)
|
||||
{
|
||||
synchronized (parent.getTreeLock())
|
||||
{
|
||||
final Insets insets = parent.getInsets();
|
||||
final int ncomponents = parent.getComponentCount();
|
||||
int nrows = getRows();
|
||||
int ncols = getColumns();
|
||||
|
||||
if (ncomponents == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (nrows > 0)
|
||||
{
|
||||
ncols = (ncomponents + nrows - 1) / nrows;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrows = (ncomponents + ncols - 1) / ncols;
|
||||
}
|
||||
|
||||
final int hgap = getHgap();
|
||||
final int vgap = getVgap();
|
||||
|
||||
// scaling factors
|
||||
final Dimension pd = preferredLayoutSize(parent);
|
||||
final double sw = (1.0 * parent.getWidth()) / pd.width;
|
||||
final double sh = (1.0 * parent.getHeight()) / pd.height;
|
||||
|
||||
final int[] w = new int[ncols];
|
||||
final int[] h = new int[nrows];
|
||||
|
||||
// calculate dimensions for all components + apply scaling
|
||||
for (int i = 0; i < ncomponents; i++)
|
||||
{
|
||||
final int r = i / ncols;
|
||||
final int c = i % ncols;
|
||||
final Component comp = parent.getComponent(i);
|
||||
final Dimension d = comp.getPreferredSize();
|
||||
d.width = (int) (sw * d.width);
|
||||
d.height = (int) (sh * d.height);
|
||||
|
||||
if (w[c] < d.width)
|
||||
{
|
||||
w[c] = d.width;
|
||||
}
|
||||
|
||||
if (h[r] < d.height)
|
||||
{
|
||||
h[r] = d.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply new bounds to all child components
|
||||
for (int c = 0, x = insets.left; c < ncols; c++)
|
||||
{
|
||||
for (int r = 0, y = insets.top; r < nrows; r++)
|
||||
{
|
||||
int i = r * ncols + c;
|
||||
|
||||
if (i < ncomponents)
|
||||
{
|
||||
parent.getComponent(i).setBounds(x, y, w[c], h[r]);
|
||||
}
|
||||
|
||||
y += h[r] + vgap;
|
||||
}
|
||||
|
||||
x += w[c] + hgap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate outer size of the layout based on it's children and sizer
|
||||
*
|
||||
* @param parent parent component
|
||||
* @param sizer functioning returning dimension of the child component
|
||||
* @return outer size
|
||||
*/
|
||||
private Dimension calculateSize(final Container parent, final Function<Component, Dimension> sizer)
|
||||
{
|
||||
final int ncomponents = parent.getComponentCount();
|
||||
int nrows = getRows();
|
||||
int ncols = getColumns();
|
||||
|
||||
if (nrows > 0)
|
||||
{
|
||||
ncols = (ncomponents + nrows - 1) / nrows;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrows = (ncomponents + ncols - 1) / ncols;
|
||||
}
|
||||
|
||||
final int[] w = new int[ncols];
|
||||
final int[] h = new int[nrows];
|
||||
|
||||
// Calculate dimensions for all components
|
||||
for (int i = 0; i < ncomponents; i++)
|
||||
{
|
||||
final int r = i / ncols;
|
||||
final int c = i % ncols;
|
||||
final Component comp = parent.getComponent(i);
|
||||
final Dimension d = sizer.apply(comp);
|
||||
|
||||
if (w[c] < d.width)
|
||||
{
|
||||
w[c] = d.width;
|
||||
}
|
||||
|
||||
if (h[r] < d.height)
|
||||
{
|
||||
h[r] = d.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total width and height of the layout
|
||||
int nw = 0;
|
||||
|
||||
for (int j = 0; j < ncols; j++)
|
||||
{
|
||||
nw += w[j];
|
||||
}
|
||||
|
||||
int nh = 0;
|
||||
|
||||
for (int i = 0; i < nrows; i++)
|
||||
{
|
||||
nh += h[i];
|
||||
}
|
||||
|
||||
final Insets insets = parent.getInsets();
|
||||
|
||||
// Apply insets and horizontal and vertical gap to layout
|
||||
return new Dimension(
|
||||
insets.left + insets.right + nw + (ncols - 1) * getHgap(),
|
||||
insets.top + insets.bottom + nh + (nrows - 1) * getVgap());
|
||||
}
|
||||
}
|
||||
@@ -1,96 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Tyler <https://github.com/tylerthardy>
|
||||
* 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.ui;
|
||||
|
||||
import javax.swing.text.StyleContext;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FontManager
|
||||
{
|
||||
private static final Font runescapeFont;
|
||||
private static final Font runescapeSmallFont;
|
||||
private static final Font runescapeBoldFont;
|
||||
|
||||
static
|
||||
{
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
|
||||
try
|
||||
{
|
||||
Font font = Font.createFont(Font.TRUETYPE_FONT,
|
||||
FontManager.class.getResourceAsStream("runescape.ttf"))
|
||||
.deriveFont(Font.PLAIN, 16);
|
||||
ge.registerFont(font);
|
||||
|
||||
runescapeFont = StyleContext.getDefaultStyleContext()
|
||||
.getFont(font.getName(), Font.PLAIN, 16);
|
||||
ge.registerFont(runescapeFont);
|
||||
|
||||
Font smallFont = Font.createFont(Font.TRUETYPE_FONT,
|
||||
FontManager.class.getResourceAsStream("runescape_small.ttf"))
|
||||
.deriveFont(Font.PLAIN, 16);
|
||||
ge.registerFont(smallFont);
|
||||
|
||||
runescapeSmallFont = StyleContext.getDefaultStyleContext()
|
||||
.getFont(smallFont.getName(), Font.PLAIN, 16);
|
||||
ge.registerFont(runescapeSmallFont);
|
||||
|
||||
Font boldFont = Font.createFont(Font.TRUETYPE_FONT,
|
||||
FontManager.class.getResourceAsStream("runescape_bold.ttf"))
|
||||
.deriveFont(Font.PLAIN, 16);
|
||||
ge.registerFont(boldFont);
|
||||
|
||||
runescapeBoldFont = StyleContext.getDefaultStyleContext()
|
||||
.getFont(boldFont.getName(), Font.PLAIN, 16);
|
||||
ge.registerFont(runescapeBoldFont);
|
||||
}
|
||||
catch (FontFormatException ex)
|
||||
{
|
||||
throw new RuntimeException("Font loaded, but format incorrect.", ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException("Font file not found.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Font getRunescapeFont()
|
||||
{
|
||||
return runescapeFont;
|
||||
}
|
||||
|
||||
public static Font getRunescapeSmallFont()
|
||||
{
|
||||
return runescapeSmallFont;
|
||||
}
|
||||
|
||||
public static Font getRunescapeBoldFont()
|
||||
{
|
||||
return runescapeBoldFont;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, Tyler <https://github.com/tylerthardy>
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.io.IOException;
|
||||
import javax.swing.text.StyleContext;
|
||||
|
||||
public class FontManager
|
||||
{
|
||||
private static final Font runescapeFont;
|
||||
private static final Font runescapeSmallFont;
|
||||
private static final Font runescapeBoldFont;
|
||||
|
||||
static
|
||||
{
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
|
||||
try
|
||||
{
|
||||
Font font = Font.createFont(Font.TRUETYPE_FONT,
|
||||
FontManager.class.getResourceAsStream("runescape.ttf"))
|
||||
.deriveFont(Font.PLAIN, 16);
|
||||
ge.registerFont(font);
|
||||
|
||||
runescapeFont = StyleContext.getDefaultStyleContext()
|
||||
.getFont(font.getName(), Font.PLAIN, 16);
|
||||
ge.registerFont(runescapeFont);
|
||||
|
||||
Font smallFont = Font.createFont(Font.TRUETYPE_FONT,
|
||||
FontManager.class.getResourceAsStream("runescape_small.ttf"))
|
||||
.deriveFont(Font.PLAIN, 16);
|
||||
ge.registerFont(smallFont);
|
||||
|
||||
runescapeSmallFont = StyleContext.getDefaultStyleContext()
|
||||
.getFont(smallFont.getName(), Font.PLAIN, 16);
|
||||
ge.registerFont(runescapeSmallFont);
|
||||
|
||||
Font boldFont = Font.createFont(Font.TRUETYPE_FONT,
|
||||
FontManager.class.getResourceAsStream("runescape_bold.ttf"))
|
||||
.deriveFont(Font.PLAIN, 16);
|
||||
ge.registerFont(boldFont);
|
||||
|
||||
runescapeBoldFont = StyleContext.getDefaultStyleContext()
|
||||
.getFont(boldFont.getName(), Font.PLAIN, 16);
|
||||
ge.registerFont(runescapeBoldFont);
|
||||
}
|
||||
catch (FontFormatException ex)
|
||||
{
|
||||
throw new RuntimeException("Font loaded, but format incorrect.", ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException("Font file not found.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Font getRunescapeFont()
|
||||
{
|
||||
return runescapeFont;
|
||||
}
|
||||
|
||||
public static Font getRunescapeSmallFont()
|
||||
{
|
||||
return runescapeSmallFont;
|
||||
}
|
||||
|
||||
public static Font getRunescapeBoldFont()
|
||||
{
|
||||
return runescapeBoldFont;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,243 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Jeremy Plsek <github.com/jplsek>
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import org.pushingpixels.substance.internal.SubstanceSynapse;
|
||||
|
||||
/**
|
||||
* This is a custom Splash Screen and does not use Java's SplashScreen class. This has helper methods to update the
|
||||
* status while loading RuneLite. All public methods run non-blocking passed to the swing thread.
|
||||
*/
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class RuneLiteSplashScreen
|
||||
{
|
||||
private RuneLiteProperties runeLiteProperties = new RuneLiteProperties();
|
||||
|
||||
public JFrame frame;
|
||||
public JPanel panel = new JPanel();
|
||||
public JLabel messageLabel;
|
||||
public JLabel subMessageLabel;
|
||||
public JProgressBar progressBar = new JProgressBar();
|
||||
|
||||
private int currentStep;
|
||||
|
||||
/**
|
||||
* This is not done in the constructor in order to avoid processing in case the user chooses to not load
|
||||
* the splash screen.
|
||||
* @param estimatedSteps steps until completion, used for the progress bar
|
||||
*/
|
||||
private void initLayout(final int estimatedSteps)
|
||||
{
|
||||
SwingUtil.setupRuneLiteLookAndFeel();
|
||||
|
||||
// init fields with updated swing look and feel
|
||||
frame = new JFrame("RuneLitePlus Loading");
|
||||
messageLabel = new JLabel("Loading...");
|
||||
subMessageLabel = new JLabel();
|
||||
progressBar.setUI(new BasicProgressBarUI());
|
||||
progressBar.setMinimum(0);
|
||||
progressBar.setMaximum(estimatedSteps);
|
||||
|
||||
// frame setup
|
||||
frame.setSize(220, 290);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setUndecorated(true);
|
||||
|
||||
// main panel setup
|
||||
// To reduce substance's colorization (tinting)
|
||||
panel.putClientProperty(SubstanceSynapse.COLORIZATION_FACTOR, 1.0);
|
||||
panel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
final GridBagLayout layout = new GridBagLayout();
|
||||
layout.columnWeights = new double[]{1};
|
||||
layout.rowWeights = new double[]{1, 0, 0, 1, 0, 1};
|
||||
panel.setLayout(layout);
|
||||
|
||||
// logo
|
||||
synchronized (ImageIO.class)
|
||||
{
|
||||
try
|
||||
{
|
||||
final BufferedImage logo = ImageIO.read(RuneLiteSplashScreen.class.getResourceAsStream("/runeliteplus.png"));
|
||||
frame.setIconImage(logo);
|
||||
|
||||
final BufferedImage logoTransparent = ImageIO.read(RuneLiteSplashScreen.class.getResourceAsStream("/runeliteplus_transparent.png"));
|
||||
final GridBagConstraints logoConstraints = new GridBagConstraints();
|
||||
logoConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
panel.add(new JLabel(new ImageIcon(logoTransparent.getScaledInstance(96, 96, Image.SCALE_SMOOTH))), logoConstraints);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Error loading logo", e);
|
||||
}
|
||||
}
|
||||
|
||||
// runelite title
|
||||
final JLabel title = new JLabel("RuneLitePlus");
|
||||
final GridBagConstraints titleConstraints = new GridBagConstraints();
|
||||
titleConstraints.gridy = 1;
|
||||
panel.add(title, titleConstraints);
|
||||
|
||||
// version
|
||||
final JLabel version = new JLabel("RuneLite Version : " + runeLiteProperties.getVersion());
|
||||
version.setForeground(Color.GREEN);
|
||||
version.setFont(FontManager.getRunescapeSmallFont());
|
||||
version.setForeground(version.getForeground().darker());
|
||||
final GridBagConstraints versionConstraints = new GridBagConstraints();
|
||||
versionConstraints.gridy = 2;
|
||||
panel.add(version, versionConstraints);
|
||||
|
||||
// version
|
||||
final JLabel litVersion = new JLabel("Plus Version : PRE-" + RuneLite.RUNELIT_VERSION);
|
||||
litVersion.setForeground(Color.GREEN);
|
||||
litVersion.setFont(FontManager.getRunescapeSmallFont());
|
||||
litVersion.setForeground(litVersion.getForeground().darker());
|
||||
final GridBagConstraints litVersionConstraints = new GridBagConstraints();
|
||||
litVersionConstraints.gridy = 3;
|
||||
litVersionConstraints.weightx = 4;
|
||||
panel.add(litVersion, litVersionConstraints);
|
||||
|
||||
|
||||
// progressbar
|
||||
final GridBagConstraints progressConstraints = new GridBagConstraints();
|
||||
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
progressConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
progressConstraints.gridy = 4;
|
||||
panel.add(progressBar, progressConstraints);
|
||||
|
||||
// main message
|
||||
messageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
final GridBagConstraints messageConstraints = new GridBagConstraints();
|
||||
messageConstraints.gridy = 5;
|
||||
panel.add(messageLabel, messageConstraints);
|
||||
|
||||
// alternate message
|
||||
final GridBagConstraints subMessageConstraints = new GridBagConstraints();
|
||||
subMessageLabel.setForeground(subMessageLabel.getForeground().darker());
|
||||
subMessageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
subMessageConstraints.gridy = 6;
|
||||
panel.add(subMessageLabel, subMessageConstraints);
|
||||
|
||||
frame.setContentPane(panel);
|
||||
}
|
||||
|
||||
private boolean notActive()
|
||||
{
|
||||
return frame == null || !frame.isDisplayable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close/dispose of the splash screen
|
||||
*/
|
||||
public void close()
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frame.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the splash screen to be visible.
|
||||
* @param estimatedSteps steps until completion, used for the progress bar
|
||||
*/
|
||||
public void open(final int estimatedSteps)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
initLayout(estimatedSteps);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void setMessage(final String message)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
messageLabel.setText(message);
|
||||
});
|
||||
}
|
||||
|
||||
public void setSubMessage(final String subMessage)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
subMessageLabel.setText(subMessage);
|
||||
});
|
||||
}
|
||||
|
||||
public void setProgress(int currentProgress, int progressGoal)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (progressGoal!=progressBar.getMaximum()) {
|
||||
panel.remove(progressBar);
|
||||
panel.validate();
|
||||
final GridBagConstraints progressConstraints = new GridBagConstraints();
|
||||
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
progressConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
progressConstraints.gridy = 4;
|
||||
panel.add(progressBar, progressConstraints);
|
||||
panel.validate();
|
||||
}
|
||||
progressBar.setMaximum(progressGoal);
|
||||
progressBar.setValue(currentProgress);
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Jeremy Plsek <github.com/jplsek>
|
||||
* 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.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import org.pushingpixels.substance.internal.SubstanceSynapse;
|
||||
|
||||
/**
|
||||
* This is a custom Splash Screen and does not use Java's SplashScreen class. This has helper methods to update the
|
||||
* status while loading RuneLite. All public methods run non-blocking passed to the swing thread.
|
||||
*/
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class RuneLiteSplashScreen
|
||||
{
|
||||
private RuneLiteProperties runeLiteProperties = new RuneLiteProperties();
|
||||
|
||||
public JFrame frame;
|
||||
public JPanel panel = new JPanel();
|
||||
public JLabel messageLabel;
|
||||
public JLabel subMessageLabel;
|
||||
public JProgressBar progressBar = new JProgressBar();
|
||||
|
||||
private int currentStep;
|
||||
|
||||
/**
|
||||
* This is not done in the constructor in order to avoid processing in case the user chooses to not load
|
||||
* the splash screen.
|
||||
*
|
||||
* @param estimatedSteps steps until completion, used for the progress bar
|
||||
*/
|
||||
private void initLayout(final int estimatedSteps)
|
||||
{
|
||||
SwingUtil.setupRuneLiteLookAndFeel();
|
||||
|
||||
// init fields with updated swing look and feel
|
||||
frame = new JFrame("RuneLitePlus Loading");
|
||||
messageLabel = new JLabel("Loading...");
|
||||
subMessageLabel = new JLabel();
|
||||
progressBar.setUI(new BasicProgressBarUI());
|
||||
progressBar.setMinimum(0);
|
||||
progressBar.setMaximum(estimatedSteps);
|
||||
|
||||
// frame setup
|
||||
frame.setSize(220, 290);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setUndecorated(true);
|
||||
|
||||
// main panel setup
|
||||
// To reduce substance's colorization (tinting)
|
||||
panel.putClientProperty(SubstanceSynapse.COLORIZATION_FACTOR, 1.0);
|
||||
panel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
final GridBagLayout layout = new GridBagLayout();
|
||||
layout.columnWeights = new double[]{1};
|
||||
layout.rowWeights = new double[]{1, 0, 0, 1, 0, 1};
|
||||
panel.setLayout(layout);
|
||||
|
||||
// logo
|
||||
synchronized (ImageIO.class)
|
||||
{
|
||||
try
|
||||
{
|
||||
final BufferedImage logo = ImageIO.read(RuneLiteSplashScreen.class.getResourceAsStream("/runeliteplus.png"));
|
||||
frame.setIconImage(logo);
|
||||
|
||||
final BufferedImage logoTransparent = ImageIO.read(RuneLiteSplashScreen.class.getResourceAsStream("/runeliteplus_transparent.png"));
|
||||
final GridBagConstraints logoConstraints = new GridBagConstraints();
|
||||
logoConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
panel.add(new JLabel(new ImageIcon(logoTransparent.getScaledInstance(96, 96, Image.SCALE_SMOOTH))), logoConstraints);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Error loading logo", e);
|
||||
}
|
||||
}
|
||||
|
||||
// runelite title
|
||||
final JLabel title = new JLabel("RuneLitePlus");
|
||||
final GridBagConstraints titleConstraints = new GridBagConstraints();
|
||||
titleConstraints.gridy = 1;
|
||||
panel.add(title, titleConstraints);
|
||||
|
||||
// version
|
||||
final JLabel version = new JLabel("RuneLite Version : " + runeLiteProperties.getVersion());
|
||||
version.setForeground(Color.GREEN);
|
||||
version.setFont(FontManager.getRunescapeSmallFont());
|
||||
version.setForeground(version.getForeground().darker());
|
||||
final GridBagConstraints versionConstraints = new GridBagConstraints();
|
||||
versionConstraints.gridy = 2;
|
||||
panel.add(version, versionConstraints);
|
||||
|
||||
// version
|
||||
final JLabel litVersion = new JLabel("Plus Version : PRE-" + RuneLite.RUNELIT_VERSION);
|
||||
litVersion.setForeground(Color.GREEN);
|
||||
litVersion.setFont(FontManager.getRunescapeSmallFont());
|
||||
litVersion.setForeground(litVersion.getForeground().darker());
|
||||
final GridBagConstraints litVersionConstraints = new GridBagConstraints();
|
||||
litVersionConstraints.gridy = 3;
|
||||
litVersionConstraints.weightx = 4;
|
||||
panel.add(litVersion, litVersionConstraints);
|
||||
|
||||
|
||||
// progressbar
|
||||
final GridBagConstraints progressConstraints = new GridBagConstraints();
|
||||
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
progressConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
progressConstraints.gridy = 4;
|
||||
panel.add(progressBar, progressConstraints);
|
||||
|
||||
// main message
|
||||
messageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
final GridBagConstraints messageConstraints = new GridBagConstraints();
|
||||
messageConstraints.gridy = 5;
|
||||
panel.add(messageLabel, messageConstraints);
|
||||
|
||||
// alternate message
|
||||
final GridBagConstraints subMessageConstraints = new GridBagConstraints();
|
||||
subMessageLabel.setForeground(subMessageLabel.getForeground().darker());
|
||||
subMessageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
subMessageConstraints.gridy = 6;
|
||||
panel.add(subMessageLabel, subMessageConstraints);
|
||||
|
||||
frame.setContentPane(panel);
|
||||
}
|
||||
|
||||
private boolean notActive()
|
||||
{
|
||||
return frame == null || !frame.isDisplayable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close/dispose of the splash screen
|
||||
*/
|
||||
public void close()
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frame.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the splash screen to be visible.
|
||||
*
|
||||
* @param estimatedSteps steps until completion, used for the progress bar
|
||||
*/
|
||||
public void open(final int estimatedSteps)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
initLayout(estimatedSteps);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void setMessage(final String message)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
messageLabel.setText(message);
|
||||
});
|
||||
}
|
||||
|
||||
public void setSubMessage(final String subMessage)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
subMessageLabel.setText(subMessage);
|
||||
});
|
||||
}
|
||||
|
||||
public void setProgress(int currentProgress, int progressGoal)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
if (notActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (progressGoal != progressBar.getMaximum())
|
||||
{
|
||||
panel.remove(progressBar);
|
||||
panel.validate();
|
||||
final GridBagConstraints progressConstraints = new GridBagConstraints();
|
||||
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
progressConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
progressConstraints.gridy = 4;
|
||||
panel.add(progressBar, progressConstraints);
|
||||
panel.validate();
|
||||
}
|
||||
progressBar.setMaximum(progressGoal);
|
||||
progressBar.setValue(currentProgress);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,90 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Levi <me@levischuck.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.ui.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.swing.JPanel;
|
||||
import lombok.Getter;
|
||||
|
||||
public class DimmableJPanel extends JPanel
|
||||
{
|
||||
// Dimming state, allows for restoring original colors before dimming
|
||||
@Getter
|
||||
private boolean dimmed = false;
|
||||
private Color dimmedForeground = null;
|
||||
private Color dimmedBackground = null;
|
||||
private Color undimmedForeground = null;
|
||||
private Color undimmedBackground = null;
|
||||
|
||||
@Override
|
||||
public void setForeground(Color color)
|
||||
{
|
||||
undimmedForeground = color;
|
||||
dimmedForeground = color.darker();
|
||||
super.setForeground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color color)
|
||||
{
|
||||
undimmedBackground = color;
|
||||
dimmedBackground = color.darker();
|
||||
super.setBackground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getForeground()
|
||||
{
|
||||
return dimmed ? dimmedForeground : undimmedForeground;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground()
|
||||
{
|
||||
return dimmed ? dimmedBackground : undimmedBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimming sets all parts of this component with darker colors except for the central label
|
||||
* This is useful for showing that progress is paused
|
||||
* Setting dim to false will restore the original colors from before the component was dimmed.
|
||||
* @param dimmed
|
||||
*/
|
||||
public void setDimmed(boolean dimmed)
|
||||
{
|
||||
this.dimmed = dimmed;
|
||||
|
||||
if (dimmed)
|
||||
{
|
||||
super.setBackground(dimmedBackground);
|
||||
super.setForeground(dimmedForeground);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setBackground(undimmedBackground);
|
||||
super.setForeground(undimmedForeground);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018, Levi <me@levischuck.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.ui.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.swing.JPanel;
|
||||
import lombok.Getter;
|
||||
|
||||
public class DimmableJPanel extends JPanel
|
||||
{
|
||||
// Dimming state, allows for restoring original colors before dimming
|
||||
@Getter
|
||||
private boolean dimmed = false;
|
||||
private Color dimmedForeground = null;
|
||||
private Color dimmedBackground = null;
|
||||
private Color undimmedForeground = null;
|
||||
private Color undimmedBackground = null;
|
||||
|
||||
@Override
|
||||
public void setForeground(Color color)
|
||||
{
|
||||
undimmedForeground = color;
|
||||
dimmedForeground = color.darker();
|
||||
super.setForeground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color color)
|
||||
{
|
||||
undimmedBackground = color;
|
||||
dimmedBackground = color.darker();
|
||||
super.setBackground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getForeground()
|
||||
{
|
||||
return dimmed ? dimmedForeground : undimmedForeground;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground()
|
||||
{
|
||||
return dimmed ? dimmedBackground : undimmedBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dimming sets all parts of this component with darker colors except for the central label
|
||||
* This is useful for showing that progress is paused
|
||||
* Setting dim to false will restore the original colors from before the component was dimmed.
|
||||
*
|
||||
* @param dimmed
|
||||
*/
|
||||
public void setDimmed(boolean dimmed)
|
||||
{
|
||||
this.dimmed = dimmed;
|
||||
|
||||
if (dimmed)
|
||||
{
|
||||
super.setBackground(dimmedBackground);
|
||||
super.setForeground(dimmedForeground);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setBackground(undimmedBackground);
|
||||
super.setForeground(undimmedForeground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +1,95 @@
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 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 HOLDER 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.ui.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JPanel;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* A progress bar to be displayed underneath the GE offer item panels
|
||||
*/
|
||||
public class ThinProgressBar extends JPanel
|
||||
{
|
||||
@Getter
|
||||
private int maximumValue = 1;
|
||||
|
||||
@Getter
|
||||
private int value;
|
||||
|
||||
public ThinProgressBar()
|
||||
{
|
||||
setForeground(Color.GREEN);
|
||||
setMaximumSize(new Dimension(Integer.MAX_VALUE, 4));
|
||||
setMinimumSize(new Dimension(0, 4));
|
||||
setPreferredSize(new Dimension(0, 4));
|
||||
setSize(new Dimension(0, 4));
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
public double getPercentage()
|
||||
{
|
||||
return (value * 100) / maximumValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForeground(Color color)
|
||||
{
|
||||
super.setForeground(color);
|
||||
setBackground(color.darker());
|
||||
}
|
||||
|
||||
public void setMaximumValue(int maximumValue)
|
||||
{
|
||||
if (maximumValue < 1)
|
||||
{
|
||||
maximumValue = 1;
|
||||
}
|
||||
this.maximumValue = maximumValue;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setValue(int value)
|
||||
{
|
||||
this.value = value;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
super.paintComponent(g);
|
||||
int w = getWidth();
|
||||
int h = getHeight();
|
||||
int div = (value * w) / maximumValue;
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(div, 0, w, h);
|
||||
g.setColor(getForeground());
|
||||
g.fillRect(0, 0, div, h);
|
||||
}
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 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 HOLDER 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.ui.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JPanel;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* A progress bar to be displayed underneath the GE offer item panels
|
||||
*/
|
||||
public class ThinProgressBar extends JPanel
|
||||
{
|
||||
@Getter
|
||||
private int maximumValue = 1;
|
||||
|
||||
@Getter
|
||||
private int value;
|
||||
|
||||
public ThinProgressBar()
|
||||
{
|
||||
setForeground(Color.GREEN);
|
||||
setMaximumSize(new Dimension(Integer.MAX_VALUE, 4));
|
||||
setMinimumSize(new Dimension(0, 4));
|
||||
setPreferredSize(new Dimension(0, 4));
|
||||
setSize(new Dimension(0, 4));
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
public double getPercentage()
|
||||
{
|
||||
return (value * 100) / (double) maximumValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForeground(Color color)
|
||||
{
|
||||
super.setForeground(color);
|
||||
setBackground(color.darker());
|
||||
}
|
||||
|
||||
public void setMaximumValue(int maximumValue)
|
||||
{
|
||||
if (maximumValue < 1)
|
||||
{
|
||||
maximumValue = 1;
|
||||
}
|
||||
this.maximumValue = maximumValue;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setValue(int value)
|
||||
{
|
||||
this.value = value;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
super.paintComponent(g);
|
||||
int w = getWidth();
|
||||
int h = getHeight();
|
||||
int div = (value * w) / maximumValue;
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(div, 0, w, h);
|
||||
g.setColor(getForeground());
|
||||
g.fillRect(0, 0, div, h);
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,72 @@
|
||||
/*
|
||||
* 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.ui.overlay;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class Overlay implements LayoutableRenderableEntity
|
||||
{
|
||||
@Nullable
|
||||
private final Plugin plugin;
|
||||
private Point preferredLocation;
|
||||
private Dimension preferredSize;
|
||||
private OverlayPosition preferredPosition;
|
||||
private Rectangle bounds = new Rectangle();
|
||||
private OverlayPosition position = OverlayPosition.TOP_LEFT;
|
||||
private OverlayPriority priority = OverlayPriority.NONE;
|
||||
private OverlayLayer layer = OverlayLayer.UNDER_WIDGETS;
|
||||
private final List<OverlayMenuEntry> menuEntries = new ArrayList<>();
|
||||
|
||||
protected Overlay()
|
||||
{
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
protected Overlay(Plugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlay name, used for saving the overlay, needs to be unique
|
||||
* @return overlay name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class Overlay implements LayoutableRenderableEntity
|
||||
{
|
||||
@Nullable
|
||||
private final Plugin plugin;
|
||||
private Point preferredLocation;
|
||||
private Dimension preferredSize;
|
||||
private OverlayPosition preferredPosition;
|
||||
private Rectangle bounds = new Rectangle();
|
||||
private OverlayPosition position = OverlayPosition.TOP_LEFT;
|
||||
private OverlayPriority priority = OverlayPriority.NONE;
|
||||
private OverlayLayer layer = OverlayLayer.UNDER_WIDGETS;
|
||||
private final List<OverlayMenuEntry> menuEntries = new ArrayList<>();
|
||||
|
||||
protected Overlay()
|
||||
{
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
protected Overlay(Plugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlay name, used for saving the overlay, needs to be unique
|
||||
*
|
||||
* @return overlay name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,385 +1,385 @@
|
||||
/*
|
||||
* 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.ui.overlay;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.OverlayMenuClicked;
|
||||
import net.runelite.client.events.PluginChanged;
|
||||
|
||||
/**
|
||||
* Manages state of all game overlays
|
||||
*/
|
||||
@Singleton
|
||||
public class OverlayManager
|
||||
{
|
||||
public static final String OPTION_CONFIGURE = "Configure";
|
||||
|
||||
private static final String OVERLAY_CONFIG_PREFERRED_LOCATION = "_preferredLocation";
|
||||
private static final String OVERLAY_CONFIG_PREFERRED_POSITION = "_preferredPosition";
|
||||
private static final String OVERLAY_CONFIG_PREFERRED_SIZE = "_preferredSize";
|
||||
private static final String RUNELITE_CONFIG_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value();
|
||||
|
||||
@VisibleForTesting
|
||||
static final Comparator<Overlay> OVERLAY_COMPARATOR = (a, b) ->
|
||||
{
|
||||
final OverlayPosition aPos = a.getPreferredPosition() != null
|
||||
? a.getPreferredPosition()
|
||||
: a.getPosition();
|
||||
|
||||
final OverlayPosition bPos = b.getPreferredPosition() != null
|
||||
? b.getPreferredPosition()
|
||||
: b.getPosition();
|
||||
|
||||
if (aPos != bPos)
|
||||
{
|
||||
// This is so non-dynamic overlays render after dynamic
|
||||
// overlays, which are generally in the scene
|
||||
return aPos.compareTo(bPos);
|
||||
}
|
||||
|
||||
// For dynamic overlays, higher priority means to
|
||||
// draw *later* so it is on top.
|
||||
// For non-dynamic overlays, higher priority means
|
||||
// draw *first* so that they are closer to their
|
||||
// defined position.
|
||||
return aPos == OverlayPosition.DYNAMIC
|
||||
? a.getPriority().compareTo(b.getPriority())
|
||||
: b.getPriority().compareTo(a.getPriority());
|
||||
};
|
||||
|
||||
/**
|
||||
* Insertion-order sorted set of overlays
|
||||
* All access to this must be guarded by a lock on this OverlayManager
|
||||
*/
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<Overlay> overlays = new ArrayList<>();
|
||||
@Getter
|
||||
private final List<WidgetItem> itemWidgets = new ArrayList<>();
|
||||
|
||||
private final Map<OverlayLayer, List<Overlay>> overlayLayers = new EnumMap<>(OverlayLayer.class);
|
||||
|
||||
private final ConfigManager configManager;
|
||||
private final EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
private OverlayManager(final ConfigManager configManager, final EventBus eventBus)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPluginChanged(final PluginChanged event)
|
||||
{
|
||||
overlays.forEach(this::loadOverlay);
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE_OVERLAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.consume();
|
||||
|
||||
Optional<Overlay> optionalOverlay = overlays.stream().filter(o -> overlays.indexOf(o) == event.getId()).findAny();
|
||||
if (optionalOverlay.isPresent())
|
||||
{
|
||||
Overlay overlay = optionalOverlay.get();
|
||||
List<OverlayMenuEntry> menuEntries = overlay.getMenuEntries();
|
||||
Optional<OverlayMenuEntry> optionalOverlayMenuEntry = menuEntries.stream()
|
||||
.filter(me -> me.getOption().equals(event.getMenuOption()))
|
||||
.findAny();
|
||||
if (optionalOverlayMenuEntry.isPresent())
|
||||
{
|
||||
eventBus.post(new OverlayMenuClicked(optionalOverlayMenuEntry.get(), overlay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the overlays on a layer sorted by priority and position
|
||||
*
|
||||
* @param layer the layer
|
||||
* @return An immutable list of all of the overlays on that layer
|
||||
*/
|
||||
synchronized List<Overlay> getLayer(OverlayLayer layer)
|
||||
{
|
||||
return overlayLayers.get(layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add overlay.
|
||||
*
|
||||
* @param overlay the overlay
|
||||
* @return true if overlay was added
|
||||
*/
|
||||
public synchronized boolean add(final Overlay overlay)
|
||||
{
|
||||
if (overlays.contains(overlay))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add is always true
|
||||
overlays.add(overlay);
|
||||
loadOverlay(overlay);
|
||||
// WidgetItemOverlays have a reference to the overlay manager in order to get the WidgetItems
|
||||
// for each frame.
|
||||
if (overlay instanceof WidgetItemOverlay)
|
||||
{
|
||||
((WidgetItemOverlay) overlay).setOverlayManager(this);
|
||||
}
|
||||
rebuildOverlayLayers();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove overlay.
|
||||
*
|
||||
* @param overlay the overlay
|
||||
* @return true if overlay was removed
|
||||
*/
|
||||
public synchronized boolean remove(final Overlay overlay)
|
||||
{
|
||||
final boolean remove = overlays.remove(overlay);
|
||||
|
||||
if (remove)
|
||||
{
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove if overlay matches filter
|
||||
*
|
||||
* @param filter the filter
|
||||
* @return true if any overlay was removed
|
||||
*/
|
||||
public synchronized boolean removeIf(Predicate<Overlay> filter)
|
||||
{
|
||||
final boolean removeIf = overlays.removeIf(filter);
|
||||
|
||||
if (removeIf)
|
||||
{
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
return removeIf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all overlays
|
||||
*/
|
||||
public synchronized void clear()
|
||||
{
|
||||
overlays.clear();
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force save overlay data
|
||||
*
|
||||
* @param overlay overlay to save
|
||||
*/
|
||||
public synchronized void saveOverlay(final Overlay overlay)
|
||||
{
|
||||
saveOverlayPosition(overlay);
|
||||
saveOverlaySize(overlay);
|
||||
saveOverlayLocation(overlay);
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets stored overlay position data
|
||||
*
|
||||
* @param overlay overlay to reset
|
||||
*/
|
||||
public synchronized void resetOverlay(final Overlay overlay)
|
||||
{
|
||||
overlay.setPreferredPosition(null);
|
||||
overlay.setPreferredSize(null);
|
||||
overlay.setPreferredLocation(null);
|
||||
saveOverlay(overlay);
|
||||
}
|
||||
|
||||
private synchronized void rebuildOverlayLayers()
|
||||
{
|
||||
for (OverlayLayer l : OverlayLayer.values())
|
||||
{
|
||||
overlayLayers.put(l, new ArrayList<>());
|
||||
}
|
||||
|
||||
for (final Overlay overlay : overlays)
|
||||
{
|
||||
OverlayLayer layer = overlay.getLayer();
|
||||
|
||||
if (overlay.getPreferredLocation() != null && overlay.getPreferredPosition() == null)
|
||||
{
|
||||
// When UNDER_WIDGET overlays are in preferred locations, move to
|
||||
// ABOVE_WIDGETS so that it can draw over interfaces
|
||||
if (layer == OverlayLayer.UNDER_WIDGETS && !(overlay instanceof WidgetOverlay))
|
||||
{
|
||||
layer = OverlayLayer.ABOVE_WIDGETS;
|
||||
}
|
||||
}
|
||||
|
||||
overlayLayers.get(layer).add(overlay);
|
||||
}
|
||||
|
||||
overlayLayers.forEach((layer, value) ->
|
||||
{
|
||||
value.sort(OVERLAY_COMPARATOR);
|
||||
overlayLayers.put(layer, Collections.unmodifiableList(value));
|
||||
});
|
||||
}
|
||||
|
||||
private void loadOverlay(final Overlay overlay)
|
||||
{
|
||||
final Point location = loadOverlayLocation(overlay);
|
||||
overlay.setPreferredLocation(location);
|
||||
final Dimension size = loadOverlaySize(overlay);
|
||||
overlay.setPreferredSize(size);
|
||||
final OverlayPosition position = loadOverlayPosition(overlay);
|
||||
overlay.setPreferredPosition(position);
|
||||
}
|
||||
|
||||
private void saveOverlayLocation(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||
if (overlay.getPreferredLocation() != null)
|
||||
{
|
||||
configManager.setConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key,
|
||||
overlay.getPreferredLocation());
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOverlaySize(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||
if (overlay.getPreferredSize() != null)
|
||||
{
|
||||
configManager.setConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key,
|
||||
overlay.getPreferredSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOverlayPosition(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||
if (overlay.getPreferredPosition() != null)
|
||||
{
|
||||
configManager.setConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key,
|
||||
overlay.getPreferredPosition());
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
||||
private Point loadOverlayLocation(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, key, Point.class);
|
||||
}
|
||||
|
||||
private Dimension loadOverlaySize(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, key, Dimension.class);
|
||||
}
|
||||
|
||||
private OverlayPosition loadOverlayPosition(final Overlay overlay)
|
||||
{
|
||||
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, locationKey, OverlayPosition.class);
|
||||
}
|
||||
|
||||
public WidgetOverlay getWidgetOverlay(final WidgetInfo info)
|
||||
{
|
||||
for (Overlay o : overlays)
|
||||
{
|
||||
if (o instanceof WidgetOverlay)
|
||||
{
|
||||
WidgetOverlay overlay = (WidgetOverlay) o;
|
||||
if (overlay.getWidgetInfo().equals(info))
|
||||
{
|
||||
return overlay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.OverlayMenuClicked;
|
||||
import net.runelite.client.events.PluginChanged;
|
||||
|
||||
/**
|
||||
* Manages state of all game overlays
|
||||
*/
|
||||
@Singleton
|
||||
public class OverlayManager
|
||||
{
|
||||
public static final String OPTION_CONFIGURE = "Configure";
|
||||
|
||||
private static final String OVERLAY_CONFIG_PREFERRED_LOCATION = "_preferredLocation";
|
||||
private static final String OVERLAY_CONFIG_PREFERRED_POSITION = "_preferredPosition";
|
||||
private static final String OVERLAY_CONFIG_PREFERRED_SIZE = "_preferredSize";
|
||||
private static final String RUNELITE_CONFIG_GROUP_NAME = RuneLiteConfig.class.getAnnotation(ConfigGroup.class).value();
|
||||
|
||||
@VisibleForTesting
|
||||
static final Comparator<Overlay> OVERLAY_COMPARATOR = (a, b) ->
|
||||
{
|
||||
final OverlayPosition aPos = a.getPreferredPosition() != null
|
||||
? a.getPreferredPosition()
|
||||
: a.getPosition();
|
||||
|
||||
final OverlayPosition bPos = b.getPreferredPosition() != null
|
||||
? b.getPreferredPosition()
|
||||
: b.getPosition();
|
||||
|
||||
if (aPos != bPos)
|
||||
{
|
||||
// This is so non-dynamic overlays render after dynamic
|
||||
// overlays, which are generally in the scene
|
||||
return aPos.compareTo(bPos);
|
||||
}
|
||||
|
||||
// For dynamic overlays, higher priority means to
|
||||
// draw *later* so it is on top.
|
||||
// For non-dynamic overlays, higher priority means
|
||||
// draw *first* so that they are closer to their
|
||||
// defined position.
|
||||
return aPos == OverlayPosition.DYNAMIC
|
||||
? a.getPriority().compareTo(b.getPriority())
|
||||
: b.getPriority().compareTo(a.getPriority());
|
||||
};
|
||||
|
||||
/**
|
||||
* Insertion-order sorted set of overlays
|
||||
* All access to this must be guarded by a lock on this OverlayManager
|
||||
*/
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<Overlay> overlays = new ArrayList<>();
|
||||
@Getter
|
||||
private final List<WidgetItem> itemWidgets = new ArrayList<>();
|
||||
|
||||
private final Map<OverlayLayer, List<Overlay>> overlayLayers = new EnumMap<>(OverlayLayer.class);
|
||||
|
||||
private final ConfigManager configManager;
|
||||
private final EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
private OverlayManager(final ConfigManager configManager, final EventBus eventBus)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
this.eventBus = eventBus;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPluginChanged(final PluginChanged event)
|
||||
{
|
||||
overlays.forEach(this::loadOverlay);
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE_OVERLAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.consume();
|
||||
|
||||
Optional<Overlay> optionalOverlay = overlays.stream().filter(o -> overlays.indexOf(o) == event.getId()).findAny();
|
||||
if (optionalOverlay.isPresent())
|
||||
{
|
||||
Overlay overlay = optionalOverlay.get();
|
||||
List<OverlayMenuEntry> menuEntries = overlay.getMenuEntries();
|
||||
Optional<OverlayMenuEntry> optionalOverlayMenuEntry = menuEntries.stream()
|
||||
.filter(me -> me.getOption().equals(event.getMenuOption()))
|
||||
.findAny();
|
||||
if (optionalOverlayMenuEntry.isPresent())
|
||||
{
|
||||
eventBus.post(new OverlayMenuClicked(optionalOverlayMenuEntry.get(), overlay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the overlays on a layer sorted by priority and position
|
||||
*
|
||||
* @param layer the layer
|
||||
* @return An immutable list of all of the overlays on that layer
|
||||
*/
|
||||
synchronized List<Overlay> getLayer(OverlayLayer layer)
|
||||
{
|
||||
return overlayLayers.get(layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add overlay.
|
||||
*
|
||||
* @param overlay the overlay
|
||||
* @return true if overlay was added
|
||||
*/
|
||||
public synchronized boolean add(final Overlay overlay)
|
||||
{
|
||||
if (overlays.contains(overlay))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add is always true
|
||||
overlays.add(overlay);
|
||||
loadOverlay(overlay);
|
||||
// WidgetItemOverlays have a reference to the overlay manager in order to get the WidgetItems
|
||||
// for each frame.
|
||||
if (overlay instanceof WidgetItemOverlay)
|
||||
{
|
||||
((WidgetItemOverlay) overlay).setOverlayManager(this);
|
||||
}
|
||||
rebuildOverlayLayers();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove overlay.
|
||||
*
|
||||
* @param overlay the overlay
|
||||
* @return true if overlay was removed
|
||||
*/
|
||||
public synchronized boolean remove(final Overlay overlay)
|
||||
{
|
||||
final boolean remove = overlays.remove(overlay);
|
||||
|
||||
if (remove)
|
||||
{
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove if overlay matches filter
|
||||
*
|
||||
* @param filter the filter
|
||||
* @return true if any overlay was removed
|
||||
*/
|
||||
public synchronized boolean removeIf(Predicate<Overlay> filter)
|
||||
{
|
||||
final boolean removeIf = overlays.removeIf(filter);
|
||||
|
||||
if (removeIf)
|
||||
{
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
return removeIf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all overlays
|
||||
*/
|
||||
public synchronized void clear()
|
||||
{
|
||||
overlays.clear();
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force save overlay data
|
||||
*
|
||||
* @param overlay overlay to save
|
||||
*/
|
||||
public synchronized void saveOverlay(final Overlay overlay)
|
||||
{
|
||||
saveOverlayPosition(overlay);
|
||||
saveOverlaySize(overlay);
|
||||
saveOverlayLocation(overlay);
|
||||
rebuildOverlayLayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets stored overlay position data
|
||||
*
|
||||
* @param overlay overlay to reset
|
||||
*/
|
||||
public synchronized void resetOverlay(final Overlay overlay)
|
||||
{
|
||||
overlay.setPreferredPosition(null);
|
||||
overlay.setPreferredSize(null);
|
||||
overlay.setPreferredLocation(null);
|
||||
saveOverlay(overlay);
|
||||
}
|
||||
|
||||
private synchronized void rebuildOverlayLayers()
|
||||
{
|
||||
for (OverlayLayer l : OverlayLayer.values())
|
||||
{
|
||||
overlayLayers.put(l, new ArrayList<>());
|
||||
}
|
||||
|
||||
for (final Overlay overlay : overlays)
|
||||
{
|
||||
OverlayLayer layer = overlay.getLayer();
|
||||
|
||||
if (overlay.getPreferredLocation() != null && overlay.getPreferredPosition() == null)
|
||||
{
|
||||
// When UNDER_WIDGET overlays are in preferred locations, move to
|
||||
// ABOVE_WIDGETS so that it can draw over interfaces
|
||||
if (layer == OverlayLayer.UNDER_WIDGETS && !(overlay instanceof WidgetOverlay))
|
||||
{
|
||||
layer = OverlayLayer.ABOVE_WIDGETS;
|
||||
}
|
||||
}
|
||||
|
||||
overlayLayers.get(layer).add(overlay);
|
||||
}
|
||||
|
||||
overlayLayers.forEach((layer, value) ->
|
||||
{
|
||||
value.sort(OVERLAY_COMPARATOR);
|
||||
overlayLayers.put(layer, Collections.unmodifiableList(value));
|
||||
});
|
||||
}
|
||||
|
||||
private void loadOverlay(final Overlay overlay)
|
||||
{
|
||||
final Point location = loadOverlayLocation(overlay);
|
||||
overlay.setPreferredLocation(location);
|
||||
final Dimension size = loadOverlaySize(overlay);
|
||||
overlay.setPreferredSize(size);
|
||||
final OverlayPosition position = loadOverlayPosition(overlay);
|
||||
overlay.setPreferredPosition(position);
|
||||
}
|
||||
|
||||
private void saveOverlayLocation(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||
if (overlay.getPreferredLocation() != null)
|
||||
{
|
||||
configManager.setConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key,
|
||||
overlay.getPreferredLocation());
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOverlaySize(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||
if (overlay.getPreferredSize() != null)
|
||||
{
|
||||
configManager.setConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key,
|
||||
overlay.getPreferredSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOverlayPosition(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||
if (overlay.getPreferredPosition() != null)
|
||||
{
|
||||
configManager.setConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key,
|
||||
overlay.getPreferredPosition());
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.unsetConfiguration(
|
||||
RUNELITE_CONFIG_GROUP_NAME,
|
||||
key);
|
||||
}
|
||||
}
|
||||
|
||||
private Point loadOverlayLocation(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_LOCATION;
|
||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, key, Point.class);
|
||||
}
|
||||
|
||||
private Dimension loadOverlaySize(final Overlay overlay)
|
||||
{
|
||||
final String key = overlay.getName() + OVERLAY_CONFIG_PREFERRED_SIZE;
|
||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, key, Dimension.class);
|
||||
}
|
||||
|
||||
private OverlayPosition loadOverlayPosition(final Overlay overlay)
|
||||
{
|
||||
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, locationKey, OverlayPosition.class);
|
||||
}
|
||||
|
||||
public WidgetOverlay getWidgetOverlay(final WidgetInfo info)
|
||||
{
|
||||
for (Overlay o : overlays)
|
||||
{
|
||||
if (o instanceof WidgetOverlay)
|
||||
{
|
||||
WidgetOverlay overlay = (WidgetOverlay) o;
|
||||
if (overlay.getWidgetInfo().equals(info))
|
||||
{
|
||||
return overlay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,6 @@ import java.awt.image.BufferedImage;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
@@ -77,7 +76,7 @@ public class OverlayUtil
|
||||
graphics.setColor(color);
|
||||
graphics.rotate(angle, center.getX(), center.getY());
|
||||
graphics.drawRect(center.getX() - width / 2, center.getY() - height / 2, width, height);
|
||||
graphics.rotate(-angle , center.getX(), center.getY());
|
||||
graphics.rotate(-angle, center.getX(), center.getY());
|
||||
}
|
||||
|
||||
public static void renderTextLocation(Graphics2D graphics, Point txtLoc, String text, Color color)
|
||||
@@ -259,13 +258,13 @@ public class OverlayUtil
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color,
|
||||
BufferedImage image, int yOffset, int xOffset)
|
||||
BufferedImage image, int yOffset, int xOffset)
|
||||
{
|
||||
Point textLocation = new Point(actor.getConvexHull().getBounds().x + xOffset,
|
||||
actor.getConvexHull().getBounds().y + yOffset);
|
||||
|
||||
actor.getConvexHull().getBounds().y + yOffset);
|
||||
|
||||
renderImageLocation(graphics, textLocation, image);
|
||||
xOffset = image.getWidth() + 1;
|
||||
yOffset = (image.getHeight() - (int) graphics.getFontMetrics().getStringBounds(text, graphics).getHeight());
|
||||
|
||||
@@ -101,8 +101,8 @@ public class WidgetOverlay extends Overlay
|
||||
int y = bounds.y;
|
||||
x = Math.max(parent.x, x);
|
||||
y = Math.max(parent.y, y);
|
||||
x = Math.min((int)parent.getMaxX() - bounds.width, x);
|
||||
y = Math.min((int)parent.getMaxY() - bounds.height, y);
|
||||
x = Math.min((int) parent.getMaxX() - bounds.width, x);
|
||||
y = Math.min((int) parent.getMaxY() - bounds.height, y);
|
||||
bounds.setLocation(x, y);
|
||||
return bounds;
|
||||
}
|
||||
@@ -123,8 +123,8 @@ public class WidgetOverlay extends Overlay
|
||||
int y = bounds.y;
|
||||
x = Math.max(parent.x, x);
|
||||
y = Math.max(parent.y, y);
|
||||
x = Math.min((int)parent.getMaxX() - bounds.width, x);
|
||||
y = Math.min((int)parent.getMaxY() - bounds.height, y);
|
||||
x = Math.min((int) parent.getMaxX() - bounds.width, x);
|
||||
y = Math.min((int) parent.getMaxY() - bounds.height, y);
|
||||
bounds.setLocation(x, y);
|
||||
widget.setOriginalX(0);
|
||||
widget.setOriginalY(0);
|
||||
|
||||
@@ -200,10 +200,7 @@ public class ArrowMinimapOverlay extends Overlay
|
||||
localPoint = new LocalPoint(localPoint.getX() + 1, localPoint.getY() + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
localPoint = npc.getLocalLocation();
|
||||
}
|
||||
localPoint = null;
|
||||
|
||||
renderMinimapArrow(graphics, arrowPoint, localPoint, localPlayerPos, worldPlayerPos);
|
||||
}
|
||||
|
||||
@@ -1,61 +1,59 @@
|
||||
/*
|
||||
* 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.ui.overlay.arrow;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
|
||||
@Singleton
|
||||
public class ArrowPointManager
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Multimap<Plugin, ArrowPoint> arrowPoints = HashMultimap.create();
|
||||
|
||||
public void add(Plugin plugin, ArrowPoint arrowPoint)
|
||||
{
|
||||
arrowPoints.put(plugin, arrowPoint);
|
||||
}
|
||||
|
||||
public void remove(Plugin plugin, ArrowPoint arrowPoint)
|
||||
{
|
||||
arrowPoints.remove(plugin, arrowPoint);
|
||||
}
|
||||
|
||||
public void clear(Plugin plugin)
|
||||
{
|
||||
arrowPoints.removeAll(plugin);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
arrowPoints.clear();
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay.arrow;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
|
||||
@Singleton
|
||||
public class ArrowPointManager
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Multimap<Plugin, ArrowPoint> arrowPoints = HashMultimap.create();
|
||||
|
||||
public void add(Plugin plugin, ArrowPoint arrowPoint)
|
||||
{
|
||||
arrowPoints.put(plugin, arrowPoint);
|
||||
}
|
||||
|
||||
public void remove(Plugin plugin, ArrowPoint arrowPoint)
|
||||
{
|
||||
arrowPoints.remove(plugin, arrowPoint);
|
||||
}
|
||||
|
||||
public void clear(Plugin plugin)
|
||||
{
|
||||
arrowPoints.removeAll(plugin);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
arrowPoints.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,98 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.ui.overlay.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Setter
|
||||
public class BackgroundComponent implements RenderableEntity
|
||||
{
|
||||
private static final int BORDER_OFFSET = 2;
|
||||
|
||||
private static final int OUTSIDE_STROKE_RED_OFFSET = 14;
|
||||
private static final int OUTSIDE_STROKE_GREEN_OFFSET = 13;
|
||||
private static final int OUTSIDE_STROKE_BLUE_OFFSET = 15;
|
||||
private static final int OUTSIDE_STROKE_ALPHA = 255;
|
||||
|
||||
private static final int INSIDE_STROKE_RED_OFFSET = 20;
|
||||
private static final int INSIDE_STROKE_GREEN_OFFSET = 21;
|
||||
private static final int INSIDE_STROKE_BLUE_OFFSET = 19;
|
||||
private static final int INSIDE_STROKE_ALPHA = 255;
|
||||
|
||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
private Rectangle rectangle = new Rectangle();
|
||||
private boolean fill = true;
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Color outsideStrokeColor = new Color(
|
||||
Math.max(0, backgroundColor.getRed() - OUTSIDE_STROKE_RED_OFFSET),
|
||||
Math.max(0, backgroundColor.getGreen() - OUTSIDE_STROKE_GREEN_OFFSET),
|
||||
Math.max(0, backgroundColor.getBlue() - OUTSIDE_STROKE_BLUE_OFFSET),
|
||||
OUTSIDE_STROKE_ALPHA
|
||||
);
|
||||
|
||||
Color insideStrokeColor = new Color(
|
||||
Math.min(255, backgroundColor.getRed() + INSIDE_STROKE_RED_OFFSET),
|
||||
Math.min(255, backgroundColor.getGreen() + INSIDE_STROKE_GREEN_OFFSET),
|
||||
Math.min(255, backgroundColor.getBlue() + INSIDE_STROKE_BLUE_OFFSET),
|
||||
INSIDE_STROKE_ALPHA
|
||||
);
|
||||
|
||||
// Render background
|
||||
if (fill)
|
||||
{
|
||||
graphics.setColor(backgroundColor);
|
||||
graphics.fill(rectangle);
|
||||
}
|
||||
|
||||
// Render outside stroke
|
||||
final Rectangle outsideStroke = new Rectangle();
|
||||
outsideStroke.setLocation(rectangle.x, rectangle.y);
|
||||
outsideStroke.setSize(rectangle.width - BORDER_OFFSET / 2, rectangle.height - BORDER_OFFSET / 2);
|
||||
graphics.setColor(outsideStrokeColor);
|
||||
graphics.draw(outsideStroke);
|
||||
|
||||
// Render inside stroke
|
||||
final Rectangle insideStroke = new Rectangle();
|
||||
insideStroke.setLocation(rectangle.x + BORDER_OFFSET / 2, rectangle.y + BORDER_OFFSET / 2);
|
||||
insideStroke.setSize(rectangle.width - BORDER_OFFSET - BORDER_OFFSET / 2,
|
||||
rectangle.height - BORDER_OFFSET - BORDER_OFFSET / 2);
|
||||
graphics.setColor(insideStrokeColor);
|
||||
graphics.draw(insideStroke);
|
||||
|
||||
return new Dimension(rectangle.getSize());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2017, 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.ui.overlay.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Setter
|
||||
public class BackgroundComponent implements RenderableEntity
|
||||
{
|
||||
private static final int BORDER_OFFSET = 2;
|
||||
|
||||
private static final int OUTSIDE_STROKE_RED_OFFSET = 14;
|
||||
private static final int OUTSIDE_STROKE_GREEN_OFFSET = 13;
|
||||
private static final int OUTSIDE_STROKE_BLUE_OFFSET = 15;
|
||||
private static final int OUTSIDE_STROKE_ALPHA = 255;
|
||||
|
||||
private static final int INSIDE_STROKE_RED_OFFSET = 20;
|
||||
private static final int INSIDE_STROKE_GREEN_OFFSET = 21;
|
||||
private static final int INSIDE_STROKE_BLUE_OFFSET = 19;
|
||||
private static final int INSIDE_STROKE_ALPHA = 255;
|
||||
|
||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
private Rectangle rectangle = new Rectangle();
|
||||
private boolean fill = true;
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Color outsideStrokeColor = new Color(
|
||||
Math.max(0, backgroundColor.getRed() - OUTSIDE_STROKE_RED_OFFSET),
|
||||
Math.max(0, backgroundColor.getGreen() - OUTSIDE_STROKE_GREEN_OFFSET),
|
||||
Math.max(0, backgroundColor.getBlue() - OUTSIDE_STROKE_BLUE_OFFSET),
|
||||
OUTSIDE_STROKE_ALPHA
|
||||
);
|
||||
|
||||
Color insideStrokeColor = new Color(
|
||||
Math.min(255, backgroundColor.getRed() + INSIDE_STROKE_RED_OFFSET),
|
||||
Math.min(255, backgroundColor.getGreen() + INSIDE_STROKE_GREEN_OFFSET),
|
||||
Math.min(255, backgroundColor.getBlue() + INSIDE_STROKE_BLUE_OFFSET),
|
||||
INSIDE_STROKE_ALPHA
|
||||
);
|
||||
|
||||
// Render background
|
||||
if (fill)
|
||||
{
|
||||
graphics.setColor(backgroundColor);
|
||||
graphics.fill(rectangle);
|
||||
}
|
||||
|
||||
// Render outside stroke
|
||||
final Rectangle outsideStroke = new Rectangle();
|
||||
outsideStroke.setLocation(rectangle.x, rectangle.y);
|
||||
outsideStroke.setSize(rectangle.width - BORDER_OFFSET / 2, rectangle.height - BORDER_OFFSET / 2);
|
||||
graphics.setColor(outsideStrokeColor);
|
||||
graphics.draw(outsideStroke);
|
||||
|
||||
// Render inside stroke
|
||||
final Rectangle insideStroke = new Rectangle();
|
||||
insideStroke.setLocation(rectangle.x + BORDER_OFFSET / 2, rectangle.y + BORDER_OFFSET / 2);
|
||||
insideStroke.setSize(rectangle.width - BORDER_OFFSET - BORDER_OFFSET / 2,
|
||||
rectangle.height - BORDER_OFFSET - BORDER_OFFSET / 2);
|
||||
graphics.setColor(insideStrokeColor);
|
||||
graphics.draw(insideStroke);
|
||||
|
||||
return new Dimension(rectangle.getSize());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
/*
|
||||
* 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.ui.overlay.components;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
public interface LayoutableRenderableEntity extends RenderableEntity
|
||||
{
|
||||
Rectangle getBounds();
|
||||
void setPreferredLocation(Point position);
|
||||
void setPreferredSize(Dimension dimension);
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay.components;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
public interface LayoutableRenderableEntity extends RenderableEntity
|
||||
{
|
||||
Rectangle getBounds();
|
||||
|
||||
void setPreferredLocation(Point position);
|
||||
|
||||
void setPreferredSize(Dimension dimension);
|
||||
}
|
||||
|
||||
@@ -61,10 +61,10 @@ public class PanelComponent implements LayoutableRenderableEntity
|
||||
|
||||
@Setter
|
||||
private Rectangle border = new Rectangle(
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER);
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER);
|
||||
|
||||
@Setter
|
||||
private Point gap = new Point(0, 0);
|
||||
@@ -81,8 +81,8 @@ public class PanelComponent implements LayoutableRenderableEntity
|
||||
|
||||
// Calculate panel dimension
|
||||
final Dimension dimension = new Dimension(
|
||||
border.x + childDimensions.width + border.width,
|
||||
border.y + childDimensions.height + border.height);
|
||||
border.x + childDimensions.width + border.width,
|
||||
border.y + childDimensions.height + border.height);
|
||||
|
||||
// Render background
|
||||
if (backgroundColor != null)
|
||||
@@ -103,15 +103,15 @@ public class PanelComponent implements LayoutableRenderableEntity
|
||||
|
||||
// Create child preferred size
|
||||
final Dimension childPreferredSize = new Dimension(
|
||||
preferredSize.width - border.x - border.width,
|
||||
preferredSize.height - border.y - border.height);
|
||||
preferredSize.width - border.x - border.width,
|
||||
preferredSize.height - border.y - border.height);
|
||||
|
||||
// Calculate max width/height for infoboxes
|
||||
int totalHeight = 0;
|
||||
int totalWidth = 0;
|
||||
|
||||
// Render all children
|
||||
for (int i = 0; i < children.size(); i ++)
|
||||
for (int i = 0; i < children.size(); i++)
|
||||
{
|
||||
final LayoutableRenderableEntity child = children.get(i);
|
||||
child.setPreferredLocation(new Point(x, y));
|
||||
@@ -136,7 +136,7 @@ public class PanelComponent implements LayoutableRenderableEntity
|
||||
totalWidth = Math.max(totalWidth, width);
|
||||
totalHeight = Math.max(totalHeight, height);
|
||||
|
||||
if (wrapping > 0 && i < children.size() - 1 && (i + 1) % wrapping == 0)
|
||||
if (wrapping > 0 && i < children.size() - 1 && (i + 1) % wrapping == 0)
|
||||
{
|
||||
switch (orientation)
|
||||
{
|
||||
|
||||
@@ -1,220 +1,220 @@
|
||||
/*
|
||||
* 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.ui.overlay.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
@Setter
|
||||
public class TooltipComponent implements RenderableEntity
|
||||
{
|
||||
private static final Pattern BR = Pattern.compile("</br>");
|
||||
private static final int OFFSET = 4;
|
||||
private static final int MOD_ICON_WIDTH = 13; // they are generally 13px wide
|
||||
|
||||
private String text;
|
||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
private Point position = new Point();
|
||||
private IndexedSprite[] modIcons;
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Tooltip size
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
final int textDescent = metrics.getDescent();
|
||||
final int textHeight = metrics.getHeight();
|
||||
int tooltipWidth = 0;
|
||||
int tooltipHeight = 0;
|
||||
String[] lines = BR.split(text);
|
||||
|
||||
// Calculate tooltip size
|
||||
for (String line : lines)
|
||||
{
|
||||
int textWidth = calculateTextWidth(metrics, line);
|
||||
|
||||
if (textWidth > tooltipWidth)
|
||||
{
|
||||
tooltipWidth = textWidth;
|
||||
}
|
||||
|
||||
tooltipHeight += textHeight;
|
||||
}
|
||||
|
||||
// Tooltip position
|
||||
int x = position.x;
|
||||
int y = position.y;
|
||||
|
||||
// Render tooltip - background
|
||||
final Rectangle tooltipBackground = new Rectangle(x, y,
|
||||
tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2);
|
||||
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
||||
backgroundComponent.setBackgroundColor(backgroundColor);
|
||||
backgroundComponent.setRectangle(tooltipBackground);
|
||||
backgroundComponent.render(graphics);
|
||||
graphics.setColor(Color.WHITE);
|
||||
|
||||
// Render tooltip - text - line by line
|
||||
int textX = x + OFFSET;
|
||||
int textY = y + OFFSET;
|
||||
int lineX;
|
||||
Color nextColor = Color.WHITE;
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
lineX = textX;
|
||||
final String line = lines[i];
|
||||
char[] chars = line.toCharArray();
|
||||
|
||||
int begin = 0;
|
||||
for (int j = 0; j < chars.length; j++)
|
||||
{
|
||||
if (chars[j] == '<')
|
||||
{
|
||||
TextComponent textComponent = new TextComponent();
|
||||
textComponent.setColor(nextColor);
|
||||
String text = line.substring(begin, j);
|
||||
textComponent.setText(text);
|
||||
textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent));
|
||||
textComponent.render(graphics);
|
||||
|
||||
lineX += metrics.stringWidth(text);
|
||||
|
||||
begin = j;
|
||||
}
|
||||
else if (chars[j] == '>')
|
||||
{
|
||||
String subLine = line.substring(begin + 1, j);
|
||||
|
||||
if (subLine.startsWith("col="))
|
||||
{
|
||||
String argument = subLine.substring(4);
|
||||
nextColor = Color.decode("#" + argument);
|
||||
}
|
||||
else if (subLine.equals("/col"))
|
||||
{
|
||||
nextColor = Color.WHITE;
|
||||
}
|
||||
else if (subLine.startsWith("img="))
|
||||
{
|
||||
if (modIcons != null)
|
||||
{
|
||||
String argument = subLine.substring(4);
|
||||
int iconId = Integer.parseInt(argument);
|
||||
IndexedSprite modIcon = modIcons[iconId];
|
||||
renderModIcon(graphics, lineX, textY + i * textHeight - textDescent, modIcon);
|
||||
lineX += modIcon.getWidth();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponent textComponent = new TextComponent();
|
||||
textComponent.setColor(nextColor);
|
||||
String text = line.substring(begin, j + 1);
|
||||
textComponent.setText(text);
|
||||
textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent));
|
||||
textComponent.render(graphics);
|
||||
|
||||
lineX += metrics.stringWidth(text);
|
||||
}
|
||||
|
||||
begin = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw trailing text (after last tag)
|
||||
final TextComponent textComponent = new TextComponent();
|
||||
textComponent.setColor(nextColor);
|
||||
textComponent.setText(line.substring(begin, line.length()));
|
||||
textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent));
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
|
||||
return new Dimension(tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2);
|
||||
}
|
||||
|
||||
private static int calculateTextWidth(FontMetrics metrics, String line)
|
||||
{
|
||||
char[] chars = line.toCharArray();
|
||||
int textWidth = 0;
|
||||
|
||||
int begin = 0;
|
||||
for (int j = 0; j < chars.length; j++)
|
||||
{
|
||||
if (chars[j] == '<')
|
||||
{
|
||||
textWidth += metrics.stringWidth(line.substring(begin, j));
|
||||
|
||||
begin = j;
|
||||
}
|
||||
else if (chars[j] == '>')
|
||||
{
|
||||
String subLine = line.substring(begin + 1, j);
|
||||
|
||||
if (subLine.startsWith("img="))
|
||||
{
|
||||
textWidth += MOD_ICON_WIDTH;
|
||||
}
|
||||
else if (!subLine.startsWith("col=") && !subLine.startsWith("/col"))
|
||||
{
|
||||
textWidth += metrics.stringWidth(line.substring(begin, j + 1));
|
||||
}
|
||||
|
||||
begin = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Include trailing text (after last tag)
|
||||
textWidth += metrics.stringWidth(line.substring(begin, line.length()));
|
||||
|
||||
return textWidth;
|
||||
}
|
||||
|
||||
private void renderModIcon(Graphics2D graphics, int x, int y, IndexedSprite modIcon)
|
||||
{
|
||||
int sourceOffset = 0;
|
||||
|
||||
for (int y2 = 0; y2 < modIcon.getHeight(); y2++)
|
||||
{
|
||||
for (int x2 = 0; x2 < modIcon.getWidth(); x2++)
|
||||
{
|
||||
int index = modIcon.getPixels()[sourceOffset++] & 0xff;
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
graphics.setColor(new Color(modIcon.getPalette()[index]));
|
||||
graphics.drawLine(x + x2, y + y2, x + x2, y + y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.client.ui.overlay.RenderableEntity;
|
||||
|
||||
@Setter
|
||||
public class TooltipComponent implements RenderableEntity
|
||||
{
|
||||
private static final Pattern BR = Pattern.compile("</br>");
|
||||
private static final int OFFSET = 4;
|
||||
private static final int MOD_ICON_WIDTH = 13; // they are generally 13px wide
|
||||
|
||||
private String text;
|
||||
private Color backgroundColor = ComponentConstants.STANDARD_BACKGROUND_COLOR;
|
||||
private Point position = new Point();
|
||||
private IndexedSprite[] modIcons;
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Tooltip size
|
||||
final FontMetrics metrics = graphics.getFontMetrics();
|
||||
final int textDescent = metrics.getDescent();
|
||||
final int textHeight = metrics.getHeight();
|
||||
int tooltipWidth = 0;
|
||||
int tooltipHeight = 0;
|
||||
String[] lines = BR.split(text);
|
||||
|
||||
// Calculate tooltip size
|
||||
for (String line : lines)
|
||||
{
|
||||
int textWidth = calculateTextWidth(metrics, line);
|
||||
|
||||
if (textWidth > tooltipWidth)
|
||||
{
|
||||
tooltipWidth = textWidth;
|
||||
}
|
||||
|
||||
tooltipHeight += textHeight;
|
||||
}
|
||||
|
||||
// Tooltip position
|
||||
int x = position.x;
|
||||
int y = position.y;
|
||||
|
||||
// Render tooltip - background
|
||||
final Rectangle tooltipBackground = new Rectangle(x, y,
|
||||
tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2);
|
||||
final BackgroundComponent backgroundComponent = new BackgroundComponent();
|
||||
backgroundComponent.setBackgroundColor(backgroundColor);
|
||||
backgroundComponent.setRectangle(tooltipBackground);
|
||||
backgroundComponent.render(graphics);
|
||||
graphics.setColor(Color.WHITE);
|
||||
|
||||
// Render tooltip - text - line by line
|
||||
int textX = x + OFFSET;
|
||||
int textY = y + OFFSET;
|
||||
int lineX;
|
||||
Color nextColor = Color.WHITE;
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
lineX = textX;
|
||||
final String line = lines[i];
|
||||
char[] chars = line.toCharArray();
|
||||
|
||||
int begin = 0;
|
||||
for (int j = 0; j < chars.length; j++)
|
||||
{
|
||||
if (chars[j] == '<')
|
||||
{
|
||||
TextComponent textComponent = new TextComponent();
|
||||
textComponent.setColor(nextColor);
|
||||
String text = line.substring(begin, j);
|
||||
textComponent.setText(text);
|
||||
textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent));
|
||||
textComponent.render(graphics);
|
||||
|
||||
lineX += metrics.stringWidth(text);
|
||||
|
||||
begin = j;
|
||||
}
|
||||
else if (chars[j] == '>')
|
||||
{
|
||||
String subLine = line.substring(begin + 1, j);
|
||||
|
||||
if (subLine.startsWith("col="))
|
||||
{
|
||||
String argument = subLine.substring(4);
|
||||
nextColor = Color.decode("#" + argument);
|
||||
}
|
||||
else if (subLine.equals("/col"))
|
||||
{
|
||||
nextColor = Color.WHITE;
|
||||
}
|
||||
else if (subLine.startsWith("img="))
|
||||
{
|
||||
if (modIcons != null)
|
||||
{
|
||||
String argument = subLine.substring(4);
|
||||
int iconId = Integer.parseInt(argument);
|
||||
IndexedSprite modIcon = modIcons[iconId];
|
||||
renderModIcon(graphics, lineX, textY + i * textHeight - textDescent, modIcon);
|
||||
lineX += modIcon.getWidth();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponent textComponent = new TextComponent();
|
||||
textComponent.setColor(nextColor);
|
||||
String text = line.substring(begin, j + 1);
|
||||
textComponent.setText(text);
|
||||
textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent));
|
||||
textComponent.render(graphics);
|
||||
|
||||
lineX += metrics.stringWidth(text);
|
||||
}
|
||||
|
||||
begin = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw trailing text (after last tag)
|
||||
final TextComponent textComponent = new TextComponent();
|
||||
textComponent.setColor(nextColor);
|
||||
textComponent.setText(line.substring(begin));
|
||||
textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent));
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
|
||||
return new Dimension(tooltipWidth + OFFSET * 2, tooltipHeight + OFFSET * 2);
|
||||
}
|
||||
|
||||
private static int calculateTextWidth(FontMetrics metrics, String line)
|
||||
{
|
||||
char[] chars = line.toCharArray();
|
||||
int textWidth = 0;
|
||||
|
||||
int begin = 0;
|
||||
for (int j = 0; j < chars.length; j++)
|
||||
{
|
||||
if (chars[j] == '<')
|
||||
{
|
||||
textWidth += metrics.stringWidth(line.substring(begin, j));
|
||||
|
||||
begin = j;
|
||||
}
|
||||
else if (chars[j] == '>')
|
||||
{
|
||||
String subLine = line.substring(begin + 1, j);
|
||||
|
||||
if (subLine.startsWith("img="))
|
||||
{
|
||||
textWidth += MOD_ICON_WIDTH;
|
||||
}
|
||||
else if (!subLine.startsWith("col=") && !subLine.startsWith("/col"))
|
||||
{
|
||||
textWidth += metrics.stringWidth(line.substring(begin, j + 1));
|
||||
}
|
||||
|
||||
begin = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Include trailing text (after last tag)
|
||||
textWidth += metrics.stringWidth(line.substring(begin));
|
||||
|
||||
return textWidth;
|
||||
}
|
||||
|
||||
private void renderModIcon(Graphics2D graphics, int x, int y, IndexedSprite modIcon)
|
||||
{
|
||||
int sourceOffset = 0;
|
||||
|
||||
for (int y2 = 0; y2 < modIcon.getHeight(); y2++)
|
||||
{
|
||||
for (int x2 = 0; x2 < modIcon.getWidth(); x2++)
|
||||
{
|
||||
int index = modIcon.getPixels()[sourceOffset++] & 0xff;
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
graphics.setColor(new Color(modIcon.getPalette()[index]));
|
||||
graphics.drawLine(x + x2, y + y2, x + x2, y + y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,166 +1,166 @@
|
||||
/*
|
||||
* 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.ui.overlay.infobox;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class InfoBoxManager
|
||||
{
|
||||
private final List<InfoBox> infoBoxes = new ArrayList<>();
|
||||
private final RuneLiteConfig runeLiteConfig;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager(final RuneLiteConfig runeLiteConfig)
|
||||
{
|
||||
this.runeLiteConfig = runeLiteConfig;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("runelite") && event.getKey().equals("infoBoxSize"))
|
||||
{
|
||||
infoBoxes.forEach(this::updateInfoBoxImage);
|
||||
}
|
||||
}
|
||||
|
||||
public void addInfoBox(InfoBox infoBox)
|
||||
{
|
||||
Preconditions.checkNotNull(infoBox);
|
||||
log.debug("Adding InfoBox {}", infoBox);
|
||||
|
||||
updateInfoBoxImage(infoBox);
|
||||
infoBoxes.add(infoBox);
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
|
||||
public void removeInfoBox(InfoBox infoBox)
|
||||
{
|
||||
if (infoBoxes.remove(infoBox))
|
||||
{
|
||||
log.debug("Removed InfoBox {}", infoBox);
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeIf(Predicate<InfoBox> filter)
|
||||
{
|
||||
if (infoBoxes.removeIf(filter))
|
||||
{
|
||||
log.debug("Removed InfoBoxes for filter {}", filter);
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
public List<InfoBox> getInfoBoxes()
|
||||
{
|
||||
return Collections.unmodifiableList(infoBoxes);
|
||||
}
|
||||
|
||||
public void cull()
|
||||
{
|
||||
boolean culled = false;
|
||||
for (Iterator<InfoBox> it = infoBoxes.iterator(); it.hasNext();)
|
||||
{
|
||||
InfoBox box = it.next();
|
||||
|
||||
if (box.cull())
|
||||
{
|
||||
log.debug("Culling InfoBox {}", box);
|
||||
it.remove();
|
||||
culled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (culled)
|
||||
{
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInfoBoxImage(final InfoBox infoBox)
|
||||
{
|
||||
if (infoBox.getImage() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set scaled InfoBox image
|
||||
final Image image = infoBox.getImage();
|
||||
Image resultImage = image;
|
||||
final double width = image.getWidth(null);
|
||||
final double height = image.getHeight(null);
|
||||
final double size = Math.max(2, runeLiteConfig.infoBoxSize()); // Limit size to 2 as that is minimum size not causing breakage
|
||||
|
||||
if (size < width || size < height)
|
||||
{
|
||||
final double scalex = size / width;
|
||||
final double scaley = size / height;
|
||||
|
||||
if (scalex == 1 && scaley == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final double scale = Math.min(scalex, scaley);
|
||||
final int newWidth = (int) (width * scale);
|
||||
final int newHeight = (int) (height * scale);
|
||||
final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics g = scaledImage.createGraphics();
|
||||
g.drawImage(image, 0, 0, newWidth, newHeight, null);
|
||||
g.dispose();
|
||||
resultImage = scaledImage;
|
||||
}
|
||||
|
||||
infoBox.setScaledImage(resultImage);
|
||||
}
|
||||
|
||||
private void refreshInfoBoxes()
|
||||
{
|
||||
infoBoxes.sort((b1, b2) -> ComparisonChain
|
||||
.start()
|
||||
.compare(b1.getPriority(), b2.getPriority())
|
||||
.compare(b1.getPlugin().getClass().getAnnotation(PluginDescriptor.class).name(), b2.getPlugin().getClass().getAnnotation(PluginDescriptor.class).name())
|
||||
.result());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay.infobox;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class InfoBoxManager
|
||||
{
|
||||
private final List<InfoBox> infoBoxes = new ArrayList<>();
|
||||
private final RuneLiteConfig runeLiteConfig;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager(final RuneLiteConfig runeLiteConfig)
|
||||
{
|
||||
this.runeLiteConfig = runeLiteConfig;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("runelite") && event.getKey().equals("infoBoxSize"))
|
||||
{
|
||||
infoBoxes.forEach(this::updateInfoBoxImage);
|
||||
}
|
||||
}
|
||||
|
||||
public void addInfoBox(InfoBox infoBox)
|
||||
{
|
||||
Preconditions.checkNotNull(infoBox);
|
||||
log.debug("Adding InfoBox {}", infoBox);
|
||||
|
||||
updateInfoBoxImage(infoBox);
|
||||
infoBoxes.add(infoBox);
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
|
||||
public void removeInfoBox(InfoBox infoBox)
|
||||
{
|
||||
if (infoBoxes.remove(infoBox))
|
||||
{
|
||||
log.debug("Removed InfoBox {}", infoBox);
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeIf(Predicate<InfoBox> filter)
|
||||
{
|
||||
if (infoBoxes.removeIf(filter))
|
||||
{
|
||||
log.debug("Removed InfoBoxes for filter {}", filter);
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
public List<InfoBox> getInfoBoxes()
|
||||
{
|
||||
return Collections.unmodifiableList(infoBoxes);
|
||||
}
|
||||
|
||||
public void cull()
|
||||
{
|
||||
boolean culled = false;
|
||||
for (Iterator<InfoBox> it = infoBoxes.iterator(); it.hasNext(); )
|
||||
{
|
||||
InfoBox box = it.next();
|
||||
|
||||
if (box.cull())
|
||||
{
|
||||
log.debug("Culling InfoBox {}", box);
|
||||
it.remove();
|
||||
culled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (culled)
|
||||
{
|
||||
refreshInfoBoxes();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInfoBoxImage(final InfoBox infoBox)
|
||||
{
|
||||
if (infoBox.getImage() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set scaled InfoBox image
|
||||
final Image image = infoBox.getImage();
|
||||
Image resultImage = image;
|
||||
final double width = image.getWidth(null);
|
||||
final double height = image.getHeight(null);
|
||||
final double size = Math.max(2, runeLiteConfig.infoBoxSize()); // Limit size to 2 as that is minimum size not causing breakage
|
||||
|
||||
if (size < width || size < height)
|
||||
{
|
||||
final double scalex = size / width;
|
||||
final double scaley = size / height;
|
||||
|
||||
if (scalex == 1 && scaley == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final double scale = Math.min(scalex, scaley);
|
||||
final int newWidth = (int) (width * scale);
|
||||
final int newHeight = (int) (height * scale);
|
||||
final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics g = scaledImage.createGraphics();
|
||||
g.drawImage(image, 0, 0, newWidth, newHeight, null);
|
||||
g.dispose();
|
||||
resultImage = scaledImage;
|
||||
}
|
||||
|
||||
infoBox.setScaledImage(resultImage);
|
||||
}
|
||||
|
||||
private void refreshInfoBoxes()
|
||||
{
|
||||
infoBoxes.sort((b1, b2) -> ComparisonChain
|
||||
.start()
|
||||
.compare(b1.getPriority(), b2.getPriority())
|
||||
.compare(b1.getPlugin().getClass().getAnnotation(PluginDescriptor.class).name(), b2.getPlugin().getClass().getAnnotation(PluginDescriptor.class).name())
|
||||
.result());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,311 +1,312 @@
|
||||
/*
|
||||
* 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.ui.overlay.worldmap;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
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.input.MouseManager;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
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;
|
||||
|
||||
@Singleton
|
||||
public class WorldMapOverlay extends Overlay
|
||||
{
|
||||
private static final int TOOLTIP_OFFSET_HEIGHT = 25;
|
||||
private static final int TOOLTIP_OFFSET_WIDTH = 5;
|
||||
private static final int TOOLTIP_PADDING_HEIGHT = 1;
|
||||
private static final int TOOLTIP_PADDING_WIDTH = 2;
|
||||
|
||||
private final WorldMapPointManager worldMapPointManager;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private WorldMapOverlay(
|
||||
Client client,
|
||||
WorldMapPointManager worldMapPointManager,
|
||||
MouseManager mouseManager,
|
||||
WorldMapOverlayMouseListener worldMapOverlayMouseListener)
|
||||
{
|
||||
this.client = client;
|
||||
this.worldMapPointManager = worldMapPointManager;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ABOVE_MAP);
|
||||
mouseManager.registerMouseListener(worldMapOverlayMouseListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final List<WorldMapPoint> points = worldMapPointManager.getWorldMapPoints();
|
||||
|
||||
if (points.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Widget widget = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
if (widget == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Rectangle worldMapRectangle = widget.getBounds();
|
||||
final Area mapViewArea = getWorldMapClipArea(worldMapRectangle);
|
||||
final Rectangle canvasBounds = client.getCanvas().getBounds();
|
||||
// in fixed, the bounds are offset by the size of the black borders outside the canvas
|
||||
canvasBounds.setLocation(0, 0);
|
||||
final Area canvasViewArea = getWorldMapClipArea(canvasBounds);
|
||||
Area currentClip = null;
|
||||
|
||||
WorldMapPoint tooltipPoint = null;
|
||||
|
||||
for (WorldMapPoint worldPoint : points)
|
||||
{
|
||||
BufferedImage image = worldPoint.getImage();
|
||||
WorldPoint point = worldPoint.getWorldPoint();
|
||||
|
||||
if (image != null && point != null)
|
||||
{
|
||||
Point drawPoint = mapWorldPointToGraphicsPoint(point);
|
||||
|
||||
if (drawPoint == null)
|
||||
{
|
||||
worldPoint.setClickbox(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (worldPoint.isSnapToEdge() && canvasViewArea != currentClip)
|
||||
{
|
||||
graphics.setClip(canvasViewArea);
|
||||
currentClip = canvasViewArea;
|
||||
}
|
||||
else if (!worldPoint.isSnapToEdge() && mapViewArea != currentClip)
|
||||
{
|
||||
graphics.setClip(mapViewArea);
|
||||
currentClip = mapViewArea;
|
||||
}
|
||||
|
||||
if (worldPoint.isSnapToEdge())
|
||||
{
|
||||
if (worldMapRectangle.contains(drawPoint.getX(), drawPoint.getY()))
|
||||
{
|
||||
if (worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
worldPoint.setCurrentlyEdgeSnapped(false);
|
||||
worldPoint.onEdgeUnsnap();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drawPoint = clipToRectangle(drawPoint, worldMapRectangle);
|
||||
if (!worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
worldPoint.setCurrentlyEdgeSnapped(true);
|
||||
worldPoint.onEdgeSnap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int drawX = drawPoint.getX();
|
||||
int drawY = drawPoint.getY();
|
||||
|
||||
if (worldPoint.getImagePoint() == null)
|
||||
{
|
||||
drawX -= image.getWidth() / 2;
|
||||
drawY -= image.getHeight() / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawX -= worldPoint.getImagePoint().getX();
|
||||
drawY -= worldPoint.getImagePoint().getY();
|
||||
}
|
||||
|
||||
graphics.drawImage(image, drawX, drawY, null);
|
||||
Rectangle clickbox = new Rectangle(drawX, drawY, image.getWidth(), image.getHeight());
|
||||
worldPoint.setClickbox(clickbox);
|
||||
|
||||
if (worldPoint.isTooltipVisible())
|
||||
{
|
||||
tooltipPoint = worldPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tooltipPoint != null)
|
||||
{
|
||||
drawTooltip(graphics, tooltipPoint);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the screen coordinates for a WorldPoint on the world map
|
||||
* @param worldPoint WorldPoint to get screen coordinates of
|
||||
* @return Point of screen coordinates of the center of the world point
|
||||
*/
|
||||
public Point mapWorldPointToGraphicsPoint(WorldPoint worldPoint)
|
||||
{
|
||||
RenderOverview ro = client.getRenderOverview();
|
||||
|
||||
if (!ro.getWorldMapData().surfaceContainsPosition(worldPoint.getX(), worldPoint.getY()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Float pixelsPerTile = ro.getWorldMapZoom();
|
||||
|
||||
Widget map = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
if (map != null)
|
||||
{
|
||||
Rectangle worldMapRect = map.getBounds();
|
||||
|
||||
int widthInTiles = (int) Math.ceil(worldMapRect.getWidth() / pixelsPerTile);
|
||||
int heightInTiles = (int) Math.ceil(worldMapRect.getHeight() / pixelsPerTile);
|
||||
|
||||
Point worldMapPosition = ro.getWorldMapPosition();
|
||||
|
||||
//Offset in tiles from anchor sides
|
||||
int yTileMax = worldMapPosition.getY() - heightInTiles / 2;
|
||||
int yTileOffset = (yTileMax - worldPoint.getY() - 1) * -1;
|
||||
int xTileOffset = worldPoint.getX() + widthInTiles / 2 - worldMapPosition.getX();
|
||||
|
||||
int xGraphDiff = ((int) (xTileOffset * pixelsPerTile));
|
||||
int yGraphDiff = (int) (yTileOffset * pixelsPerTile);
|
||||
|
||||
//Center on tile.
|
||||
yGraphDiff -= pixelsPerTile - Math.ceil(pixelsPerTile / 2);
|
||||
xGraphDiff += pixelsPerTile - Math.ceil(pixelsPerTile / 2);
|
||||
|
||||
yGraphDiff = worldMapRect.height - yGraphDiff;
|
||||
yGraphDiff += (int) worldMapRect.getY();
|
||||
xGraphDiff += (int) worldMapRect.getX();
|
||||
|
||||
return new Point(xGraphDiff, yGraphDiff);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a clip area which excludes the area of widgets which overlay the world map.
|
||||
*
|
||||
* @param baseRectangle The base area to clip from
|
||||
* @return An {@link Area} representing <code>baseRectangle</code>, with the area
|
||||
* of visible widgets overlaying the world map clipped from it.
|
||||
*/
|
||||
private Area getWorldMapClipArea(Rectangle baseRectangle)
|
||||
{
|
||||
final Widget overview = client.getWidget(WidgetInfo.WORLD_MAP_OVERVIEW_MAP);
|
||||
final Widget surfaceSelector = client.getWidget(WidgetInfo.WORLD_MAP_SURFACE_SELECTOR);
|
||||
|
||||
Area clipArea = new Area(baseRectangle);
|
||||
|
||||
if (overview != null && !overview.isHidden())
|
||||
{
|
||||
clipArea.subtract(new Area(overview.getBounds()));
|
||||
}
|
||||
|
||||
if (surfaceSelector != null && !surfaceSelector.isHidden())
|
||||
{
|
||||
clipArea.subtract(new Area(surfaceSelector.getBounds()));
|
||||
}
|
||||
|
||||
return clipArea;
|
||||
}
|
||||
|
||||
private void drawTooltip(Graphics2D graphics, WorldMapPoint worldPoint)
|
||||
{
|
||||
String tooltip = worldPoint.getTooltip();
|
||||
Point drawPoint = mapWorldPointToGraphicsPoint(worldPoint.getWorldPoint());
|
||||
if (tooltip == null || tooltip.length() <= 0 || drawPoint == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawPoint = new Point(drawPoint.getX() + TOOLTIP_OFFSET_WIDTH, drawPoint.getY() + TOOLTIP_OFFSET_HEIGHT);
|
||||
|
||||
graphics.setClip(client.getCanvas().getBounds());
|
||||
graphics.setColor(JagexColors.TOOLTIP_BACKGROUND);
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
FontMetrics fm = graphics.getFontMetrics();
|
||||
int width = fm.stringWidth(tooltip);
|
||||
int height = fm.getHeight();
|
||||
|
||||
Rectangle tooltipRect = new Rectangle(drawPoint.getX() - TOOLTIP_PADDING_WIDTH, drawPoint.getY() - TOOLTIP_PADDING_HEIGHT, width + TOOLTIP_PADDING_WIDTH * 2, height + TOOLTIP_PADDING_HEIGHT * 2);
|
||||
graphics.fillRect((int) tooltipRect.getX(), (int) tooltipRect.getY(), (int) tooltipRect.getWidth(), (int) tooltipRect.getHeight());
|
||||
|
||||
graphics.setColor(JagexColors.TOOLTIP_BORDER);
|
||||
graphics.drawRect((int) tooltipRect.getX(), (int) tooltipRect.getY(), (int) tooltipRect.getWidth(), (int) tooltipRect.getHeight());
|
||||
graphics.setColor(JagexColors.TOOLTIP_TEXT);
|
||||
graphics.drawString(tooltip, drawPoint.getX(), drawPoint.getY() + height);
|
||||
}
|
||||
|
||||
private Point clipToRectangle(Point drawPoint, Rectangle mapDisplayRectangle)
|
||||
{
|
||||
int clippedX = drawPoint.getX();
|
||||
|
||||
if (drawPoint.getX() < mapDisplayRectangle.getX())
|
||||
{
|
||||
clippedX = (int) mapDisplayRectangle.getX();
|
||||
}
|
||||
|
||||
if (drawPoint.getX() > mapDisplayRectangle.getX() + mapDisplayRectangle.getWidth())
|
||||
{
|
||||
clippedX = (int) (mapDisplayRectangle.getX() + mapDisplayRectangle.getWidth());
|
||||
}
|
||||
|
||||
int clippedY = drawPoint.getY();
|
||||
|
||||
if (drawPoint.getY() < mapDisplayRectangle.getY())
|
||||
{
|
||||
clippedY = (int) mapDisplayRectangle.getY();
|
||||
}
|
||||
|
||||
if (drawPoint.getY() > mapDisplayRectangle.getY() + mapDisplayRectangle.getHeight())
|
||||
{
|
||||
clippedY = (int) (mapDisplayRectangle.getY() + mapDisplayRectangle.getHeight());
|
||||
}
|
||||
|
||||
return new Point(clippedX, clippedY);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.ui.overlay.worldmap;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
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.input.MouseManager;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
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;
|
||||
|
||||
@Singleton
|
||||
public class WorldMapOverlay extends Overlay
|
||||
{
|
||||
private static final int TOOLTIP_OFFSET_HEIGHT = 25;
|
||||
private static final int TOOLTIP_OFFSET_WIDTH = 5;
|
||||
private static final int TOOLTIP_PADDING_HEIGHT = 1;
|
||||
private static final int TOOLTIP_PADDING_WIDTH = 2;
|
||||
|
||||
private final WorldMapPointManager worldMapPointManager;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private WorldMapOverlay(
|
||||
Client client,
|
||||
WorldMapPointManager worldMapPointManager,
|
||||
MouseManager mouseManager,
|
||||
WorldMapOverlayMouseListener worldMapOverlayMouseListener)
|
||||
{
|
||||
this.client = client;
|
||||
this.worldMapPointManager = worldMapPointManager;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ABOVE_MAP);
|
||||
mouseManager.registerMouseListener(worldMapOverlayMouseListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final List<WorldMapPoint> points = worldMapPointManager.getWorldMapPoints();
|
||||
|
||||
if (points.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Widget widget = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
if (widget == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Rectangle worldMapRectangle = widget.getBounds();
|
||||
final Area mapViewArea = getWorldMapClipArea(worldMapRectangle);
|
||||
final Rectangle canvasBounds = client.getCanvas().getBounds();
|
||||
// in fixed, the bounds are offset by the size of the black borders outside the canvas
|
||||
canvasBounds.setLocation(0, 0);
|
||||
final Area canvasViewArea = getWorldMapClipArea(canvasBounds);
|
||||
Area currentClip = null;
|
||||
|
||||
WorldMapPoint tooltipPoint = null;
|
||||
|
||||
for (WorldMapPoint worldPoint : points)
|
||||
{
|
||||
BufferedImage image = worldPoint.getImage();
|
||||
WorldPoint point = worldPoint.getWorldPoint();
|
||||
|
||||
if (image != null && point != null)
|
||||
{
|
||||
Point drawPoint = mapWorldPointToGraphicsPoint(point);
|
||||
|
||||
if (drawPoint == null)
|
||||
{
|
||||
worldPoint.setClickbox(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (worldPoint.isSnapToEdge() && canvasViewArea != currentClip)
|
||||
{
|
||||
graphics.setClip(canvasViewArea);
|
||||
currentClip = canvasViewArea;
|
||||
}
|
||||
else if (!worldPoint.isSnapToEdge() && mapViewArea != currentClip)
|
||||
{
|
||||
graphics.setClip(mapViewArea);
|
||||
currentClip = mapViewArea;
|
||||
}
|
||||
|
||||
if (worldPoint.isSnapToEdge())
|
||||
{
|
||||
if (worldMapRectangle.contains(drawPoint.getX(), drawPoint.getY()))
|
||||
{
|
||||
if (worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
worldPoint.setCurrentlyEdgeSnapped(false);
|
||||
worldPoint.onEdgeUnsnap();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drawPoint = clipToRectangle(drawPoint, worldMapRectangle);
|
||||
if (!worldPoint.isCurrentlyEdgeSnapped())
|
||||
{
|
||||
worldPoint.setCurrentlyEdgeSnapped(true);
|
||||
worldPoint.onEdgeSnap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int drawX = drawPoint.getX();
|
||||
int drawY = drawPoint.getY();
|
||||
|
||||
if (worldPoint.getImagePoint() == null)
|
||||
{
|
||||
drawX -= image.getWidth() / 2;
|
||||
drawY -= image.getHeight() / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawX -= worldPoint.getImagePoint().getX();
|
||||
drawY -= worldPoint.getImagePoint().getY();
|
||||
}
|
||||
|
||||
graphics.drawImage(image, drawX, drawY, null);
|
||||
Rectangle clickbox = new Rectangle(drawX, drawY, image.getWidth(), image.getHeight());
|
||||
worldPoint.setClickbox(clickbox);
|
||||
|
||||
if (worldPoint.isTooltipVisible())
|
||||
{
|
||||
tooltipPoint = worldPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tooltipPoint != null)
|
||||
{
|
||||
drawTooltip(graphics, tooltipPoint);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the screen coordinates for a WorldPoint on the world map
|
||||
*
|
||||
* @param worldPoint WorldPoint to get screen coordinates of
|
||||
* @return Point of screen coordinates of the center of the world point
|
||||
*/
|
||||
public Point mapWorldPointToGraphicsPoint(WorldPoint worldPoint)
|
||||
{
|
||||
RenderOverview ro = client.getRenderOverview();
|
||||
|
||||
if (!ro.getWorldMapData().surfaceContainsPosition(worldPoint.getX(), worldPoint.getY()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Float pixelsPerTile = ro.getWorldMapZoom();
|
||||
|
||||
Widget map = client.getWidget(WidgetInfo.WORLD_MAP_VIEW);
|
||||
if (map != null)
|
||||
{
|
||||
Rectangle worldMapRect = map.getBounds();
|
||||
|
||||
int widthInTiles = (int) Math.ceil(worldMapRect.getWidth() / pixelsPerTile);
|
||||
int heightInTiles = (int) Math.ceil(worldMapRect.getHeight() / pixelsPerTile);
|
||||
|
||||
Point worldMapPosition = ro.getWorldMapPosition();
|
||||
|
||||
//Offset in tiles from anchor sides
|
||||
int yTileMax = worldMapPosition.getY() - heightInTiles / 2;
|
||||
int yTileOffset = (yTileMax - worldPoint.getY() - 1) * -1;
|
||||
int xTileOffset = worldPoint.getX() + widthInTiles / 2 - worldMapPosition.getX();
|
||||
|
||||
int xGraphDiff = ((int) (xTileOffset * pixelsPerTile));
|
||||
int yGraphDiff = (int) (yTileOffset * pixelsPerTile);
|
||||
|
||||
//Center on tile.
|
||||
yGraphDiff -= pixelsPerTile - Math.ceil(pixelsPerTile / 2);
|
||||
xGraphDiff += pixelsPerTile - Math.ceil(pixelsPerTile / 2);
|
||||
|
||||
yGraphDiff = worldMapRect.height - yGraphDiff;
|
||||
yGraphDiff += (int) worldMapRect.getY();
|
||||
xGraphDiff += (int) worldMapRect.getX();
|
||||
|
||||
return new Point(xGraphDiff, yGraphDiff);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a clip area which excludes the area of widgets which overlay the world map.
|
||||
*
|
||||
* @param baseRectangle The base area to clip from
|
||||
* @return An {@link Area} representing <code>baseRectangle</code>, with the area
|
||||
* of visible widgets overlaying the world map clipped from it.
|
||||
*/
|
||||
private Area getWorldMapClipArea(Rectangle baseRectangle)
|
||||
{
|
||||
final Widget overview = client.getWidget(WidgetInfo.WORLD_MAP_OVERVIEW_MAP);
|
||||
final Widget surfaceSelector = client.getWidget(WidgetInfo.WORLD_MAP_SURFACE_SELECTOR);
|
||||
|
||||
Area clipArea = new Area(baseRectangle);
|
||||
|
||||
if (overview != null && !overview.isHidden())
|
||||
{
|
||||
clipArea.subtract(new Area(overview.getBounds()));
|
||||
}
|
||||
|
||||
if (surfaceSelector != null && !surfaceSelector.isHidden())
|
||||
{
|
||||
clipArea.subtract(new Area(surfaceSelector.getBounds()));
|
||||
}
|
||||
|
||||
return clipArea;
|
||||
}
|
||||
|
||||
private void drawTooltip(Graphics2D graphics, WorldMapPoint worldPoint)
|
||||
{
|
||||
String tooltip = worldPoint.getTooltip();
|
||||
Point drawPoint = mapWorldPointToGraphicsPoint(worldPoint.getWorldPoint());
|
||||
if (tooltip == null || tooltip.length() <= 0 || drawPoint == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawPoint = new Point(drawPoint.getX() + TOOLTIP_OFFSET_WIDTH, drawPoint.getY() + TOOLTIP_OFFSET_HEIGHT);
|
||||
|
||||
graphics.setClip(client.getCanvas().getBounds());
|
||||
graphics.setColor(JagexColors.TOOLTIP_BACKGROUND);
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
FontMetrics fm = graphics.getFontMetrics();
|
||||
int width = fm.stringWidth(tooltip);
|
||||
int height = fm.getHeight();
|
||||
|
||||
Rectangle tooltipRect = new Rectangle(drawPoint.getX() - TOOLTIP_PADDING_WIDTH, drawPoint.getY() - TOOLTIP_PADDING_HEIGHT, width + TOOLTIP_PADDING_WIDTH * 2, height + TOOLTIP_PADDING_HEIGHT * 2);
|
||||
graphics.fillRect((int) tooltipRect.getX(), (int) tooltipRect.getY(), (int) tooltipRect.getWidth(), (int) tooltipRect.getHeight());
|
||||
|
||||
graphics.setColor(JagexColors.TOOLTIP_BORDER);
|
||||
graphics.drawRect((int) tooltipRect.getX(), (int) tooltipRect.getY(), (int) tooltipRect.getWidth(), (int) tooltipRect.getHeight());
|
||||
graphics.setColor(JagexColors.TOOLTIP_TEXT);
|
||||
graphics.drawString(tooltip, drawPoint.getX(), drawPoint.getY() + height);
|
||||
}
|
||||
|
||||
private Point clipToRectangle(Point drawPoint, Rectangle mapDisplayRectangle)
|
||||
{
|
||||
int clippedX = drawPoint.getX();
|
||||
|
||||
if (drawPoint.getX() < mapDisplayRectangle.getX())
|
||||
{
|
||||
clippedX = (int) mapDisplayRectangle.getX();
|
||||
}
|
||||
|
||||
if (drawPoint.getX() > mapDisplayRectangle.getX() + mapDisplayRectangle.getWidth())
|
||||
{
|
||||
clippedX = (int) (mapDisplayRectangle.getX() + mapDisplayRectangle.getWidth());
|
||||
}
|
||||
|
||||
int clippedY = drawPoint.getY();
|
||||
|
||||
if (drawPoint.getY() < mapDisplayRectangle.getY())
|
||||
{
|
||||
clippedY = (int) mapDisplayRectangle.getY();
|
||||
}
|
||||
|
||||
if (drawPoint.getY() > mapDisplayRectangle.getY() + mapDisplayRectangle.getHeight())
|
||||
{
|
||||
clippedY = (int) (mapDisplayRectangle.getY() + mapDisplayRectangle.getHeight());
|
||||
}
|
||||
|
||||
return new Point(clippedX, clippedY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,242 +1,243 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.awt.Color;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class ColorUtil
|
||||
{
|
||||
public static final int MAX_RGB_VALUE = 255;
|
||||
public static final int MIN_RGB_VALUE = 0;
|
||||
private static final String OPENING_COLOR_TAG_START = "<col=";
|
||||
private static final String OPENING_COLOR_TAG_END = ">";
|
||||
private static final String CLOSING_COLOR_TAG = "</col>";
|
||||
private final static Pattern ALPHA_HEX_PATTERN = Pattern.compile("^(#|0x)?[0-9a-fA-F]{7,8}");
|
||||
private final static Pattern HEX_PATTERN = Pattern.compile("^(#|0x)?[0-9a-fA-F]{1,8}");
|
||||
|
||||
/**
|
||||
* Creates a color tag from the given color.
|
||||
*
|
||||
* @param color The Color to create a tag from.
|
||||
* @return A string of the color tag for the given color.
|
||||
*/
|
||||
public static String colorTag(Color color)
|
||||
{
|
||||
return OPENING_COLOR_TAG_START + colorToHexCode(color) + OPENING_COLOR_TAG_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the given str with an opening color tag of the given color.
|
||||
*
|
||||
* @param str The string to be colorized.
|
||||
* @param color The color to be used in the color tag.
|
||||
* @return The passed str with a prepended color tag.
|
||||
*/
|
||||
public static String prependColorTag(final String str, final Color color)
|
||||
{
|
||||
return colorTag(color) + str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given str with a color tag of the given color.
|
||||
*
|
||||
* @param str The string to be colorized.
|
||||
* @param color The color to be used in the color tag.
|
||||
* @return The passed str wrapped with opening and closing color tags.
|
||||
*/
|
||||
public static String wrapWithColorTag(final String str, final Color color)
|
||||
{
|
||||
return prependColorTag(str, color) + CLOSING_COLOR_TAG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given color to it's hexidecimal equivalent.
|
||||
*
|
||||
* @param color Color to get hexidecimal string from.
|
||||
* @return Hexidecimal string representing the given color, in the form "#abcdef".
|
||||
*/
|
||||
public static String toHexColor(final Color color)
|
||||
{
|
||||
return "#" + colorToHexCode(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between colors a and b by t.
|
||||
*
|
||||
* @param a first color
|
||||
* @param b second color
|
||||
* @param t factor
|
||||
* @return interpolated color
|
||||
*/
|
||||
public static Color colorLerp(final Color a, final Color b, final double t)
|
||||
{
|
||||
final double r1 = a.getRed();
|
||||
final double r2 = b.getRed();
|
||||
final double g1 = a.getGreen();
|
||||
final double g2 = b.getGreen();
|
||||
final double b1 = a.getBlue();
|
||||
final double b2 = b.getBlue();
|
||||
|
||||
return new Color(
|
||||
(int) Math.round(r1 + (t * (r2 - r1))),
|
||||
(int) Math.round(g1 + (t * (g2 - g1))),
|
||||
(int) Math.round(b1 + (t * (b2 - b1)))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the RGB hex color code of the passed color.
|
||||
*
|
||||
* @param color The color to get a hex code from.
|
||||
* @return A lower-cased string of the RGB hex code of color.
|
||||
*/
|
||||
public static String colorToHexCode(final Color color)
|
||||
{
|
||||
return String.format("%06x", color.getRGB() & 0xFFFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ARGB hex color code of the passed color.
|
||||
*
|
||||
* @param color The color to get a hex code from.
|
||||
* @return A lower-cased string of the ARGB hex code of color.
|
||||
*/
|
||||
public static String colorToAlphaHexCode(final Color color)
|
||||
{
|
||||
return String.format("%08x", color.getRGB());
|
||||
}
|
||||
|
||||
static boolean isFullyTransparent(final Color color)
|
||||
{
|
||||
return color.getAlpha() == 0;
|
||||
}
|
||||
|
||||
static boolean isNotFullyTransparent(final Color color)
|
||||
{
|
||||
return !isFullyTransparent(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the passed hex string is an alpha hex color.
|
||||
*
|
||||
* @param hex The hex to test.
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isAlphaHex(String hex)
|
||||
{
|
||||
return ALPHA_HEX_PATTERN.matcher(hex).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the passed hex string is a hex color.
|
||||
*
|
||||
* @param hex The hex to test.
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isHex(String hex)
|
||||
{
|
||||
return HEX_PATTERN.matcher(hex).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits an int to the rgba value range (0-255)
|
||||
*
|
||||
* @param value The value for the r, g, b, or a.
|
||||
* @return An int between 0 - 255.
|
||||
*/
|
||||
public static int constrainValue(int value)
|
||||
{
|
||||
return Ints.constrainToRange(value, MIN_RGB_VALUE, MAX_RGB_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Color from the passed int string.
|
||||
*
|
||||
* @param string The int to get a Color object from.
|
||||
* @return A Color of the int of color.
|
||||
*/
|
||||
public static Color fromString(String string)
|
||||
{
|
||||
try
|
||||
{
|
||||
int i = Integer.decode(string);
|
||||
return new Color(i, true);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Color from the passed hex string.
|
||||
*
|
||||
* @param hex The hex to get a Color object from.
|
||||
* @return A Color of the hex code of color.
|
||||
*/
|
||||
public static Color fromHex(String hex)
|
||||
{
|
||||
if (!hex.startsWith("#") && !hex.startsWith("0x"))
|
||||
{
|
||||
hex = "#" + hex;
|
||||
}
|
||||
|
||||
if ((hex.length() <= 7 && hex.startsWith("#")) || (hex.length() <= 8 && hex.startsWith("0x")))
|
||||
{
|
||||
try
|
||||
{
|
||||
return Color.decode(hex);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new Color(Long.decode(hex).intValue(), true);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates color from passed object hash code
|
||||
* @param object object with hashCode
|
||||
* @return color
|
||||
*/
|
||||
public static Color fromObject(@Nonnull final Object object)
|
||||
{
|
||||
int i = object.hashCode();
|
||||
float h = (i % 360) / 360f;
|
||||
return Color.getHSBColor(h, 1, 1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.awt.Color;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class ColorUtil
|
||||
{
|
||||
public static final int MAX_RGB_VALUE = 255;
|
||||
public static final int MIN_RGB_VALUE = 0;
|
||||
private static final String OPENING_COLOR_TAG_START = "<col=";
|
||||
private static final String OPENING_COLOR_TAG_END = ">";
|
||||
private static final String CLOSING_COLOR_TAG = "</col>";
|
||||
private final static Pattern ALPHA_HEX_PATTERN = Pattern.compile("^(#|0x)?[0-9a-fA-F]{7,8}");
|
||||
private final static Pattern HEX_PATTERN = Pattern.compile("^(#|0x)?[0-9a-fA-F]{1,8}");
|
||||
|
||||
/**
|
||||
* Creates a color tag from the given color.
|
||||
*
|
||||
* @param color The Color to create a tag from.
|
||||
* @return A string of the color tag for the given color.
|
||||
*/
|
||||
public static String colorTag(Color color)
|
||||
{
|
||||
return OPENING_COLOR_TAG_START + colorToHexCode(color) + OPENING_COLOR_TAG_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the given str with an opening color tag of the given color.
|
||||
*
|
||||
* @param str The string to be colorized.
|
||||
* @param color The color to be used in the color tag.
|
||||
* @return The passed str with a prepended color tag.
|
||||
*/
|
||||
public static String prependColorTag(final String str, final Color color)
|
||||
{
|
||||
return colorTag(color) + str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given str with a color tag of the given color.
|
||||
*
|
||||
* @param str The string to be colorized.
|
||||
* @param color The color to be used in the color tag.
|
||||
* @return The passed str wrapped with opening and closing color tags.
|
||||
*/
|
||||
public static String wrapWithColorTag(final String str, final Color color)
|
||||
{
|
||||
return prependColorTag(str, color) + CLOSING_COLOR_TAG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given color to it's hexidecimal equivalent.
|
||||
*
|
||||
* @param color Color to get hexidecimal string from.
|
||||
* @return Hexidecimal string representing the given color, in the form "#abcdef".
|
||||
*/
|
||||
public static String toHexColor(final Color color)
|
||||
{
|
||||
return "#" + colorToHexCode(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between colors a and b by t.
|
||||
*
|
||||
* @param a first color
|
||||
* @param b second color
|
||||
* @param t factor
|
||||
* @return interpolated color
|
||||
*/
|
||||
public static Color colorLerp(final Color a, final Color b, final double t)
|
||||
{
|
||||
final double r1 = a.getRed();
|
||||
final double r2 = b.getRed();
|
||||
final double g1 = a.getGreen();
|
||||
final double g2 = b.getGreen();
|
||||
final double b1 = a.getBlue();
|
||||
final double b2 = b.getBlue();
|
||||
|
||||
return new Color(
|
||||
(int) Math.round(r1 + (t * (r2 - r1))),
|
||||
(int) Math.round(g1 + (t * (g2 - g1))),
|
||||
(int) Math.round(b1 + (t * (b2 - b1)))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the RGB hex color code of the passed color.
|
||||
*
|
||||
* @param color The color to get a hex code from.
|
||||
* @return A lower-cased string of the RGB hex code of color.
|
||||
*/
|
||||
public static String colorToHexCode(final Color color)
|
||||
{
|
||||
return String.format("%06x", color.getRGB() & 0xFFFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ARGB hex color code of the passed color.
|
||||
*
|
||||
* @param color The color to get a hex code from.
|
||||
* @return A lower-cased string of the ARGB hex code of color.
|
||||
*/
|
||||
public static String colorToAlphaHexCode(final Color color)
|
||||
{
|
||||
return String.format("%08x", color.getRGB());
|
||||
}
|
||||
|
||||
static boolean isFullyTransparent(final Color color)
|
||||
{
|
||||
return color.getAlpha() == 0;
|
||||
}
|
||||
|
||||
static boolean isNotFullyTransparent(final Color color)
|
||||
{
|
||||
return !isFullyTransparent(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the passed hex string is an alpha hex color.
|
||||
*
|
||||
* @param hex The hex to test.
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isAlphaHex(String hex)
|
||||
{
|
||||
return ALPHA_HEX_PATTERN.matcher(hex).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the passed hex string is a hex color.
|
||||
*
|
||||
* @param hex The hex to test.
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isHex(String hex)
|
||||
{
|
||||
return HEX_PATTERN.matcher(hex).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits an int to the rgba value range (0-255)
|
||||
*
|
||||
* @param value The value for the r, g, b, or a.
|
||||
* @return An int between 0 - 255.
|
||||
*/
|
||||
public static int constrainValue(int value)
|
||||
{
|
||||
return Ints.constrainToRange(value, MIN_RGB_VALUE, MAX_RGB_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Color from the passed int string.
|
||||
*
|
||||
* @param string The int to get a Color object from.
|
||||
* @return A Color of the int of color.
|
||||
*/
|
||||
public static Color fromString(String string)
|
||||
{
|
||||
try
|
||||
{
|
||||
int i = Integer.decode(string);
|
||||
return new Color(i, true);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Color from the passed hex string.
|
||||
*
|
||||
* @param hex The hex to get a Color object from.
|
||||
* @return A Color of the hex code of color.
|
||||
*/
|
||||
public static Color fromHex(String hex)
|
||||
{
|
||||
if (!hex.startsWith("#") && !hex.startsWith("0x"))
|
||||
{
|
||||
hex = "#" + hex;
|
||||
}
|
||||
|
||||
if ((hex.length() <= 7 && hex.startsWith("#")) || (hex.length() <= 8 && hex.startsWith("0x")))
|
||||
{
|
||||
try
|
||||
{
|
||||
return Color.decode(hex);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new Color(Long.decode(hex).intValue(), true);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates color from passed object hash code
|
||||
*
|
||||
* @param object object with hashCode
|
||||
* @return color
|
||||
*/
|
||||
public static Color fromObject(@Nonnull final Object object)
|
||||
{
|
||||
int i = object.hashCode();
|
||||
float h = (i % 360) / 360f;
|
||||
return Color.getHSBColor(h, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.GrayFilter;
|
||||
import java.util.function.Predicate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
@@ -56,7 +56,7 @@ public class ImageUtil
|
||||
* Creates a {@link BufferedImage} from an {@link Image}.
|
||||
*
|
||||
* @param image An Image to be converted to a BufferedImage.
|
||||
* @return A BufferedImage instance of the same given image.
|
||||
* @return A BufferedImage instance of the same given image.
|
||||
*/
|
||||
public static BufferedImage bufferedImageFromImage(final Image image)
|
||||
{
|
||||
@@ -78,7 +78,7 @@ public class ImageUtil
|
||||
* @param image The image to be darkened or brightened.
|
||||
* @param offset A signed 8-bit integer value to brighten or darken the image with.
|
||||
* Values above 0 will brighten, and values below 0 will darken.
|
||||
* @return The given image with its brightness adjusted by the given offset.
|
||||
* @return The given image with its brightness adjusted by the given offset.
|
||||
*/
|
||||
public static BufferedImage grayscaleOffset(final BufferedImage image, final int offset)
|
||||
{
|
||||
@@ -104,7 +104,7 @@ public class ImageUtil
|
||||
* @param image The image to be darkened or brightened.
|
||||
* @param percentage The ratio to darken or brighten the given image.
|
||||
* Values above 1 will brighten, and values below 1 will darken.
|
||||
* @return The given image with its brightness scaled by the given percentage.
|
||||
* @return The given image with its brightness scaled by the given percentage.
|
||||
*/
|
||||
public static BufferedImage grayscaleOffset(final BufferedImage image, final float percentage)
|
||||
{
|
||||
@@ -130,7 +130,7 @@ public class ImageUtil
|
||||
* @param offset A signed 8-bit integer value to modify the image's alpha component with.
|
||||
* Values above 0 will increase transparency, and values below 0 will decrease
|
||||
* transparency.
|
||||
* @return The given image with its alpha component adjusted by the given offset.
|
||||
* @return The given image with its alpha component adjusted by the given offset.
|
||||
*/
|
||||
public static BufferedImage alphaOffset(final BufferedImage image, final int offset)
|
||||
{
|
||||
@@ -152,7 +152,7 @@ public class ImageUtil
|
||||
* @param percentage The ratio to modify the image's alpha component with.
|
||||
* Values above 1 will increase transparency, and values below 1 will decrease
|
||||
* transparency.
|
||||
* @return The given image with its alpha component scaled by the given percentage.
|
||||
* @return The given image with its alpha component scaled by the given percentage.
|
||||
*/
|
||||
public static BufferedImage alphaOffset(final BufferedImage image, final float percentage)
|
||||
{
|
||||
@@ -170,7 +170,7 @@ public class ImageUtil
|
||||
* Creates a grayscale image from the given image.
|
||||
*
|
||||
* @param image The source image to be converted.
|
||||
* @return A copy of the given imnage, with colors converted to grayscale.
|
||||
* @return A copy of the given imnage, with colors converted to grayscale.
|
||||
*/
|
||||
public static BufferedImage grayscaleImage(final BufferedImage image)
|
||||
{
|
||||
@@ -181,8 +181,8 @@ public class ImageUtil
|
||||
/**
|
||||
* Re-size a BufferedImage to the given dimensions.
|
||||
*
|
||||
* @param image the BufferedImage.
|
||||
* @param newWidth The width to set the BufferedImage to.
|
||||
* @param image the BufferedImage.
|
||||
* @param newWidth The width to set the BufferedImage to.
|
||||
* @param newHeight The height to set the BufferedImage to.
|
||||
* @return The BufferedImage with the specified dimensions
|
||||
*/
|
||||
@@ -198,7 +198,7 @@ public class ImageUtil
|
||||
* @param image The image whose canvas should be re-sized.
|
||||
* @param newWidth The width to set the BufferedImage to.
|
||||
* @param newHeight The height to set the BufferedImage to.
|
||||
* @return The BufferedImage centered within canvas of given dimensions.
|
||||
* @return The BufferedImage centered within canvas of given dimensions.
|
||||
*/
|
||||
public static BufferedImage resizeCanvas(final BufferedImage image, final int newWidth, final int newHeight)
|
||||
{
|
||||
@@ -217,7 +217,7 @@ public class ImageUtil
|
||||
*
|
||||
* @param image The image to be rotated.
|
||||
* @param theta The number of radians to rotate the image.
|
||||
* @return The given image, rotated by the given theta.
|
||||
* @return The given image, rotated by the given theta.
|
||||
*/
|
||||
public static BufferedImage rotateImage(final BufferedImage image, final double theta)
|
||||
{
|
||||
@@ -233,7 +233,7 @@ public class ImageUtil
|
||||
* @param image The image to be flipped.
|
||||
* @param horizontal Whether the image should be flipped horizontally.
|
||||
* @param vertical Whether the image should be flipped vertically.
|
||||
* @return The given image, flipped horizontally and/or vertically.
|
||||
* @return The given image, flipped horizontally and/or vertically.
|
||||
*/
|
||||
public static BufferedImage flipImage(final BufferedImage image, final boolean horizontal, final boolean vertical)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ public class ImageUtil
|
||||
*
|
||||
* @param image The image to be outlined.
|
||||
* @param color The color to use for the outline.
|
||||
* @return The BufferedImage with its edges outlined with the given color.
|
||||
* @return The BufferedImage with its edges outlined with the given color.
|
||||
*/
|
||||
public static BufferedImage outlineImage(final BufferedImage image, final Color color)
|
||||
{
|
||||
@@ -282,7 +282,7 @@ public class ImageUtil
|
||||
* @param image The image to be outlined.
|
||||
* @param color The color to use for the outline.
|
||||
* @param fillCondition The predicate to be consumed by {@link #fillImage(BufferedImage, Color, Predicate) fillImage(BufferedImage, Color, Predicate)}
|
||||
* @return The BufferedImage with its edges outlined with the given color.
|
||||
* @return The BufferedImage with its edges outlined with the given color.
|
||||
*/
|
||||
public static BufferedImage outlineImage(final BufferedImage image, final Color color, final Predicate<Color> fillCondition)
|
||||
{
|
||||
@@ -296,8 +296,8 @@ public class ImageUtil
|
||||
* @param image The image to be outlined.
|
||||
* @param color The color to use for the outline.
|
||||
* @param outlineCorners Whether to draw an outline around corners, or only around edges.
|
||||
* @return The BufferedImage with its edges--and optionally, corners--outlined
|
||||
* with the given color.
|
||||
* @return The BufferedImage with its edges--and optionally, corners--outlined
|
||||
* with the given color.
|
||||
*/
|
||||
public static BufferedImage outlineImage(final BufferedImage image, final Color color, final Boolean outlineCorners)
|
||||
{
|
||||
@@ -312,8 +312,8 @@ public class ImageUtil
|
||||
* @param color The color to use for the outline.
|
||||
* @param fillCondition The predicate to be consumed by {@link #fillImage(BufferedImage, Color, Predicate) fillImage(BufferedImage, Color, Predicate)}
|
||||
* @param outlineCorners Whether to draw an outline around corners, or only around edges.
|
||||
* @return The BufferedImage with its edges--and optionally, corners--outlined
|
||||
* with the given color.
|
||||
* @return The BufferedImage with its edges--and optionally, corners--outlined
|
||||
* with the given color.
|
||||
*/
|
||||
public static BufferedImage outlineImage(final BufferedImage image, final Color color, final Predicate<Color> fillCondition, final Boolean outlineCorners)
|
||||
{
|
||||
@@ -347,7 +347,7 @@ public class ImageUtil
|
||||
*
|
||||
* @param c The class to be referenced for resource path.
|
||||
* @param path The path, relative to the given class.
|
||||
* @return A {@link BufferedImage} of the loaded image resource from the given path.
|
||||
* @return A {@link BufferedImage} of the loaded image resource from the given path.
|
||||
*/
|
||||
public static BufferedImage getResourceStreamFromClass(final Class c, final String path)
|
||||
{
|
||||
@@ -369,7 +369,7 @@ public class ImageUtil
|
||||
*
|
||||
* @param image The image which should have its non-transparent pixels filled.
|
||||
* @param color The color with which to fill pixels.
|
||||
* @return The given image with all non-transparent pixels set to the given color.
|
||||
* @return The given image with all non-transparent pixels set to the given color.
|
||||
*/
|
||||
public static BufferedImage fillImage(final BufferedImage image, final Color color)
|
||||
{
|
||||
@@ -377,14 +377,14 @@ public class ImageUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills pixels of the given image with the given color based on a given fill condition
|
||||
* predicate.
|
||||
* Fills pixels of the given image with the given color based on a given fill condition
|
||||
* predicate.
|
||||
*
|
||||
* @param image The image which should have its non-transparent pixels filled.
|
||||
* @param color The color with which to fill pixels.
|
||||
* @param fillCondition The condition on which to fill pixels with the given color.
|
||||
* @return The given image with all pixels fulfilling the fill condition predicate
|
||||
* set to the given color.
|
||||
* @return The given image with all pixels fulfilling the fill condition predicate
|
||||
* set to the given color.
|
||||
*/
|
||||
static BufferedImage fillImage(final BufferedImage image, final Color color, final Predicate<Color> fillCondition)
|
||||
{
|
||||
@@ -411,7 +411,7 @@ public class ImageUtil
|
||||
* @param image The image to be adjusted.
|
||||
* @param scales An array of scale operations to be performed on the image's color components.
|
||||
* @param offsets An array of offset operations to be performed on the image's color components.
|
||||
* @return The modified image after applying the given adjustments.
|
||||
* @return The modified image after applying the given adjustments.
|
||||
*/
|
||||
private static BufferedImage offset(final BufferedImage image, final float[] scales, final float[] offsets)
|
||||
{
|
||||
@@ -421,9 +421,10 @@ public class ImageUtil
|
||||
|
||||
/**
|
||||
* Converts the buffered image into a sprite image and returns it
|
||||
*
|
||||
* @param image The image to be converted
|
||||
* @param client Current client instance
|
||||
* @return The buffered image as a sprite image
|
||||
* @return The buffered image as a sprite image
|
||||
*/
|
||||
public static SpritePixels getImageSpritePixels(BufferedImage image, Client client)
|
||||
{
|
||||
@@ -455,12 +456,12 @@ public class ImageUtil
|
||||
|
||||
/**
|
||||
* Converts an image into an {@code IndexedSprite} instance.
|
||||
*
|
||||
* <p>
|
||||
* The passed in image can only have at max 255 different colors.
|
||||
*
|
||||
* @param image The image to be converted
|
||||
* @param client Current client instance
|
||||
* @return The image as an {@code IndexedSprite}
|
||||
* @return The image as an {@code IndexedSprite}
|
||||
*/
|
||||
public static IndexedSprite getImageIndexedSprite(BufferedImage image, Client client)
|
||||
{
|
||||
|
||||
@@ -1,150 +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.util;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Utility class used for browser navigation
|
||||
*/
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class LinkBrowser
|
||||
{
|
||||
private static boolean shouldAttemptXdg = OSType.getOSType() == OSType.Linux;
|
||||
|
||||
/**
|
||||
* Tries to navigate to specified URL in browser. In case operation fails, displays message box with message
|
||||
* and copies link to clipboard to navigate to.
|
||||
* @param url url to open
|
||||
* @return true if operation was successful
|
||||
*/
|
||||
public static boolean browse(final String url)
|
||||
{
|
||||
if (Strings.isNullOrEmpty(url))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attemptDesktopBrowse(url))
|
||||
{
|
||||
log.debug("Opened browser through Desktop#browse to {}", url);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shouldAttemptXdg && attemptXdgOpen(url))
|
||||
{
|
||||
log.debug("Opened browser through xdg-open to {}", url);
|
||||
return true;
|
||||
}
|
||||
|
||||
showMessageBox("Unable to open link. Press 'OK' and link will be copied to your clipboard.", url);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean attemptXdgOpen(String url)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Process exec = Runtime.getRuntime().exec(new String[]{"xdg-open", url});
|
||||
exec.waitFor();
|
||||
|
||||
final int ret = exec.exitValue();
|
||||
if (ret == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
log.warn("xdg-open {} returned with error code {}", url, ret);
|
||||
return false;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// xdg-open not found
|
||||
shouldAttemptXdg = false;
|
||||
return false;
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
log.warn("Interrupted while waiting for xdg-open {} to execute", url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean attemptDesktopBrowse(String url)
|
||||
{
|
||||
if (!Desktop.isDesktopSupported())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Desktop desktop = Desktop.getDesktop();
|
||||
|
||||
if (!desktop.isSupported(Desktop.Action.BROWSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
desktop.browse(new URI(url));
|
||||
return true;
|
||||
}
|
||||
catch (IOException | URISyntaxException ex)
|
||||
{
|
||||
log.warn("Failed to open Desktop#browser {}", url, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open swing message box with specified message and copy data to clipboard
|
||||
* @param message message to show
|
||||
*/
|
||||
private static void showMessageBox(final String message, final String data)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
final int result = JOptionPane.showConfirmDialog(null, message, "Message",
|
||||
JOptionPane.OK_CANCEL_OPTION);
|
||||
|
||||
if (result == JOptionPane.OK_OPTION)
|
||||
{
|
||||
final StringSelection stringSelection = new StringSelection(data);
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Utility class used for browser navigation
|
||||
*/
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class LinkBrowser
|
||||
{
|
||||
private static boolean shouldAttemptXdg = OSType.getOSType() == OSType.Linux;
|
||||
|
||||
/**
|
||||
* Tries to navigate to specified URL in browser. In case operation fails, displays message box with message
|
||||
* and copies link to clipboard to navigate to.
|
||||
*
|
||||
* @param url url to open
|
||||
* @return true if operation was successful
|
||||
*/
|
||||
public static boolean browse(final String url)
|
||||
{
|
||||
if (Strings.isNullOrEmpty(url))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attemptDesktopBrowse(url))
|
||||
{
|
||||
log.debug("Opened browser through Desktop#browse to {}", url);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shouldAttemptXdg && attemptXdgOpen(url))
|
||||
{
|
||||
log.debug("Opened browser through xdg-open to {}", url);
|
||||
return true;
|
||||
}
|
||||
|
||||
showMessageBox("Unable to open link. Press 'OK' and link will be copied to your clipboard.", url);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean attemptXdgOpen(String url)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Process exec = Runtime.getRuntime().exec(new String[]{"xdg-open", url});
|
||||
exec.waitFor();
|
||||
|
||||
final int ret = exec.exitValue();
|
||||
if (ret == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
log.warn("xdg-open {} returned with error code {}", url, ret);
|
||||
return false;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// xdg-open not found
|
||||
shouldAttemptXdg = false;
|
||||
return false;
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
log.warn("Interrupted while waiting for xdg-open {} to execute", url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean attemptDesktopBrowse(String url)
|
||||
{
|
||||
if (!Desktop.isDesktopSupported())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Desktop desktop = Desktop.getDesktop();
|
||||
|
||||
if (!desktop.isSupported(Desktop.Action.BROWSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
desktop.browse(new URI(url));
|
||||
return true;
|
||||
}
|
||||
catch (IOException | URISyntaxException ex)
|
||||
{
|
||||
log.warn("Failed to open Desktop#browser {}", url, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open swing message box with specified message and copy data to clipboard
|
||||
*
|
||||
* @param message message to show
|
||||
*/
|
||||
private static void showMessageBox(final String message, final String data)
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
final int result = JOptionPane.showConfirmDialog(null, message, "Message",
|
||||
JOptionPane.OK_CANCEL_OPTION);
|
||||
|
||||
if (result == JOptionPane.OK_OPTION)
|
||||
{
|
||||
final StringSelection stringSelection = new StringSelection(data);
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,8 +109,8 @@ public class MenuUtil
|
||||
private static MenuEntry findOptionTarget(Stream<MenuEntry> stream, String option, String target)
|
||||
{
|
||||
Optional<MenuEntry> maybeEntry = stream.filter(e -> Text.standardize(e.getOption()).equals(option) &&
|
||||
Text.standardize(e.getTarget()).equals(target))
|
||||
/* autism */ .findFirst();
|
||||
Text.standardize(e.getTarget()).equals(target))
|
||||
/* autism */.findFirst();
|
||||
|
||||
return maybeEntry.orElse(null);
|
||||
}
|
||||
@@ -118,8 +118,8 @@ public class MenuUtil
|
||||
private static MenuEntry findOptionTargetLenient(Stream<MenuEntry> stream, String option, String target)
|
||||
{
|
||||
Optional<MenuEntry> maybeEntry = stream.filter(e -> Text.standardize(e.getOption()).contains(option) &&
|
||||
Text.standardize(e.getTarget()).contains(target))
|
||||
/* autism */ .findFirst();
|
||||
Text.standardize(e.getTarget()).contains(target))
|
||||
/* autism */.findFirst();
|
||||
|
||||
return maybeEntry.orElse(null);
|
||||
}
|
||||
|
||||
@@ -1,79 +1,92 @@
|
||||
package net.runelite.client.util;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class MiscUtils
|
||||
{
|
||||
private static int[] abovePointsX = { 2944, 3392, 3392, 2944 };
|
||||
private static int[] abovePointsY = { 3523, 3523, 3971, 3971 };
|
||||
private static int[] belowPointsX = { 2944, 2944, 3264, 3264 };
|
||||
private static int[] belowPointsY = { 9918, 10360, 10360, 9918 };
|
||||
|
||||
private static Polygon abovePoly = new Polygon(abovePointsX, abovePointsY, abovePointsX.length);
|
||||
private static Polygon belowPoly = new Polygon(belowPointsX, belowPointsY, belowPointsX.length);
|
||||
|
||||
//test replacement so private for now
|
||||
private static boolean inWildy(WorldPoint point)
|
||||
{
|
||||
if (point == null)
|
||||
return false;
|
||||
|
||||
return abovePoly.contains(point.getX(), point.getY()) || belowPoly.contains(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
public static int getWildernessLevelFrom(Client client, WorldPoint point)
|
||||
{
|
||||
if (client == null)
|
||||
return 0;
|
||||
|
||||
if (point == null)
|
||||
return 0;
|
||||
|
||||
int x = point.getX();
|
||||
|
||||
if (point.getPlane() == 0 && (x < 2940 || x > 3391))
|
||||
return 0;
|
||||
|
||||
int y = point.getY();
|
||||
//v underground //v above ground
|
||||
int wildernessLevel = clamp(y > 6400 ? ((y - 9920) / 8) + 1 : ((y - 3520) / 8) + 1, 0, 56);
|
||||
|
||||
if (point.getPlane() > 0)
|
||||
if (y < 9920)
|
||||
wildernessLevel = 0;
|
||||
|
||||
if (client.getWorldType().stream().anyMatch(worldType -> worldType == WorldType.PVP || worldType == WorldType.HIGH_RISK))
|
||||
{
|
||||
wildernessLevel += 15;
|
||||
}
|
||||
|
||||
return Math.max(0, wildernessLevel);
|
||||
}
|
||||
|
||||
public static int clamp(int val, int min, int max)
|
||||
{
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
|
||||
public static float clamp(float val, float min, float max)
|
||||
{
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
|
||||
public static boolean inWilderness(Client client)
|
||||
{
|
||||
Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
if (localPlayer == null)
|
||||
return false;
|
||||
|
||||
return inWildy(localPlayer.getWorldLocation());
|
||||
|
||||
//return getWildernessLevelFrom(client, localPlayer.getWorldLocation()) > 0;
|
||||
}
|
||||
}
|
||||
package net.runelite.client.util;
|
||||
|
||||
import java.awt.Polygon;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
public class MiscUtils
|
||||
{
|
||||
private static int[] abovePointsX = {2944, 3392, 3392, 2944};
|
||||
private static int[] abovePointsY = {3523, 3523, 3971, 3971};
|
||||
private static int[] belowPointsX = {2944, 2944, 3264, 3264};
|
||||
private static int[] belowPointsY = {9918, 10360, 10360, 9918};
|
||||
|
||||
private static Polygon abovePoly = new Polygon(abovePointsX, abovePointsY, abovePointsX.length);
|
||||
private static Polygon belowPoly = new Polygon(belowPointsX, belowPointsY, belowPointsX.length);
|
||||
|
||||
//test replacement so private for now
|
||||
private static boolean inWildy(WorldPoint point)
|
||||
{
|
||||
if (point == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return abovePoly.contains(point.getX(), point.getY()) || belowPoly.contains(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
public static int getWildernessLevelFrom(Client client, WorldPoint point)
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (point == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x = point.getX();
|
||||
|
||||
if (point.getPlane() == 0 && (x < 2940 || x > 3391))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int y = point.getY();
|
||||
//v underground //v above ground
|
||||
int wildernessLevel = clamp(y > 6400 ? ((y - 9920) / 8) + 1 : ((y - 3520) / 8) + 1, 0, 56);
|
||||
|
||||
if (point.getPlane() > 0)
|
||||
{
|
||||
if (y < 9920)
|
||||
{
|
||||
wildernessLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (client.getWorldType().stream().anyMatch(worldType -> worldType == WorldType.PVP || worldType == WorldType.HIGH_RISK))
|
||||
{
|
||||
wildernessLevel += 15;
|
||||
}
|
||||
|
||||
return Math.max(0, wildernessLevel);
|
||||
}
|
||||
|
||||
public static int clamp(int val, int min, int max)
|
||||
{
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
|
||||
public static float clamp(float val, float min, float max)
|
||||
{
|
||||
return Math.max(min, Math.min(max, val));
|
||||
}
|
||||
|
||||
public static boolean inWilderness(Client client)
|
||||
{
|
||||
Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
if (localPlayer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return inWildy(localPlayer.getWorldLocation());
|
||||
|
||||
//return getWildernessLevelFrom(client, localPlayer.getWorldLocation()) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2019. PKLite - All Rights Reserved
|
||||
* Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited.
|
||||
* Proprietary and confidential. Refer to PKLite License file for more information on
|
||||
* full terms of this copyright and to determine what constitutes authorized use.
|
||||
* Written by PKLite(ST0NEWALL, others) <stonewall@thots.cc.usa>, 2019
|
||||
*
|
||||
*/
|
||||
|
||||
package net.runelite.client.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import static net.runelite.client.util.StackFormatter.quantityToRSDecimalStack;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PvPUtil
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the wilderness level based on a world point
|
||||
* @param point the point in the world to get the wilderness level for
|
||||
* @return the int representing the wilderness level
|
||||
*/
|
||||
public static int getWildernessLevelFrom(WorldPoint point)
|
||||
{
|
||||
int x = point.getX();
|
||||
int y = point.getY();
|
||||
|
||||
int underLevel = ((y - 9920) / 8) + 1;
|
||||
int upperLevel = ((y - 3520) / 8) + 1;
|
||||
|
||||
return y > 6400 ? underLevel : upperLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if another player is attackable based off of wilderness level and combat levels
|
||||
* @param client The client of the local player
|
||||
* @param player the player to determine attackability
|
||||
* @return returns true if the player is attackable, false otherwise
|
||||
*/
|
||||
public static boolean isAttackable(Client client, Player player)
|
||||
{
|
||||
int wildernessLevel = 0;
|
||||
if (!(client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isPvpWorld(client.getWorldType())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (WorldType.isPvpWorld(client.getWorldType()))
|
||||
{
|
||||
if (client.getVar(Varbits.IN_WILDERNESS) != 1)
|
||||
{
|
||||
return Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel()) <= 15;
|
||||
}
|
||||
wildernessLevel = 15;
|
||||
}
|
||||
return Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel())
|
||||
< (getWildernessLevelFrom(client.getLocalPlayer().getWorldLocation())+ wildernessLevel);
|
||||
}
|
||||
|
||||
public static int calculateRisk(Client client, ItemManager itemManager)
|
||||
{
|
||||
if (client.getItemContainer(InventoryID.EQUIPMENT) == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Item[] items = ArrayUtils.addAll(Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT)).getItems(),
|
||||
Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY)).getItems());
|
||||
TreeMap<Integer, Item> priceMap = new TreeMap<>(Comparator.comparingInt(Integer::intValue));
|
||||
int wealth = 0;
|
||||
for (Item i : items)
|
||||
{
|
||||
int value = (itemManager.getItemPrice(i.getId()) * i.getQuantity());
|
||||
|
||||
final ItemComposition itemComposition = itemManager.getItemComposition(i.getId());
|
||||
if (!itemComposition.isTradeable() && value == 0)
|
||||
{
|
||||
value = itemComposition.getPrice() * i.getQuantity();
|
||||
priceMap.put(value, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = itemManager.getItemPrice(i.getId()) * i.getQuantity();
|
||||
if (i.getId() > 0 && value > 0)
|
||||
{
|
||||
priceMap.put(value, i);
|
||||
}
|
||||
}
|
||||
wealth += value;
|
||||
}
|
||||
return Integer.parseInt(quantityToRSDecimalStack(priceMap.keySet().stream().mapToInt(Integer::intValue).sum()));
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019. PKLite - All Rights Reserved
|
||||
* Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited.
|
||||
* Proprietary and confidential. Refer to PKLite License file for more information on
|
||||
* full terms of this copyright and to determine what constitutes authorized use.
|
||||
* Written by PKLite(ST0NEWALL, others) <stonewall@thots.cc.usa>, 2019
|
||||
*
|
||||
*/
|
||||
|
||||
package net.runelite.client.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import static net.runelite.client.util.StackFormatter.quantityToRSDecimalStack;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PvPUtil
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the wilderness level based on a world point
|
||||
*
|
||||
* @param point the point in the world to get the wilderness level for
|
||||
* @return the int representing the wilderness level
|
||||
*/
|
||||
public static int getWildernessLevelFrom(WorldPoint point)
|
||||
{
|
||||
int x = point.getX();
|
||||
int y = point.getY();
|
||||
|
||||
int underLevel = ((y - 9920) / 8) + 1;
|
||||
int upperLevel = ((y - 3520) / 8) + 1;
|
||||
|
||||
return y > 6400 ? underLevel : upperLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if another player is attackable based off of wilderness level and combat levels
|
||||
*
|
||||
* @param client The client of the local player
|
||||
* @param player the player to determine attackability
|
||||
* @return returns true if the player is attackable, false otherwise
|
||||
*/
|
||||
public static boolean isAttackable(Client client, Player player)
|
||||
{
|
||||
int wildernessLevel = 0;
|
||||
if (!(client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isPvpWorld(client.getWorldType())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (WorldType.isPvpWorld(client.getWorldType()))
|
||||
{
|
||||
if (client.getVar(Varbits.IN_WILDERNESS) != 1)
|
||||
{
|
||||
return Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel()) <= 15;
|
||||
}
|
||||
wildernessLevel = 15;
|
||||
}
|
||||
return Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel())
|
||||
< (getWildernessLevelFrom(client.getLocalPlayer().getWorldLocation()) + wildernessLevel);
|
||||
}
|
||||
|
||||
public static int calculateRisk(Client client, ItemManager itemManager)
|
||||
{
|
||||
if (client.getItemContainer(InventoryID.EQUIPMENT) == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Item[] items = ArrayUtils.addAll(Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT)).getItems(),
|
||||
Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY)).getItems());
|
||||
TreeMap<Integer, Item> priceMap = new TreeMap<>(Comparator.comparingInt(Integer::intValue));
|
||||
int wealth = 0;
|
||||
for (Item i : items)
|
||||
{
|
||||
int value = (itemManager.getItemPrice(i.getId()) * i.getQuantity());
|
||||
|
||||
final ItemComposition itemComposition = itemManager.getItemComposition(i.getId());
|
||||
if (!itemComposition.isTradeable() && value == 0)
|
||||
{
|
||||
value = itemComposition.getPrice() * i.getQuantity();
|
||||
priceMap.put(value, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = itemManager.getItemPrice(i.getId()) * i.getQuantity();
|
||||
if (i.getId() > 0 && value > 0)
|
||||
{
|
||||
priceMap.put(value, i);
|
||||
}
|
||||
}
|
||||
wealth += value;
|
||||
}
|
||||
return Integer.parseInt(quantityToRSDecimalStack(priceMap.keySet().stream().mapToInt(Integer::intValue).sum()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user