Merge branch 'master' into loot-tracker-reset
This commit is contained in:
@@ -46,11 +46,13 @@ import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import net.runelite.client.config.FlashNotification;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.util.OSType;
|
||||
@@ -68,7 +70,8 @@ public class Notifier
|
||||
|
||||
// Notifier properties
|
||||
private static final Color FLASH_COLOR = new Color(255, 0, 0, 70);
|
||||
private static final int FLASH_DURATION = 2000;
|
||||
private static final int MINIMUM_FLASH_DURATION_MILLIS = 2000;
|
||||
private static final int MINIMUM_FLASH_DURATION_TICKS = MINIMUM_FLASH_DURATION_MILLIS / Constants.CLIENT_TICK_LENGTH;
|
||||
|
||||
private final Client client;
|
||||
private final String appName;
|
||||
@@ -79,6 +82,7 @@ public class Notifier
|
||||
private final Path notifyIconPath;
|
||||
private final boolean terminalNotifierAvailable;
|
||||
private Instant flashStart;
|
||||
private long mouseLastPressedMillis;
|
||||
|
||||
@Inject
|
||||
private Notifier(
|
||||
@@ -146,9 +150,10 @@ public class Notifier
|
||||
.build());
|
||||
}
|
||||
|
||||
if (runeLiteConfig.enableFlashNotification())
|
||||
if (runeLiteConfig.flashNotification() != FlashNotification.DISABLED)
|
||||
{
|
||||
flashStart = Instant.now();
|
||||
mouseLastPressedMillis = client.getMouseLastPressedMillis();
|
||||
}
|
||||
|
||||
log.debug(message);
|
||||
@@ -156,24 +161,48 @@ public class Notifier
|
||||
|
||||
public void processFlash(final Graphics2D graphics)
|
||||
{
|
||||
if (flashStart == null || client.getGameCycle() % 40 >= 20)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (client.getGameState() != GameState.LOGGED_IN)
|
||||
if (flashStart == null || client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
flashStart = null;
|
||||
return;
|
||||
}
|
||||
|
||||
FlashNotification flashNotification = runeLiteConfig.flashNotification();
|
||||
|
||||
if (client.getGameCycle() % 40 >= 20
|
||||
// For solid colour, fall through every time.
|
||||
&& (flashNotification == FlashNotification.FLASH_TWO_SECONDS
|
||||
|| flashNotification == FlashNotification.FLASH_UNTIL_CANCELLED))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Color color = graphics.getColor();
|
||||
graphics.setColor(FLASH_COLOR);
|
||||
graphics.fill(new Rectangle(client.getCanvas().getSize()));
|
||||
graphics.setColor(color);
|
||||
|
||||
if (Instant.now().minusMillis(FLASH_DURATION).isAfter(flashStart))
|
||||
if (!Instant.now().minusMillis(MINIMUM_FLASH_DURATION_MILLIS).isAfter(flashStart))
|
||||
{
|
||||
flashStart = null;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (flashNotification)
|
||||
{
|
||||
case FLASH_TWO_SECONDS:
|
||||
case SOLID_TWO_SECONDS:
|
||||
flashStart = null;
|
||||
break;
|
||||
case SOLID_UNTIL_CANCELLED:
|
||||
case FLASH_UNTIL_CANCELLED:
|
||||
// Any interaction with the client since the notification started will cancel it after the minimum duration
|
||||
if (client.getMouseIdleTicks() < MINIMUM_FLASH_DURATION_TICKS
|
||||
|| client.getKeyboardIdleTicks() < MINIMUM_FLASH_DURATION_TICKS
|
||||
|| client.getMouseLastPressedMillis() > mouseLastPressedMillis)
|
||||
{
|
||||
flashStart = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* Copyright (c) 2019, Twiglet1022 <https://github.com/Twiglet1022>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,29 +22,26 @@
|
||||
* (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.inferno;
|
||||
package net.runelite.client.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
enum InfernoWaveMonster
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FlashNotification
|
||||
{
|
||||
|
||||
JAL_NIB("Jal-Nib", 32),
|
||||
JAL_MEJRAH("Jal-MejRah", 85),
|
||||
JAL_AK("Jal-Ak", 165),
|
||||
JAL_IMKOT("Jal-ImKot", 240),
|
||||
JAL_XIL("Jal-XIL", 370),
|
||||
JAL_ZEK("Jal-Zek", 490),
|
||||
JALTOK_JAD("JalTok-Jad", 900),
|
||||
TZKAL_ZUK("TzKal-Zuk", 1400);
|
||||
DISABLED("Off"),
|
||||
FLASH_TWO_SECONDS("Flash for 2 seconds"),
|
||||
SOLID_TWO_SECONDS("Solid for 2 seconds"),
|
||||
FLASH_UNTIL_CANCELLED("Flash until cancelled"),
|
||||
SOLID_UNTIL_CANCELLED("Solid until cancelled");
|
||||
|
||||
private final String name;
|
||||
private final int level;
|
||||
private final String type;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s - Level %s", name, level);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -191,9 +191,9 @@ public interface RuneLiteConfig extends Config
|
||||
description = "Flashes the game frame as a notification",
|
||||
position = 24
|
||||
)
|
||||
default boolean enableFlashNotification()
|
||||
default FlashNotification flashNotification()
|
||||
{
|
||||
return false;
|
||||
return FlashNotification.DISABLED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
|
||||
@@ -44,8 +44,9 @@ import javax.inject.Singleton;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import static net.runelite.api.Constants.CLIENT_DEFAULT_ZOOM;
|
||||
import static net.runelite.api.Constants.HIGH_ALCHEMY_CONSTANT;
|
||||
import static net.runelite.api.Constants.HIGH_ALCHEMY_MULTIPLIER;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.ItemID;
|
||||
@@ -423,7 +424,7 @@ public class ItemManager
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return (int) Math.max(1, composition.getPrice() * HIGH_ALCHEMY_CONSTANT);
|
||||
return (int) Math.max(1, composition.getPrice() * HIGH_ALCHEMY_MULTIPLIER);
|
||||
}
|
||||
|
||||
public int getAlchValue(int itemID)
|
||||
@@ -437,7 +438,7 @@ public class ItemManager
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return (int) Math.max(1, getItemDefinition(itemID).getPrice() * HIGH_ALCHEMY_CONSTANT);
|
||||
return (int) Math.max(1, getItemDefinition(itemID).getPrice() * HIGH_ALCHEMY_MULTIPLIER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -521,7 +522,7 @@ public class ItemManager
|
||||
*/
|
||||
private AsyncBufferedImage loadImage(int itemId, int quantity, boolean stackable)
|
||||
{
|
||||
AsyncBufferedImage img = new AsyncBufferedImage(36, 32, BufferedImage.TYPE_INT_ARGB);
|
||||
AsyncBufferedImage img = new AsyncBufferedImage(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
if (client.getGameState().ordinal() < GameState.LOGIN_SCREEN.ordinal())
|
||||
|
||||
@@ -144,10 +144,12 @@ public enum ItemMapping
|
||||
// Bounty hunter
|
||||
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848),
|
||||
ITEM_MAGIC_SHORTBOW(MAGIC_SHORTBOW, MAGIC_SHORTBOW_I),
|
||||
ITEM_MAGIC_SHORTBOW_SCROLL(MAGIC_SHORTBOW_SCROLL, 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_RING_OF_WEALTH_SCROLL(RING_OF_WEALTH_SCROLL, RING_OF_WEALTH_I, RING_OF_WEALTH_I1, RING_OF_WEALTH_I2, RING_OF_WEALTH_I3, 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),
|
||||
|
||||
@@ -109,7 +109,7 @@ public class LootManager
|
||||
case NpcID.LIZARD:
|
||||
|
||||
case NpcID.ZYGOMITE:
|
||||
case NpcID.ZYGOMITE_474:
|
||||
case NpcID.ZYGOMITE_1024:
|
||||
case NpcID.ANCIENT_ZYGOMITE:
|
||||
|
||||
// these monsters die with >0 hp, so we just look for coincident
|
||||
|
||||
@@ -42,9 +42,11 @@ import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MenuAction;
|
||||
import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET;
|
||||
import static net.runelite.api.MenuAction.GAME_OBJECT_FIRST_OPTION;
|
||||
import static net.runelite.api.MenuAction.WIDGET_DEFAULT;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.events.ClientTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.NpcActionChanged;
|
||||
@@ -147,14 +149,6 @@ public class MenuManager
|
||||
Collection<WidgetMenuOption> options = managedMenuOptions.get(widgetId);
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
if (menuEntries.length == 1)
|
||||
{
|
||||
// Menu entries reset, so priority entries should reset as well
|
||||
currentPriorityEntries.clear();
|
||||
|
||||
originalTypes.clear();
|
||||
}
|
||||
|
||||
for (WidgetMenuOption currentMenu : options)
|
||||
{
|
||||
if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget
|
||||
@@ -173,22 +167,14 @@ public class MenuManager
|
||||
|
||||
final MenuEntry newestEntry = menuEntries[menuEntries.length - 1];
|
||||
|
||||
boolean isPrio = false;
|
||||
for (ComparableEntry p : priorityEntries)
|
||||
{
|
||||
if (p.matches(newestEntry))
|
||||
{
|
||||
isPrio = true;
|
||||
break;
|
||||
currentPriorityEntries.add(newestEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// If the last entry was a priority entry, keep track of it
|
||||
if (isPrio)
|
||||
{
|
||||
currentPriorityEntries.add(newestEntry);
|
||||
}
|
||||
|
||||
// Make a copy of the menu entries, cause you can't remove from Arrays.asList()
|
||||
List<MenuEntry> copy = Lists.newArrayList(menuEntries);
|
||||
|
||||
@@ -197,88 +183,26 @@ public class MenuManager
|
||||
{
|
||||
copy.retainAll(currentPriorityEntries);
|
||||
|
||||
copy.add(0, CANCEL());
|
||||
}
|
||||
|
||||
// Find the current entry in the swaps map
|
||||
ComparableEntry swapEntry = null;
|
||||
for (ComparableEntry e : swaps.keySet())
|
||||
{
|
||||
if (e.matches(newestEntry))
|
||||
// This is because players existing changes walk-here target
|
||||
// so without this we lose track of em
|
||||
if (copy.size() != currentPriorityEntries.size())
|
||||
{
|
||||
swapEntry = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (swapEntry != null)
|
||||
{
|
||||
ComparableEntry swapTarget = swaps.get(swapEntry);
|
||||
|
||||
// Find the target for the swap in current menu entries
|
||||
MenuEntry foundSwap = null;
|
||||
for (MenuEntry entry : Lists.reverse(copy))
|
||||
{
|
||||
if (swapTarget.matches(entry))
|
||||
for (MenuEntry e : currentPriorityEntries)
|
||||
{
|
||||
foundSwap = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundSwap != null)
|
||||
{
|
||||
// This is the type for the entry we're swapping the newest with
|
||||
final int foundType = foundSwap.getType();
|
||||
// This is the type for the newest entry
|
||||
final int lastType = newestEntry.getType();
|
||||
|
||||
// MenuActions with an id of over 1000 get shifted to the back of the menu entry array
|
||||
// They have different id's in the packet buffer though, so we got to modify them back on click
|
||||
// I couldn't get this to work with objects, so we're using modified objectcomposition for that
|
||||
final boolean shouldModifyFoundType = foundType >= 1000;
|
||||
|
||||
final boolean shouldModifyLastType = lastType >= 1000;
|
||||
|
||||
// Bitwise or so we don't end up making things left click when they shouldn't
|
||||
if (shouldModifyFoundType ^ shouldModifyLastType)
|
||||
{
|
||||
int typeToSet;
|
||||
switch (MenuAction.of(shouldModifyFoundType ? foundType : lastType))
|
||||
if (copy.contains(e))
|
||||
{
|
||||
case EXAMINE_ITEM_BANK_EQ:
|
||||
typeToSet = MenuAction.WIDGET_DEFAULT.getId();
|
||||
break;
|
||||
case GAME_OBJECT_FIFTH_OPTION:
|
||||
typeToSet = MenuAction.GAME_OBJECT_FIRST_OPTION.getId();
|
||||
break;
|
||||
default:
|
||||
typeToSet = shouldModifyFoundType ? foundType : lastType;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldModifyFoundType)
|
||||
for (MenuEntry e2 : client.getMenuEntries())
|
||||
{
|
||||
foundSwap.setType(typeToSet);
|
||||
originalTypes.put(foundSwap, foundType);
|
||||
}
|
||||
else
|
||||
{
|
||||
newestEntry.setType(typeToSet);
|
||||
originalTypes.put(newestEntry, lastType);
|
||||
|
||||
// We're probably trying to make something left click, so just slap on
|
||||
// the menu action deprioritize 2000-inator++
|
||||
foundSwap.setType(foundType + MENU_ACTION_DEPRIORITIZE_OFFSET);
|
||||
if (e.getType() == e2.getType())
|
||||
{
|
||||
e.setTarget(e2.getTarget());
|
||||
copy.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap
|
||||
int index = copy.indexOf(foundSwap);
|
||||
int newIndex = copy.indexOf(newestEntry);
|
||||
|
||||
copy.set(index, newestEntry);
|
||||
copy.set(newIndex, foundSwap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +224,69 @@ public class MenuManager
|
||||
client.setMenuEntries(copy.toArray(new MenuEntry[0]));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onClientTick(ClientTick event)
|
||||
{
|
||||
originalTypes.clear();
|
||||
client.sortMenuEntries();
|
||||
|
||||
final MenuEntry[] oldentries = client.getMenuEntries();
|
||||
MenuEntry[] newEntries;
|
||||
|
||||
if (!currentPriorityEntries.isEmpty())
|
||||
{
|
||||
newEntries = new MenuEntry[client.getMenuOptionCount() + 1];
|
||||
newEntries[0] = CANCEL();
|
||||
|
||||
System.arraycopy(oldentries, 0, newEntries, 1, oldentries.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
newEntries = Arrays.copyOf(oldentries, client.getMenuOptionCount());
|
||||
}
|
||||
|
||||
MenuEntry leftClickEntry = newEntries[newEntries.length - 1];
|
||||
|
||||
|
||||
for (ComparableEntry src : swaps.keySet())
|
||||
{
|
||||
if (!src.matches(leftClickEntry))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ComparableEntry tgt = swaps.get(src);
|
||||
|
||||
for (int i = newEntries.length - 2; i > 0; i--)
|
||||
{
|
||||
MenuEntry e = newEntries[i];
|
||||
|
||||
if (tgt.matches(e))
|
||||
{
|
||||
newEntries[newEntries.length - 1] = e;
|
||||
newEntries[i] = leftClickEntry;
|
||||
|
||||
int type = e.getType();
|
||||
|
||||
if (type >= 1000)
|
||||
{
|
||||
int newType = getLeftClickType(type);
|
||||
if (newType != -1 && newType != type)
|
||||
{
|
||||
e.setType(newType);
|
||||
originalTypes.put(e, type);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.setMenuEntries(newEntries);
|
||||
currentPriorityEntries.clear();
|
||||
}
|
||||
|
||||
public void addPlayerMenuItem(String menuText)
|
||||
{
|
||||
Preconditions.checkNotNull(menuText);
|
||||
@@ -361,6 +348,24 @@ public class MenuManager
|
||||
}
|
||||
}
|
||||
|
||||
private int getLeftClickType(int oldType)
|
||||
{
|
||||
if (oldType > 2000)
|
||||
{
|
||||
oldType -= 2000;
|
||||
}
|
||||
|
||||
switch (MenuAction.of(oldType))
|
||||
{
|
||||
case GAME_OBJECT_FIFTH_OPTION:
|
||||
return GAME_OBJECT_FIRST_OPTION.getId();
|
||||
case EXAMINE_ITEM_BANK_EQ:
|
||||
return WIDGET_DEFAULT.getId();
|
||||
default:
|
||||
return oldType;
|
||||
}
|
||||
}
|
||||
|
||||
private void addNpcOption(NPCDefinition composition, String npcOption)
|
||||
{
|
||||
String[] actions = composition.getActions();
|
||||
@@ -404,69 +409,21 @@ public class MenuManager
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
// if (originalTypes.get(event.ge
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// This right here. That's the moment I realized once again that
|
||||
// this event still is one of the worst fucking things that has
|
||||
// ever happened to this project. MenuOptionClicked right? What
|
||||
// do you expect the data in the event object to be?
|
||||
// A FUCKING MENU ENTRY. Honestly I originally forgot why I wrote
|
||||
// the rant below this, but the hate is coming back to me once again.
|
||||
// What the fuck do you expect me to do? Make another MenuEntry from
|
||||
// all the info WHICH WOULD HAVE BEEN INSIDE THE FUCKING MENUENTRY TO
|
||||
// BEGIN WITH??? I am legit still perplexed over why someone would do
|
||||
// it like this, and I don't want them to take this lightly cause they
|
||||
// should really really really feel terrible about this.
|
||||
|
||||
if (!event.getMenuTarget().equals("do not edit") &&
|
||||
!originalTypes.isEmpty() &&
|
||||
event.getMenuAction() == MenuAction.WIDGET_DEFAULT ||
|
||||
event.getMenuAction() == MenuAction.GAME_OBJECT_FIRST_OPTION)
|
||||
if (originalTypes.containsKey(event.getMenuEntry()) &&
|
||||
!event.getTarget().equals("do not edit"))
|
||||
{
|
||||
for (Map.Entry<MenuEntry, Integer> ent : originalTypes.entrySet())
|
||||
{
|
||||
// Honestly, I was about to write a huge ass rant about
|
||||
// how I hate whoever wrote the menuoptionclicked class
|
||||
// but I decided that that'd be un-nice to them, and they
|
||||
// probably spent over 24 hours writing it. Not because
|
||||
// it was that difficult to write, of course, but because
|
||||
// they must have the fucking iq of a retarded, under developed,
|
||||
// braindead, basically good-for-nothing, idiotic chimp.
|
||||
//
|
||||
// Just kidding, of course, that would be too big of an
|
||||
// insult towards those poor chimps. It's not their fault
|
||||
// some dumbass is the way they are, right? Why should they
|
||||
// feel bad for something they can't do anything about?
|
||||
//
|
||||
// Whoever wrote that class though, should actually feel
|
||||
// 100% terrible. If they aren't depressed, I really wish
|
||||
// they become depressed very, very soon. What the fuck
|
||||
// were they even thinking.
|
||||
event.consume();
|
||||
|
||||
MenuEntry e = ent.getKey();
|
||||
|
||||
if (event.getMenuAction().getId() != e.getType()
|
||||
|| event.getId() != e.getIdentifier()
|
||||
|| !event.getMenuOption().equals(e.getOption()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
event.consume();
|
||||
|
||||
client.invokeMenuAction(
|
||||
event.getActionParam(),
|
||||
event.getWidgetId(),
|
||||
ent.getValue(),
|
||||
event.getId(),
|
||||
event.getMenuOption(),
|
||||
"do not edit",
|
||||
client.getMouseCanvasPosition().getX(),
|
||||
client.getMouseCanvasPosition().getY()
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
client.invokeMenuAction(
|
||||
event.getActionParam0(),
|
||||
event.getActionParam1(),
|
||||
originalTypes.get(event.getMenuEntry()),
|
||||
event.getIdentifier(),
|
||||
event.getOption(),
|
||||
"do not edit",
|
||||
client.getMouseCanvasPosition().getX(),
|
||||
client.getMouseCanvasPosition().getY()
|
||||
);
|
||||
}
|
||||
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE)
|
||||
@@ -474,31 +431,31 @@ public class MenuManager
|
||||
return; // not a player menu
|
||||
}
|
||||
|
||||
int widgetId = event.getWidgetId();
|
||||
int widgetId = event.getActionParam1();
|
||||
Collection<WidgetMenuOption> options = managedMenuOptions.get(widgetId);
|
||||
|
||||
for (WidgetMenuOption curMenuOption : options)
|
||||
{
|
||||
if (curMenuOption.getMenuTarget().equals(event.getMenuTarget())
|
||||
&& curMenuOption.getMenuOption().equals(event.getMenuOption()))
|
||||
if (curMenuOption.getMenuTarget().equals(event.getTarget())
|
||||
&& curMenuOption.getMenuOption().equals(event.getOption()))
|
||||
{
|
||||
WidgetMenuOptionClicked customMenu = new WidgetMenuOptionClicked();
|
||||
customMenu.setMenuOption(event.getMenuOption());
|
||||
customMenu.setMenuTarget(event.getMenuTarget());
|
||||
customMenu.setMenuOption(event.getOption());
|
||||
customMenu.setMenuTarget(event.getTarget());
|
||||
customMenu.setWidget(curMenuOption.getWidget());
|
||||
eventBus.post(customMenu);
|
||||
return; // don't continue because it's not a player option
|
||||
}
|
||||
}
|
||||
|
||||
String target = event.getMenuTarget();
|
||||
String target = event.getTarget();
|
||||
|
||||
// removes tags and level from player names for example:
|
||||
// <col=ffffff>username<col=40ff00> (level-42) or <col=ffffff><img=2>username</col>
|
||||
String username = Text.removeTags(target).split("[(]")[0].trim();
|
||||
|
||||
PlayerMenuOptionClicked playerMenuOptionClicked = new PlayerMenuOptionClicked();
|
||||
playerMenuOptionClicked.setMenuOption(event.getMenuOption());
|
||||
playerMenuOptionClicked.setMenuOption(event.getOption());
|
||||
playerMenuOptionClicked.setMenuTarget(username);
|
||||
|
||||
eventBus.post(playerMenuOptionClicked);
|
||||
|
||||
@@ -32,15 +32,15 @@ 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"
|
||||
* The left hand text to be displayed on the menu option. Ex. the option 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"
|
||||
* The right hand text to be displayed on the menu option Ex. the target 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.
|
||||
* The color that the target should be. Defaults to the brownish color that most menu options have.
|
||||
*/
|
||||
private Color color = JagexColors.MENU_TARGET;
|
||||
|
||||
|
||||
@@ -24,74 +24,119 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.alchemicalhydra;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
@Singleton
|
||||
class Hydra
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
enum AttackStyle
|
||||
{
|
||||
MAGIC(ProjectileID.HYDRA_MAGIC, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGED(ProjectileID.HYDRA_RANGED, Prayer.PROTECT_FROM_MISSILES);
|
||||
MAGIC(ProjectileID.HYDRA_MAGIC, Prayer.PROTECT_FROM_MAGIC, SpriteID.PRAYER_PROTECT_FROM_MAGIC),
|
||||
RANGED(ProjectileID.HYDRA_RANGED, Prayer.PROTECT_FROM_MISSILES, SpriteID.PRAYER_PROTECT_FROM_MISSILES);
|
||||
|
||||
@Getter
|
||||
private int projId;
|
||||
private final int projectileID;
|
||||
private final Prayer prayer;
|
||||
private final int spriteID;
|
||||
|
||||
@Getter
|
||||
private Prayer prayer;
|
||||
@Getter(AccessLevel.NONE)
|
||||
private BufferedImage image;
|
||||
|
||||
AttackStyle(int projId, Prayer prayer)
|
||||
BufferedImage getImage(SpriteManager spriteManager)
|
||||
{
|
||||
this.projId = projId;
|
||||
this.prayer = prayer;
|
||||
if (image == null)
|
||||
{
|
||||
BufferedImage tmp = spriteManager.getSprite(spriteID, 0);
|
||||
image = tmp == null ? null : ImageUtil.resizeImage(tmp, HydraOverlay.IMGSIZE, HydraOverlay.IMGSIZE);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private NPC npc;
|
||||
private final NPC npc;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private HydraPhase phase;
|
||||
private HydraPhase phase = HydraPhase.ONE;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int attackCount;
|
||||
private int attackCount = 0;
|
||||
private int nextSwitch = phase.getAttacksPerSwitch();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int nextSwitch;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private int nextSpecial = 3;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int nextSpecial;
|
||||
private AttackStyle nextAttack = AttackStyle.MAGIC;
|
||||
private AttackStyle lastAttack = AttackStyle.MAGIC;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private AttackStyle nextAttack;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean weakened = false;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private AttackStyle lastAttack;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean weakened;
|
||||
|
||||
Hydra(NPC npc)
|
||||
void changePhase(HydraPhase newPhase)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.phase = HydraPhase.ONE;
|
||||
this.nextAttack = AttackStyle.MAGIC;
|
||||
this.lastAttack = AttackStyle.MAGIC; // important, else we wouldn't switch if the first attack is ranged
|
||||
this.nextSpecial = 3;
|
||||
this.nextSwitch = phase.getAttacksPerSwitch();
|
||||
this.attackCount = 0;
|
||||
this.weakened = false;
|
||||
phase = newPhase;
|
||||
nextSpecial = 3;
|
||||
attackCount = 0;
|
||||
weakened = false;
|
||||
|
||||
if (newPhase == HydraPhase.FOUR)
|
||||
{
|
||||
weakened = true;
|
||||
switchStyles();
|
||||
nextSwitch = phase.getAttacksPerSwitch();
|
||||
}
|
||||
}
|
||||
|
||||
private void switchStyles()
|
||||
{
|
||||
nextAttack = lastAttack == Hydra.AttackStyle.MAGIC
|
||||
? Hydra.AttackStyle.RANGED
|
||||
: Hydra.AttackStyle.MAGIC;
|
||||
}
|
||||
|
||||
void handleAttack(int id)
|
||||
{
|
||||
if (id != nextAttack.getProjectileID())
|
||||
{
|
||||
if (id == lastAttack.getProjectileID())
|
||||
{
|
||||
// If the current attack isn't what was expected and we accidentally counted 1 too much
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current attack isn't what was expected and we should have switched prayers
|
||||
switchStyles();
|
||||
nextSwitch = phase.getAttacksPerSwitch() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextSwitch--;
|
||||
}
|
||||
|
||||
lastAttack = nextAttack;
|
||||
attackCount++;
|
||||
|
||||
if (nextSwitch <= 0)
|
||||
{
|
||||
switchStyles();
|
||||
nextSwitch = phase.getAttacksPerSwitch();
|
||||
}
|
||||
}
|
||||
|
||||
int getNextSpecialRelative()
|
||||
{
|
||||
return nextSpecial - attackCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,16 +26,12 @@ package net.runelite.client.plugins.alchemicalhydra;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -46,13 +42,16 @@ import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
@Singleton
|
||||
class HydraOverlay extends Overlay
|
||||
{
|
||||
|
||||
private static final Color RED_BG_COL = new Color(156, 0, 0, 156);
|
||||
private static final Color YEL_BG_COL = new Color(200, 156, 0, 156);
|
||||
private static final Color GRN_BG_COL = new Color(0, 156, 0, 156);
|
||||
static final int IMGSIZE = 36;
|
||||
|
||||
private final HydraPlugin plugin;
|
||||
private final Client client;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
private static final Color redBgCol = new Color(156, 0, 0, 156);
|
||||
private static final Color yelBgCol = new Color(200, 156, 0, 156);
|
||||
private static final Color grnBgCol = new Color(0, 156, 0, 156);
|
||||
|
||||
@Inject
|
||||
HydraOverlay(HydraPlugin plugin, Client client, SpriteManager spriteManager)
|
||||
@@ -76,9 +75,8 @@ class HydraOverlay extends Overlay
|
||||
}
|
||||
|
||||
//Add spec overlay first, to keep it above pray
|
||||
HydraPhase phase = hydra.getPhase();
|
||||
int attackCount = hydra.getAttackCount();
|
||||
int nextSpec = hydra.getNextSpecial() - attackCount;
|
||||
final HydraPhase phase = hydra.getPhase();
|
||||
final int nextSpec = hydra.getNextSpecialRelative();
|
||||
|
||||
if (nextSpec <= 3)
|
||||
{
|
||||
@@ -86,37 +84,34 @@ class HydraOverlay extends Overlay
|
||||
|
||||
if (nextSpec == 0)
|
||||
{
|
||||
specComponent.setBackgroundColor(redBgCol);
|
||||
specComponent.setBackgroundColor(RED_BG_COL);
|
||||
}
|
||||
else if (nextSpec == 1)
|
||||
{
|
||||
specComponent.setBackgroundColor(yelBgCol);
|
||||
specComponent.setBackgroundColor(YEL_BG_COL);
|
||||
}
|
||||
Image specImg = scaleImg(spriteManager.getSprite(phase.getSpecImage(), 0));
|
||||
|
||||
specComponent.setImage(specImg);
|
||||
specComponent.setImage(phase.getSpecImage(spriteManager));
|
||||
specComponent.setText(" " + (nextSpec)); //hacky way to not have to figure out how to move text
|
||||
specComponent.setPreferredSize(new Dimension(40, 40));
|
||||
panelComponent.getChildren().add(specComponent);
|
||||
}
|
||||
|
||||
|
||||
Prayer nextPrayer = hydra.getNextAttack().getPrayer();
|
||||
Image prayImg = scaleImg(getPrayerImage(hydra.getNextAttack().getPrayer()));
|
||||
int nextSwitch = hydra.getNextSwitch();
|
||||
final Prayer nextPrayer = hydra.getNextAttack().getPrayer();
|
||||
final int nextSwitch = hydra.getNextSwitch();
|
||||
|
||||
InfoBoxComponent prayComponent = new InfoBoxComponent();
|
||||
|
||||
if (nextSwitch == 1)
|
||||
{
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? yelBgCol : redBgCol);
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? YEL_BG_COL : RED_BG_COL);
|
||||
}
|
||||
else
|
||||
{
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? grnBgCol : redBgCol);
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? GRN_BG_COL : RED_BG_COL);
|
||||
}
|
||||
|
||||
prayComponent.setImage(prayImg);
|
||||
prayComponent.setImage(hydra.getNextAttack().getImage(spriteManager));
|
||||
prayComponent.setText(" " + nextSwitch);
|
||||
prayComponent.setColor(Color.white);
|
||||
prayComponent.setPreferredSize(new Dimension(40, 40));
|
||||
@@ -126,32 +121,4 @@ class HydraOverlay extends Overlay
|
||||
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
|
||||
return panelComponent.render(graphics2D);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(Prayer pray)
|
||||
{
|
||||
return pray == Prayer.PROTECT_FROM_MAGIC
|
||||
? spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0)
|
||||
: spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
}
|
||||
|
||||
private Image scaleImg(final Image img)
|
||||
{
|
||||
if (img == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final double width = img.getWidth(null);
|
||||
final double height = img.getHeight(null);
|
||||
final double size = 36; // Limit size to 2 as that is minimum size not causing breakage
|
||||
final double scalex = size / width;
|
||||
final double scaley = size / height;
|
||||
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(img, 0, 0, newWidth, newHeight, null);
|
||||
g.dispose();
|
||||
return scaledImage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,48 +24,46 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.alchemicalhydra;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
enum HydraPhase
|
||||
{ // Sorry for the autism
|
||||
{
|
||||
ONE(3, AnimationID.HYDRA_1_1, AnimationID.HYDRA_1_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, new WorldPoint(1371, 10263, 0)),
|
||||
TWO(3, AnimationID.HYDRA_2_1, AnimationID.HYDRA_2_2, 0, AnimationID.HYDRA_LIGHTNING, SpriteID.BIG_SPEC_TRANSFER, new WorldPoint(1371, 10272, 0)),
|
||||
THREE(3, AnimationID.HYDRA_3_1, AnimationID.HYDRA_3_2, 0, AnimationID.HYDRA_FIRE, SpriteID.BIG_SUPERHEAT, new WorldPoint(1362, 10272, 0)),
|
||||
FOUR(1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
|
||||
|
||||
@Getter
|
||||
private final int attacksPerSwitch;
|
||||
|
||||
@Getter
|
||||
private final int deathAnim1;
|
||||
|
||||
@Getter
|
||||
private final int deathAnim2;
|
||||
|
||||
@Getter
|
||||
private final int specProjectileId;
|
||||
|
||||
@Getter
|
||||
private final int specAnimationId;
|
||||
|
||||
@Getter
|
||||
private final int specImage;
|
||||
@Getter(AccessLevel.NONE)
|
||||
private final int specImageID;
|
||||
private final WorldPoint fountain;
|
||||
|
||||
@Getter
|
||||
private WorldPoint fountain;
|
||||
private BufferedImage specImage;
|
||||
|
||||
HydraPhase(int attacksPerSwitch, int deathAnim1, int deathAnim2, int specProjectileId, int specAnimationId, int specImage, WorldPoint fountain)
|
||||
BufferedImage getSpecImage(SpriteManager spriteManager)
|
||||
{
|
||||
this.attacksPerSwitch = attacksPerSwitch;
|
||||
this.deathAnim1 = deathAnim1;
|
||||
this.deathAnim2 = deathAnim2;
|
||||
this.specProjectileId = specProjectileId;
|
||||
this.specAnimationId = specAnimationId;
|
||||
this.specImage = specImage;
|
||||
this.fountain = fountain;
|
||||
if (specImage == null)
|
||||
{
|
||||
BufferedImage tmp = spriteManager.getSprite(specImageID, 0);
|
||||
specImage = tmp == null ? null : ImageUtil.resizeImage(tmp, HydraOverlay.IMGSIZE, HydraOverlay.IMGSIZE);
|
||||
}
|
||||
|
||||
return specImage;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
@@ -60,10 +61,10 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
@Slf4j
|
||||
public class HydraPlugin extends Plugin
|
||||
{
|
||||
@Getter
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<LocalPoint, Projectile> poisonProjectiles = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Hydra hydra;
|
||||
|
||||
private boolean inHydraInstance;
|
||||
@@ -84,7 +85,7 @@ public class HydraPlugin extends Plugin
|
||||
private HydraOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private HydraPoisonOverlay poisonOverlay;
|
||||
private HydraSceneOverlay poisonOverlay;
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
@@ -124,18 +125,16 @@ public class HydraPlugin extends Plugin
|
||||
}
|
||||
return;
|
||||
}
|
||||
NPC hydraNpc = null;
|
||||
|
||||
for (NPC npc : client.getNpcs())
|
||||
{
|
||||
if (npc.getId() == NpcID.ALCHEMICAL_HYDRA)
|
||||
{
|
||||
hydraNpc = npc;
|
||||
hydra = new Hydra(npc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hydra = new Hydra(hydraNpc);
|
||||
addOverlays();
|
||||
}
|
||||
|
||||
@@ -171,13 +170,13 @@ public class HydraPlugin extends Plugin
|
||||
switch (phase)
|
||||
{
|
||||
case ONE:
|
||||
changePhase(HydraPhase.TWO);
|
||||
hydra.changePhase(HydraPhase.TWO);
|
||||
return;
|
||||
case TWO:
|
||||
changePhase(HydraPhase.THREE);
|
||||
hydra.changePhase(HydraPhase.THREE);
|
||||
return;
|
||||
case THREE:
|
||||
changePhase(HydraPhase.FOUR);
|
||||
hydra.changePhase(HydraPhase.FOUR);
|
||||
return;
|
||||
case FOUR:
|
||||
hydra = null;
|
||||
@@ -237,9 +236,9 @@ public class HydraPlugin extends Plugin
|
||||
poisonProjectiles.put(event.getPosition(), projectile);
|
||||
}
|
||||
else if (client.getTickCount() != lastAttackTick
|
||||
&& (id == Hydra.AttackStyle.MAGIC.getProjId() || id == Hydra.AttackStyle.RANGED.getProjId()))
|
||||
&& (id == Hydra.AttackStyle.MAGIC.getProjectileID() || id == Hydra.AttackStyle.RANGED.getProjectileID()))
|
||||
{
|
||||
handleAttack(id);
|
||||
hydra.handleAttack(id);
|
||||
lastAttackTick = client.getTickCount();
|
||||
}
|
||||
}
|
||||
@@ -271,53 +270,4 @@ public class HydraPlugin extends Plugin
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(poisonOverlay);
|
||||
}
|
||||
|
||||
private void changePhase(HydraPhase newPhase)
|
||||
{
|
||||
hydra.setPhase(newPhase);
|
||||
hydra.setNextSpecial(3);
|
||||
hydra.setAttackCount(0);
|
||||
hydra.setWeakened(false);
|
||||
|
||||
if (newPhase == HydraPhase.FOUR)
|
||||
{
|
||||
hydra.setWeakened(true);
|
||||
switchStyles();
|
||||
hydra.setNextSwitch(newPhase.getAttacksPerSwitch());
|
||||
}
|
||||
}
|
||||
|
||||
private void switchStyles()
|
||||
{
|
||||
hydra.setNextAttack(hydra.getLastAttack() == Hydra.AttackStyle.MAGIC
|
||||
? Hydra.AttackStyle.RANGED
|
||||
: Hydra.AttackStyle.MAGIC);
|
||||
}
|
||||
|
||||
private void handleAttack(int id)
|
||||
{
|
||||
if (id != hydra.getNextAttack().getProjId() && id != hydra.getLastAttack().getProjId())
|
||||
{ // If the current attack isn't what was expected and we should have switched prayers
|
||||
switchStyles();
|
||||
hydra.setNextSwitch(hydra.getPhase().getAttacksPerSwitch() - 1);
|
||||
hydra.setLastAttack(hydra.getNextAttack());
|
||||
}
|
||||
else if (id != hydra.getNextAttack().getProjId() && id == hydra.getLastAttack().getProjId())
|
||||
{ // If the current attack isn't what was expected and we accidentally counted 1 too much
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra.setNextSwitch(hydra.getNextSwitch() - 1);
|
||||
hydra.setLastAttack(hydra.getNextAttack());
|
||||
}
|
||||
|
||||
hydra.setAttackCount(hydra.getAttackCount() + 1);
|
||||
|
||||
if (hydra.getNextSwitch() <= 0)
|
||||
{
|
||||
switchStyles();
|
||||
hydra.setNextSwitch(hydra.getPhase().getAttacksPerSwitch());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,13 +45,17 @@ import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@Singleton
|
||||
class HydraPoisonOverlay extends Overlay
|
||||
class HydraSceneOverlay extends Overlay
|
||||
{
|
||||
private static final Color GREEN = new Color(0, 255, 0, 100);
|
||||
private static final Color RED = new Color(255, 0, 0, 100);
|
||||
private static final Color REDFILL = new Color(255, 0, 0, 50);
|
||||
|
||||
private final HydraPlugin plugin;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public HydraPoisonOverlay(Client client, HydraPlugin plugin)
|
||||
public HydraSceneOverlay(Client client, HydraPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
@@ -99,9 +103,9 @@ class HydraPoisonOverlay extends Overlay
|
||||
}
|
||||
|
||||
graphics.setPaintMode();
|
||||
graphics.setColor(new Color(255, 0, 0, 100));
|
||||
graphics.setColor(RED);
|
||||
graphics.draw(poisonTiles);
|
||||
graphics.setColor(new Color(255, 0, 0, 50));
|
||||
graphics.setColor(REDFILL);
|
||||
graphics.fill(poisonTiles);
|
||||
}
|
||||
|
||||
@@ -133,11 +137,15 @@ class HydraPoisonOverlay extends Overlay
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = new Color(255, 0, 0, 100); // like
|
||||
Color color; // like
|
||||
|
||||
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
|
||||
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
|
||||
color = new Color(0, 255, 0, 100);
|
||||
color = GREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = RED;
|
||||
}
|
||||
|
||||
graphics.setColor(color);
|
||||
@@ -321,12 +321,12 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getWidgetId() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
&& event.getMenuAction() == MenuAction.RUNELITE
|
||||
&& event.getMenuOption().startsWith(EDIT_TAGS_MENU_OPTION))
|
||||
&& event.getOption().startsWith(EDIT_TAGS_MENU_OPTION))
|
||||
{
|
||||
event.consume();
|
||||
int inventoryIndex = event.getActionParam();
|
||||
int inventoryIndex = event.getActionParam0();
|
||||
ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK);
|
||||
if (bankContainer == null)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
@@ -230,9 +231,9 @@ public class TabInterface
|
||||
.filter(id -> id != -1)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!Strings.isNullOrEmpty(event.getMenuTarget()))
|
||||
if (!Strings.isNullOrEmpty(event.getTarget()))
|
||||
{
|
||||
if (activeTab != null && Text.removeTags(event.getMenuTarget()).equals(activeTab.getTag()))
|
||||
if (activeTab != null && Text.removeTags(event.getTarget()).equals(activeTab.getTag()))
|
||||
{
|
||||
for (Integer item : items)
|
||||
{
|
||||
@@ -564,9 +565,9 @@ public class TabInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getWidgetId() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
if (event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
&& event.getMenuAction() == MenuAction.EXAMINE_ITEM_BANK_EQ
|
||||
&& event.getMenuOption().equalsIgnoreCase("withdraw-x"))
|
||||
&& event.getOption().equalsIgnoreCase("withdraw-x"))
|
||||
{
|
||||
waitSearchTick = true;
|
||||
rememberedSearch = client.getVar(VarClientStr.INPUT_TEXT);
|
||||
@@ -575,9 +576,9 @@ public class TabInterface
|
||||
|
||||
if (iconToSet != null)
|
||||
{
|
||||
if (event.getMenuOption().startsWith(CHANGE_ICON + " ("))
|
||||
if (event.getOption().startsWith(CHANGE_ICON + " ("))
|
||||
{
|
||||
ItemDefinition item = getItem(event.getActionParam());
|
||||
ItemDefinition item = getItem(event.getActionParam0());
|
||||
int itemId = itemManager.canonicalize(item.getId());
|
||||
iconToSet.setIconItemId(itemId);
|
||||
iconToSet.getIcon().setItemId(itemId);
|
||||
@@ -590,7 +591,7 @@ public class TabInterface
|
||||
}
|
||||
|
||||
if (activeTab != null
|
||||
&& event.getMenuOption().equals("Search")
|
||||
&& event.getOption().equals("Search")
|
||||
&& client.getWidget(WidgetInfo.BANK_SEARCH_BUTTON_BACKGROUND).getSpriteId() != SpriteID.EQUIPMENT_SLOT_SELECTED)
|
||||
{
|
||||
activateTab(null);
|
||||
@@ -600,27 +601,27 @@ public class TabInterface
|
||||
client.setVar(VarClientInt.INPUT_TYPE, 0);
|
||||
}
|
||||
else if (activeTab != null
|
||||
&& event.getMenuOption().startsWith("View tab"))
|
||||
&& event.getOption().startsWith("View tab"))
|
||||
{
|
||||
activateTab(null);
|
||||
}
|
||||
else if (activeTab != null
|
||||
&& event.getWidgetId() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
&& event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
&& event.getMenuAction() == MenuAction.RUNELITE
|
||||
&& event.getMenuOption().startsWith(REMOVE_TAG))
|
||||
&& event.getOption().startsWith(REMOVE_TAG))
|
||||
{
|
||||
// Add "remove" menu entry to all items in bank while tab is selected
|
||||
event.consume();
|
||||
final ItemDefinition item = getItem(event.getActionParam());
|
||||
final ItemDefinition item = getItem(event.getActionParam0());
|
||||
final int itemId = item.getId();
|
||||
tagManager.removeTag(itemId, activeTab.getTag());
|
||||
bankSearch.search(InputType.SEARCH, TAG_SEARCH + activeTab.getTag(), true);
|
||||
}
|
||||
else if (event.getMenuAction() == MenuAction.RUNELITE
|
||||
&& ((event.getWidgetId() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getMenuOption().equals(TAG_INVENTORY))
|
||||
|| (event.getWidgetId() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getMenuOption().equals(TAG_GEAR))))
|
||||
&& ((event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId() && event.getOption().equals(TAG_INVENTORY))
|
||||
|| (event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_EQUIPMENT.getId() && event.getOption().equals(TAG_GEAR))))
|
||||
{
|
||||
handleDeposit(event, event.getWidgetId() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId());
|
||||
handleDeposit(event, event.getActionParam1() == WidgetInfo.BANK_DEPOSIT_INVENTORY.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,7 +731,13 @@ public class TabInterface
|
||||
|
||||
if (tagTab.getIcon() == null)
|
||||
{
|
||||
Widget icon = createGraphic(ColorUtil.wrapWithColorTag(tagTab.getTag(), HILIGHT_COLOR), -1, tagTab.getIconItemId(), 36, 32, bounds.x + 3, 1, false);
|
||||
Widget icon = createGraphic(
|
||||
ColorUtil.wrapWithColorTag(tagTab.getTag(), HILIGHT_COLOR),
|
||||
-1,
|
||||
tagTab.getIconItemId(),
|
||||
Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT,
|
||||
bounds.x + 3, 1,
|
||||
false);
|
||||
int clickmask = icon.getClickMask();
|
||||
clickmask |= WidgetConfig.DRAG;
|
||||
clickmask |= WidgetConfig.DRAG_ON;
|
||||
|
||||
@@ -27,12 +27,10 @@
|
||||
package net.runelite.client.plugins.banlist;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.ClanMember;
|
||||
@@ -62,12 +60,12 @@ import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Ban List",
|
||||
description = "Displays warning in chat when you join a" +
|
||||
"clan chat/new member join your clan chat and he is in a WDR/RuneWatch/Manual List",
|
||||
tags = {"PVM", "WDR", "RuneWatch"},
|
||||
type = PluginType.UTILITY,
|
||||
enabledByDefault = false
|
||||
name = "Ban List",
|
||||
description = "Displays warning in chat when you join a" +
|
||||
"clan chat/new member join your clan chat and he is in a WDR/RuneWatch/Manual List",
|
||||
tags = {"PVM", "WDR", "RuneWatch"},
|
||||
type = PluginType.UTILITY,
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
@@ -137,10 +135,10 @@ public class BanListPlugin extends Plugin
|
||||
public void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN
|
||||
|| client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN) != null
|
||||
|| client.getViewportWidget() == null
|
||||
|| client.getWidget(WidgetInfo.CLAN_CHAT) == null
|
||||
|| !config.highlightInClan())
|
||||
|| client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN) != null
|
||||
|| client.getViewportWidget() == null
|
||||
|| client.getWidget(WidgetInfo.CLAN_CHAT) == null
|
||||
|| !config.highlightInClan())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -159,10 +157,21 @@ public class BanListPlugin extends Plugin
|
||||
public void onClanMemberJoined(ClanMemberJoined event)
|
||||
{
|
||||
ClanMember member = event.getMember();
|
||||
ListType listType = checkBanList(Text.standardize(member.getUsername()));
|
||||
if (listType != null)
|
||||
ListType scamList = checkScamList(Text.standardize(member.getUsername()));
|
||||
ListType toxicList = checkToxicList(Text.standardize(member.getUsername()));
|
||||
|
||||
if (scamList != null)
|
||||
{
|
||||
sendWarning(Text.standardize(member.getUsername()), listType);
|
||||
sendWarning(Text.standardize(member.getUsername()), scamList);
|
||||
if (config.highlightInClan())
|
||||
{
|
||||
highlightRedInCC();
|
||||
}
|
||||
}
|
||||
|
||||
if (toxicList != null)
|
||||
{
|
||||
sendWarning(Text.standardize(member.getUsername()), toxicList);
|
||||
if (config.highlightInClan())
|
||||
{
|
||||
highlightRedInCC();
|
||||
@@ -184,10 +193,14 @@ public class BanListPlugin extends Plugin
|
||||
{
|
||||
Widget tradingWith = client.getWidget(335, 31);
|
||||
String name = tradingWith.getText().replaceAll("Trading With: ", "");
|
||||
if (checkBanList(name) != null)
|
||||
if (checkScamList(name) != null)
|
||||
{
|
||||
tradingWith.setText(tradingWith.getText().replaceAll(name, "<col=ff0000>" + name + " (Scammer)" + "</col>"));
|
||||
}
|
||||
if (checkToxicList(name) != null)
|
||||
{
|
||||
tradingWith.setText(tradingWith.getText().replaceAll(name, "<col=ff6400>" + name + " (Toxic)" + "</col>"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -196,7 +209,7 @@ public class BanListPlugin extends Plugin
|
||||
/**
|
||||
* Compares player name to everything in the ban lists
|
||||
*/
|
||||
private ListType checkBanList(String nameToBeChecked)
|
||||
private ListType checkScamList(String nameToBeChecked)
|
||||
{
|
||||
if (wdrScamArrayList.size() > 0 && config.enableWDR())
|
||||
{
|
||||
@@ -206,14 +219,6 @@ public class BanListPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
if (wdrToxicArrayList.size() > 0 && config.enableWDR())
|
||||
{
|
||||
if (wdrToxicArrayList.stream().anyMatch(nameToBeChecked::equalsIgnoreCase))
|
||||
{
|
||||
return ListType.WEDORAIDSTOXIC_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (runeWatchArrayList.size() > 0 && config.enableRuneWatch())
|
||||
{
|
||||
if (runeWatchArrayList.stream().anyMatch(nameToBeChecked::equalsIgnoreCase))
|
||||
@@ -233,6 +238,20 @@ public class BanListPlugin extends Plugin
|
||||
return null;
|
||||
}
|
||||
|
||||
private ListType checkToxicList(String nameToBeChecked)
|
||||
{
|
||||
|
||||
if (wdrToxicArrayList.size() > 0 && config.enableWDR())
|
||||
{
|
||||
if (wdrToxicArrayList.stream().anyMatch(nameToBeChecked::equalsIgnoreCase))
|
||||
{
|
||||
return ListType.WEDORAIDSTOXIC_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a warning to our player, notifying them that a player is on a ban list
|
||||
*/
|
||||
@@ -242,53 +261,53 @@ public class BanListPlugin extends Plugin
|
||||
{
|
||||
case WEDORAIDSSCAM_LIST:
|
||||
final String wdr__scam_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on WeDoRaids\' scammer list!")
|
||||
.build();
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on WeDoRaids\' scammer list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(wdr__scam_message)
|
||||
.build());
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(wdr__scam_message)
|
||||
.build());
|
||||
break;
|
||||
|
||||
case WEDORAIDSTOXIC_LIST:
|
||||
final String wdr__toxic_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on WeDoRaids\' toxic list!")
|
||||
.build();
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on WeDoRaids\' toxic list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(wdr__toxic_message)
|
||||
.build());
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(wdr__toxic_message)
|
||||
.build());
|
||||
break;
|
||||
|
||||
case RUNEWATCH_LIST:
|
||||
final String rw_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on the Runewatch\'s scammer list!")
|
||||
.build();
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on the Runewatch\'s scammer list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(rw_message)
|
||||
.build());
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(rw_message)
|
||||
.build());
|
||||
break;
|
||||
case MANUAL_LIST:
|
||||
final String manual_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on your manual scammer list!")
|
||||
.build();
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on your manual scammer list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(manual_message)
|
||||
.build());
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(manual_message)
|
||||
.build());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -299,8 +318,8 @@ public class BanListPlugin extends Plugin
|
||||
private void fetchFromWebsites()
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url("https://wdrdev.github.io/index")
|
||||
.build();
|
||||
.url("https://wdrdev.github.io/index")
|
||||
.build();
|
||||
RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
@@ -327,8 +346,8 @@ public class BanListPlugin extends Plugin
|
||||
|
||||
|
||||
Request secondRequest = new Request.Builder()
|
||||
.url("https://runewatch.com/incident-index-page/")
|
||||
.build();
|
||||
.url("https://runewatch.com/incident-index-page/")
|
||||
.build();
|
||||
RuneLiteAPI.CLIENT.newCall(secondRequest).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
@@ -356,8 +375,8 @@ public class BanListPlugin extends Plugin
|
||||
});
|
||||
|
||||
Request thirdRequest = new Request.Builder()
|
||||
.url("https://wdrdev.github.io/toxic")
|
||||
.build();
|
||||
.url("https://wdrdev.github.io/toxic")
|
||||
.build();
|
||||
RuneLiteAPI.CLIENT.newCall(thirdRequest).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
@@ -393,13 +412,18 @@ public class BanListPlugin extends Plugin
|
||||
Widget widget = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
|
||||
for (Widget widgetChild : widget.getDynamicChildren())
|
||||
{
|
||||
ListType listType = checkBanList(widgetChild.getText());
|
||||
ListType scamList = checkScamList(widgetChild.getText());
|
||||
ListType toxicList = checkToxicList(widgetChild.getText());
|
||||
|
||||
if (listType != null)
|
||||
if (scamList != null)
|
||||
{
|
||||
widgetChild.setText("<col=ff0000>" + widgetChild.getText() + "</col>");
|
||||
}
|
||||
else if (toxicList != null)
|
||||
{
|
||||
widgetChild.setText("<col=ff6400>" + widgetChild.getText() + "</col>");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,21 +707,21 @@ public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
String target = event.getMenuTarget();
|
||||
String target = event.getTarget();
|
||||
|
||||
if (config.tagging() && (event.getMenuTarget().contains("Penance Ranger") || event.getMenuTarget().contains("Penance Fighter")))
|
||||
if (config.tagging() && (event.getTarget().contains("Penance Ranger") || event.getTarget().contains("Penance Fighter")))
|
||||
{
|
||||
if (event.getMenuOption().contains("Attack"))
|
||||
if (event.getOption().contains("Attack"))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
foodPressed.put(event.getIdentifier(), Instant.now());
|
||||
}
|
||||
log.info(target);
|
||||
}
|
||||
|
||||
if (config.healerMenuOption() && target.contains("Penance Healer") && target.contains("<col=ff9040>Poisoned") && target.contains("->"))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
lastHealer = event.getId();
|
||||
foodPressed.put(event.getIdentifier(), Instant.now());
|
||||
lastHealer = event.getIdentifier();
|
||||
log.info("Last healer changed: " + lastHealer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public enum CannonSpots
|
||||
|
||||
BLOODVELDS(new WorldPoint(2439, 9821, 0), new WorldPoint(2448, 9821, 0), new WorldPoint(2472, 9833, 0), new WorldPoint(2453, 9817, 0)),
|
||||
FIRE_GIANTS(new WorldPoint(2393, 9782, 0), new WorldPoint(2412, 9776, 0), new WorldPoint(2401, 9780, 0)),
|
||||
ABBERANT_SPECTRES(new WorldPoint(2456, 9791, 0)),
|
||||
ABERRANT_SPECTRES(new WorldPoint(2456, 9791, 0)),
|
||||
HELLHOUNDS(new WorldPoint(2431, 9776, 0), new WorldPoint(2413, 9786, 0), new WorldPoint(2783, 9686, 0), new WorldPoint(3198, 10071, 0)),
|
||||
BLACK_DEMONS(new WorldPoint(2859, 9778, 0), new WorldPoint(2841, 9791, 0)),
|
||||
ELVES(new WorldPoint(2044, 4635, 0)),
|
||||
|
||||
@@ -168,7 +168,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
String menuOption = event.getMenuOption();
|
||||
String menuOption = event.getOption();
|
||||
|
||||
if (menuOption.contains(CLEAR_HISTORY))
|
||||
{
|
||||
|
||||
@@ -129,9 +129,12 @@ public class ChatNotificationsPlugin extends Plugin
|
||||
{
|
||||
List<String> items = Text.fromCSV(config.highlightWordsString());
|
||||
String joined = items.stream()
|
||||
.map(Text::escapeJagex) // we compare these strings to the raw Jagex ones
|
||||
.map(Pattern::quote)
|
||||
.collect(Collectors.joining("|"));
|
||||
highlightMatcher = Pattern.compile("\\b(" + joined + ")\\b", Pattern.CASE_INSENSITIVE);
|
||||
// To match <word> \b doesn't work due to <> not being in \w,
|
||||
// so match \b or \s
|
||||
highlightMatcher = Pattern.compile("(?:\\b|(?<=\\s))(" + joined + ")(?:\\b|(?=\\s))", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +142,6 @@ public class ChatNotificationsPlugin extends Plugin
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
MessageNode messageNode = chatMessage.getMessageNode();
|
||||
String nodeValue = Text.removeTags(messageNode.getValue());
|
||||
boolean update = false;
|
||||
|
||||
switch (chatMessage.getType())
|
||||
@@ -202,6 +204,7 @@ public class ChatNotificationsPlugin extends Plugin
|
||||
|
||||
if (highlightMatcher != null)
|
||||
{
|
||||
String nodeValue = messageNode.getValue();
|
||||
Matcher matcher = highlightMatcher.matcher(nodeValue);
|
||||
boolean found = false;
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
@@ -3,29 +3,22 @@ package net.runelite.client.plugins.clanmanmode;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Clan Man Mode",
|
||||
@@ -37,10 +30,6 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class ClanManModePlugin extends Plugin
|
||||
{
|
||||
|
||||
private static final String WALK_HERE = "WALK HERE";
|
||||
private static final String CANCEL = "CANCEL";
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@@ -59,18 +48,6 @@ public class ClanManModePlugin extends Plugin
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClanManager clanManager;
|
||||
|
||||
private static final String CAST = "CAST";
|
||||
private static final String ATTACK_OPTIONS_ATTACK = "ATTACK";
|
||||
public static final HashSet<String> ATTACK_OPTIONS_KEYWORDS = new HashSet<>();
|
||||
static
|
||||
{
|
||||
ATTACK_OPTIONS_KEYWORDS.add(CAST);
|
||||
ATTACK_OPTIONS_KEYWORDS.add(ATTACK_OPTIONS_ATTACK);
|
||||
}
|
||||
|
||||
@Provides
|
||||
ClanManModeConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -90,6 +67,7 @@ public class ClanManModePlugin extends Plugin
|
||||
overlayManager.add(ClanManModeOverlay);
|
||||
overlayManager.add(ClanManModeTileOverlay);
|
||||
overlayManager.add(ClanManModeMinimapOverlay);
|
||||
client.setHideFriendAttackOptions(config.hideAtkOpt());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,6 +76,7 @@ public class ClanManModePlugin extends Plugin
|
||||
overlayManager.remove(ClanManModeOverlay);
|
||||
overlayManager.remove(ClanManModeTileOverlay);
|
||||
overlayManager.remove(ClanManModeMinimapOverlay);
|
||||
client.setHideFriendAttackOptions(false);
|
||||
clan.clear();
|
||||
ticks = 0;
|
||||
wildernessLevel = 0;
|
||||
@@ -106,6 +85,17 @@ public class ClanManModePlugin extends Plugin
|
||||
inwildy = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!"clanmanmode".equals(event.getGroup()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.setHideFriendAttackOptions(config.hideAtkOpt());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
@@ -135,111 +125,4 @@ public class ClanManModePlugin extends Plugin
|
||||
clanmax = Collections.max(clan.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Player[] players = client.getCachedPlayers();
|
||||
Player player = null;
|
||||
int identifier = event.getIdentifier();
|
||||
|
||||
if (identifier >= 0 && identifier < players.length)
|
||||
{
|
||||
player = players[identifier];
|
||||
}
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase();
|
||||
|
||||
//If the option is already to walk there, or cancel we don't need to swap it with anything
|
||||
if (pOptionToReplace.equals(CANCEL) || pOptionToReplace.equals(WALK_HERE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.hideAtkOpt()
|
||||
&& ATTACK_OPTIONS_KEYWORDS.contains(pOptionToReplace)
|
||||
&& (player.isFriend() || player.isClanMember()))
|
||||
{
|
||||
swap(pOptionToReplace);
|
||||
}
|
||||
else if (!config.hideAtkOpt())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
|
||||
if (option.equals("attack"))
|
||||
{
|
||||
final Pattern ppattern = Pattern.compile("<col=ffffff>(.+?)<col=");
|
||||
final Matcher pmatch = ppattern.matcher(event.getTarget());
|
||||
|
||||
if (pmatch.find() && pmatch.matches())
|
||||
{
|
||||
if (pmatch.group(1) != null)
|
||||
{
|
||||
if (clan.containsKey(pmatch.group(1).replace(" ", " ")))
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
entries = ArrayUtils.removeElement(entries, entries[entries.length - 1]);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps menu entries if the entries could be found. This places Walk Here where the top level menu option was.
|
||||
* @param pOptionToReplace The String containing the Menu Option that needs to be replaced. IE: "Attack", "Chop Down".
|
||||
*/
|
||||
private void swap(String pOptionToReplace)
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
Integer walkHereEntry = searchIndex(entries, WALK_HERE);
|
||||
Integer entryToReplace = searchIndex(entries, pOptionToReplace);
|
||||
|
||||
if (walkHereEntry != null
|
||||
&& entryToReplace != null)
|
||||
{
|
||||
MenuEntry walkHereMenuEntry = entries[walkHereEntry];
|
||||
entries[walkHereEntry] = entries[entryToReplace];
|
||||
entries[entryToReplace] = walkHereMenuEntry;
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the index of the menu that contains the verbiage we are looking for.
|
||||
* @param pMenuEntries The list of {@link MenuEntry}s.
|
||||
* @param pMenuEntryToSearchFor The Option in the menu to search for.
|
||||
* @return The index location or null if it was not found.
|
||||
*/
|
||||
private Integer searchIndex(MenuEntry[] pMenuEntries, String pMenuEntryToSearchFor)
|
||||
{
|
||||
Integer indexLocation = 0;
|
||||
|
||||
for (MenuEntry menuEntry : pMenuEntries)
|
||||
{
|
||||
String entryOption = Text.removeTags(menuEntry.getOption()).toUpperCase();
|
||||
|
||||
if (entryOption.equals(pMenuEntryToSearchFor))
|
||||
{
|
||||
return indexLocation;
|
||||
}
|
||||
indexLocation++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,9 +225,9 @@ public class ClueScrollPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(final MenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuOption() != null && event.getMenuOption().equals("Read"))
|
||||
if (event.getOption() != null && event.getOption().equals("Read"))
|
||||
{
|
||||
final ItemDefinition itemComposition = itemManager.getItemDefinition(event.getId());
|
||||
final ItemDefinition itemComposition = itemManager.getItemDefinition(event.getIdentifier());
|
||||
|
||||
if (itemComposition != null && itemComposition.getName().startsWith("Clue scroll"))
|
||||
{
|
||||
|
||||
@@ -259,7 +259,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("Search the drawers in Catherby's Archery shop.", DRAWERS_350, new WorldPoint(2825, 3442, 0), "Hickton's Archery Emporium in Catherby."),
|
||||
new CrypticClue("The hand ain't listening.", "The Face", new WorldPoint(3019, 3232, 0), "Talk to The Face located by the manhole just north of the Port Sarim fishing shop."),
|
||||
new CrypticClue("Search the chest in the left-hand tower of Camelot Castle.", CLOSED_CHEST_25592, new WorldPoint(2748, 3495, 2), "Located on the second floor of the western tower of Camelot."),
|
||||
new CrypticClue("Kill the spiritual, magic and godly whilst representing their own god", null, "Kill a spiritual mage while wearing a corresponding god item."),
|
||||
new CrypticClue("Kill the spiritual, magic and godly whilst representing their own god.", null, "Kill a spiritual mage while wearing a corresponding god item."),
|
||||
new CrypticClue("Anger those who adhere to Saradomin's edicts to prevent travel.", "Monk of Entrana", new WorldPoint(3042, 3236, 0), "Port Sarim Docks, try to charter a ship to Entrana with armour or weapons equipped."),
|
||||
new CrypticClue("South of a river in a town surrounded by the undead, what lies beneath the furnace?", new WorldPoint(2857, 2966, 0), "Dig in front of the Shilo Village furnace."),
|
||||
new CrypticClue("Talk to the Squire in the White Knights' castle in Falador.", "Squire", new WorldPoint(2977, 3343, 0), "The squire is located in the courtyard of the White Knights' Castle."),
|
||||
|
||||
@@ -87,11 +87,11 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
|
||||
new FaloTheBardClue("A shiny helmet of flight, to obtain this with melee, struggle you might.", item(ARMADYL_HELMET)),
|
||||
// The wiki doesn't specify whether the trimmed dragon defender will work so I've assumed that it doesn't
|
||||
new FaloTheBardClue("A sword held in the other hand, red its colour, Cyclops strength you must withstand.", item(DRAGON_DEFENDER)),
|
||||
new FaloTheBardClue("A token used to kill mythical beasts, in hope of a blade or just for an xp feast.", item(WARRIOR_GUILD_TOKEN)),
|
||||
new FaloTheBardClue("A token used to kill mythical beasts, in hopes of a blade or just for an xp feast.", item(WARRIOR_GUILD_TOKEN)),
|
||||
new FaloTheBardClue("Green is my favorite, mature ale I do love, this takes your herblore above.", item(GREENMANS_ALEM)),
|
||||
new FaloTheBardClue("It can hold down a boat or crush a goat, this object, you see, is quite heavy.", item(BARRELCHEST_ANCHOR)),
|
||||
new FaloTheBardClue("It comes from the ground, underneath the snowy plain. Trolls aplenty, with what looks like a mane.", item(BASALT)),
|
||||
new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian but with no room for a shield.", item(TZHAARKETOM)),
|
||||
new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian, but with no room for a shield.", item(TZHAARKETOM)),
|
||||
new FaloTheBardClue("Penance healers runners and more, obtaining this body often gives much deplore.", item(FIGHTER_TORSO)),
|
||||
new FaloTheBardClue("Strangely found in a chest, many believe these gloves are the best.", item(BARROWS_GLOVES)),
|
||||
new FaloTheBardClue("These gloves of white won't help you fight, but aid in cooking, they just might.", item(COOKING_GAUNTLETS)),
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
@@ -64,7 +65,8 @@ public class CoxInfoBox extends Overlay
|
||||
this.client = client;
|
||||
this.spriteManager = spriteManager;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPosition(OverlayPosition.DETACHED);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,7 +105,7 @@ public class CoxInfoBox extends Overlay
|
||||
plugin.setPrayAgainstOlm(null);
|
||||
}
|
||||
|
||||
if (config.vangHealth() && plugin.isRunVanguard())
|
||||
if (config.vangHealth() && plugin.getVanguards() > 0)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Vanguards")
|
||||
|
||||
@@ -108,7 +108,7 @@ public class CoxPlugin extends Plugin
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean runOlm;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean runVanguard;
|
||||
private int vanguards;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean tektonActive;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@@ -165,13 +165,6 @@ public class CoxPlugin extends Plugin
|
||||
{
|
||||
overlayManager.add(coxOverlay);
|
||||
overlayManager.add(coxInfoBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
overlayManager.remove(coxOverlay);
|
||||
overlayManager.remove(coxInfoBox);
|
||||
HandCripple = false;
|
||||
hand = null;
|
||||
acidTarget = null;
|
||||
@@ -183,6 +176,14 @@ public class CoxPlugin extends Plugin
|
||||
burnTicks = 40;
|
||||
acidTicks = 25;
|
||||
teleportTicks = 10;
|
||||
vanguards = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
overlayManager.remove(coxOverlay);
|
||||
overlayManager.remove(coxInfoBox);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -226,22 +227,30 @@ public class CoxPlugin extends Plugin
|
||||
needOlm = true;
|
||||
Olm_NextSpec = -1;
|
||||
break;
|
||||
case "the great olm's left claw clenches to protect itself temporarily.":
|
||||
HandCripple = true;
|
||||
timer = 45;
|
||||
break;
|
||||
case "the great olm fires a sphere of aggression your way. your prayers have been sapped.":
|
||||
prayAgainstOlm = PrayAgainst.MELEE;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of aggression your way.":
|
||||
prayAgainstOlm = PrayAgainst.MELEE;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of magical power your way. your prayers have been sapped.":
|
||||
prayAgainstOlm = PrayAgainst.MAGIC;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of magical power your way.":
|
||||
prayAgainstOlm = PrayAgainst.MAGIC;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of accuracy and dexterity your way. your prayers have been sapped.":
|
||||
prayAgainstOlm = PrayAgainst.RANGED;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
case "the great olm fires a sphere of accuracy and dexterity your way.":
|
||||
prayAgainstOlm = PrayAgainst.RANGED;
|
||||
lastPrayTime = System.currentTimeMillis();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -316,7 +325,7 @@ public class CoxPlugin extends Plugin
|
||||
case NpcID.VANGUARD_7527:
|
||||
case NpcID.VANGUARD_7528:
|
||||
case NpcID.VANGUARD_7529:
|
||||
runVanguard = true;
|
||||
vanguards++;
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.GREAT_OLM_LEFT_CLAW:
|
||||
@@ -362,7 +371,7 @@ public class CoxPlugin extends Plugin
|
||||
{
|
||||
npcContainer.remove(event.getNpc());
|
||||
}
|
||||
runVanguard = false;
|
||||
vanguards--;
|
||||
break;
|
||||
case NpcID.GREAT_OLM_RIGHT_CLAW_7553:
|
||||
case NpcID.GREAT_OLM_RIGHT_CLAW:
|
||||
@@ -513,16 +522,22 @@ public class CoxPlugin extends Plugin
|
||||
}
|
||||
break;
|
||||
case NpcID.VANGUARD_7529:
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MAGE);
|
||||
if (npcs.getAttackStyle() == NPCContainer.Attackstyle.UNKNOWN)
|
||||
{
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MAGE);
|
||||
}
|
||||
break;
|
||||
case NpcID.VANGUARD_7528:
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.RANGE);
|
||||
if (npcs.getAttackStyle() == NPCContainer.Attackstyle.UNKNOWN)
|
||||
{
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.RANGE);
|
||||
}
|
||||
break;
|
||||
case NpcID.VANGUARD_7527:
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MELEE);
|
||||
break;
|
||||
case NpcID.VANGUARD_7526:
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.UNKNOWN);
|
||||
if (npcs.getAttackStyle() == NPCContainer.Attackstyle.UNKNOWN)
|
||||
{
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MELEE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ package net.runelite.client.plugins.emojis;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import joptsimple.internal.Strings;
|
||||
@@ -52,6 +54,8 @@ import net.runelite.client.util.ImageUtil;
|
||||
@Slf4j
|
||||
public class EmojiPlugin extends Plugin
|
||||
{
|
||||
private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>");
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@@ -128,7 +132,8 @@ public class EmojiPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
final String message = chatMessage.getMessage();
|
||||
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||
final String message = messageNode.getValue();
|
||||
final String updatedMessage = updateMessage(message);
|
||||
|
||||
if (updatedMessage == null)
|
||||
@@ -136,7 +141,6 @@ public class EmojiPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||
messageNode.setRuneLiteFormatMessage(updatedMessage);
|
||||
chatMessageManager.update(messageNode);
|
||||
client.refreshChat();
|
||||
@@ -169,7 +173,9 @@ public class EmojiPlugin extends Plugin
|
||||
boolean editedMessage = false;
|
||||
for (int i = 0; i < messageWords.length; i++)
|
||||
{
|
||||
final Emoji emoji = Emoji.getEmoji(messageWords[i]);
|
||||
// Remove tags except for <lt> and <gt>
|
||||
final String trigger = removeTags(messageWords[i]);
|
||||
final Emoji emoji = Emoji.getEmoji(trigger);
|
||||
|
||||
if (emoji == null)
|
||||
{
|
||||
@@ -178,7 +184,7 @@ public class EmojiPlugin extends Plugin
|
||||
|
||||
final int emojiId = modIconsStart + emoji.ordinal();
|
||||
|
||||
messageWords[i] = "<img=" + emojiId + ">";
|
||||
messageWords[i] = messageWords[i].replace(trigger, "<img=" + emojiId + ">");
|
||||
editedMessage = true;
|
||||
}
|
||||
|
||||
@@ -190,4 +196,29 @@ public class EmojiPlugin extends Plugin
|
||||
|
||||
return Strings.join(messageWords, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove tags, except for <lt> and <gt>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static String removeTags(String str)
|
||||
{
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
Matcher matcher = TAG_REGEXP.matcher(str);
|
||||
while (matcher.find())
|
||||
{
|
||||
matcher.appendReplacement(stringBuffer, "");
|
||||
String match = matcher.group(0);
|
||||
switch (match)
|
||||
{
|
||||
case "<lt>":
|
||||
case "<gt>":
|
||||
stringBuffer.append(match);
|
||||
break;
|
||||
}
|
||||
}
|
||||
matcher.appendTail(stringBuffer);
|
||||
return stringBuffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class ExaminePlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (!event.getMenuOption().equals("Examine"))
|
||||
if (!event.getOption().equals("Examine"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -116,20 +116,20 @@ public class ExaminePlugin extends Plugin
|
||||
case EXAMINE_ITEM:
|
||||
{
|
||||
type = ExamineType.ITEM;
|
||||
id = event.getId();
|
||||
id = event.getIdentifier();
|
||||
|
||||
int widgetId = event.getWidgetId();
|
||||
int widgetId = event.getActionParam1();
|
||||
int widgetGroup = TO_GROUP(widgetId);
|
||||
int widgetChild = TO_CHILD(widgetId);
|
||||
Widget widget = client.getWidget(widgetGroup, widgetChild);
|
||||
WidgetItem widgetItem = widget.getWidgetItem(event.getActionParam());
|
||||
WidgetItem widgetItem = widget.getWidgetItem(event.getActionParam0());
|
||||
quantity = widgetItem != null && widgetItem.getId() >= 0 ? widgetItem.getQuantity() : 1;
|
||||
break;
|
||||
}
|
||||
case EXAMINE_ITEM_BANK_EQ:
|
||||
{
|
||||
type = ExamineType.ITEM_BANK_EQ;
|
||||
int[] qi = findItemFromWidget(event.getWidgetId(), event.getActionParam());
|
||||
int[] qi = findItemFromWidget(event.getActionParam1(), event.getActionParam0());
|
||||
if (qi == null)
|
||||
{
|
||||
log.debug("Examine for item with unknown widget: {}", event);
|
||||
@@ -141,11 +141,11 @@ public class ExaminePlugin extends Plugin
|
||||
}
|
||||
case EXAMINE_OBJECT:
|
||||
type = ExamineType.OBJECT;
|
||||
id = event.getId();
|
||||
id = event.getIdentifier();
|
||||
break;
|
||||
case EXAMINE_NPC:
|
||||
type = ExamineType.NPC;
|
||||
id = event.getId();
|
||||
id = event.getIdentifier();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -199,26 +199,26 @@ public class ExaminePlugin extends Plugin
|
||||
log.debug("Got examine for {} {}: {}", pendingExamine.getType(), pendingExamine.getId(), event.getMessage());
|
||||
|
||||
// If it is an item, show the price of it
|
||||
final ItemDefinition itemComposition;
|
||||
final ItemDefinition Itemdefinition;
|
||||
if (pendingExamine.getType() == ExamineType.ITEM || pendingExamine.getType() == ExamineType.ITEM_BANK_EQ)
|
||||
{
|
||||
final int itemId = pendingExamine.getId();
|
||||
final int itemQuantity = pendingExamine.getQuantity();
|
||||
itemComposition = itemManager.getItemDefinition(itemId);
|
||||
Itemdefinition = itemManager.getItemDefinition(itemId);
|
||||
|
||||
if (itemComposition != null)
|
||||
if (Itemdefinition != null)
|
||||
{
|
||||
final int id = itemManager.canonicalize(itemComposition.getId());
|
||||
executor.submit(() -> getItemPrice(id, itemComposition, itemQuantity));
|
||||
final int id = itemManager.canonicalize(Itemdefinition.getId());
|
||||
executor.submit(() -> getItemPrice(id, Itemdefinition, itemQuantity));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
itemComposition = null;
|
||||
Itemdefinition = null;
|
||||
}
|
||||
|
||||
// Don't submit examine info for tradeable items, which we already have from the RS item api
|
||||
if (itemComposition != null && itemComposition.isTradeable())
|
||||
if (Itemdefinition != null && Itemdefinition.isTradeable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
|
||||
class WaveOverlay extends Overlay
|
||||
{
|
||||
@@ -97,14 +98,19 @@ class WaveOverlay extends Overlay
|
||||
.color(HEADER_COLOR)
|
||||
.build());
|
||||
|
||||
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.CENTER);
|
||||
|
||||
for (String line : buildWaveLines(waveContents))
|
||||
{
|
||||
tableComponent.addRow(line);
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
if (!tableComponent.isEmpty())
|
||||
{
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<String> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
|
||||
@@ -45,6 +45,7 @@ public class FpsDrawListener implements Runnable
|
||||
private static final int SAMPLE_SIZE = 4;
|
||||
|
||||
private final FpsConfig config;
|
||||
private final FpsPlugin plugin;
|
||||
|
||||
private long targetDelay = 0;
|
||||
|
||||
@@ -58,9 +59,10 @@ public class FpsDrawListener implements Runnable
|
||||
private long sleepDelay = 0;
|
||||
|
||||
@Inject
|
||||
private FpsDrawListener(FpsConfig config)
|
||||
private FpsDrawListener(FpsConfig config, FpsPlugin plugin)
|
||||
{
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@@ -83,8 +85,8 @@ public class FpsDrawListener implements Runnable
|
||||
|
||||
private boolean isEnforced()
|
||||
{
|
||||
return FpsLimitMode.ALWAYS == config.limitMode()
|
||||
|| (FpsLimitMode.UNFOCUSED == config.limitMode() && !isFocused);
|
||||
return FpsLimitMode.ALWAYS == plugin.getLimitMode()
|
||||
|| (FpsLimitMode.UNFOCUSED == plugin.getLimitMode() && !isFocused);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -50,7 +50,6 @@ import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
public class FpsOverlay extends Overlay
|
||||
{
|
||||
// Local dependencies
|
||||
private final FpsConfig config;
|
||||
private final Client client;
|
||||
private final FpsPlugin plugin;
|
||||
|
||||
@@ -58,9 +57,8 @@ public class FpsOverlay extends Overlay
|
||||
private boolean isFocused = true;
|
||||
|
||||
@Inject
|
||||
private FpsOverlay(FpsPlugin plugin, FpsConfig config, Client client)
|
||||
private FpsOverlay(FpsPlugin plugin, Client client)
|
||||
{
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
@@ -75,8 +73,8 @@ public class FpsOverlay extends Overlay
|
||||
|
||||
private boolean isEnforced()
|
||||
{
|
||||
return FpsLimitMode.ALWAYS == config.limitMode()
|
||||
|| (FpsLimitMode.UNFOCUSED == config.limitMode() && !isFocused);
|
||||
return FpsLimitMode.ALWAYS == plugin.getLimitMode()
|
||||
|| (FpsLimitMode.UNFOCUSED == plugin.getLimitMode() && !isFocused);
|
||||
}
|
||||
|
||||
private Color getFpsValueColor()
|
||||
@@ -110,7 +108,7 @@ public class FpsOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!config.drawFps() && !config.drawPing())
|
||||
if (!plugin.isDrawFps() && !plugin.isDrawPing())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -121,7 +119,7 @@ public class FpsOverlay extends Overlay
|
||||
|
||||
int baseYOffset = (fontMetrics.getAscent() - fontMetrics.getDescent()) + 1;
|
||||
|
||||
if (config.drawFps())
|
||||
if (plugin.isDrawFps())
|
||||
{
|
||||
final String fpsText = String.format("%d FPS", client.getFPS());
|
||||
final int textWidth = fontMetrics.stringWidth(fpsText);
|
||||
@@ -132,7 +130,7 @@ public class FpsOverlay extends Overlay
|
||||
baseYOffset += 11;
|
||||
}
|
||||
|
||||
if (config.drawPing())
|
||||
if (plugin.isDrawPing())
|
||||
{
|
||||
final String pingText = String.format("%dms", plugin.getPing());
|
||||
final int textWidth = fontMetrics.stringWidth(pingText);
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.google.inject.Provides;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
@@ -90,6 +91,15 @@ public class FpsPlugin extends Plugin
|
||||
|
||||
private final ScheduledExecutorService pingExecutorService = new ExecutorServiceExceptionLogger(Executors.newSingleThreadScheduledExecutor());
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private FpsLimitMode limitMode;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean drawFps;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean drawPing;
|
||||
|
||||
@Provides
|
||||
FpsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -102,6 +112,10 @@ public class FpsPlugin extends Plugin
|
||||
if (event.getGroup().equals(CONFIG_GROUP_KEY))
|
||||
{
|
||||
drawListener.reloadConfig();
|
||||
|
||||
limitMode = fpsConfig.limitMode();
|
||||
drawFps = fpsConfig.drawFps();
|
||||
drawPing = fpsConfig.drawPing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +129,9 @@ public class FpsPlugin extends Plugin
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
limitMode = fpsConfig.limitMode();
|
||||
drawFps = fpsConfig.drawFps();
|
||||
drawPing = fpsConfig.drawPing();
|
||||
overlayManager.add(overlay);
|
||||
drawManager.registerEveryFrameListener(drawListener);
|
||||
drawListener.reloadConfig();
|
||||
@@ -131,7 +148,7 @@ public class FpsPlugin extends Plugin
|
||||
|
||||
private void getPingToCurrentWorld()
|
||||
{
|
||||
if (client.getGameState().equals(GameState.LOGGED_IN) && fpsConfig.drawPing())
|
||||
if (client.getGameState().equals(GameState.LOGGED_IN) && drawPing)
|
||||
{
|
||||
ping = Ping.ping(String.format("oldschool%d.runescape.com", client.getWorld() - 300));
|
||||
}
|
||||
|
||||
@@ -119,6 +119,11 @@ public class FreezeTimersOverlay extends Overlay
|
||||
String text = processTickCounter(finishedAt);
|
||||
int test = Integer.parseInt(text);
|
||||
Point poi = actor.getCanvasTextLocation(g, text, 0);
|
||||
if (poi == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int xpoi = poi.getX();
|
||||
int ypoi = poi.getY();
|
||||
Point FixedPoint = new Point(xpoi, ypoi);
|
||||
|
||||
@@ -190,20 +190,20 @@ public class FriendNotesPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (WidgetInfo.TO_GROUP(event.getWidgetId()) == WidgetInfo.FRIENDS_LIST.getGroupId())
|
||||
if (WidgetInfo.TO_GROUP(event.getActionParam1()) == WidgetInfo.FRIENDS_LIST.getGroupId())
|
||||
{
|
||||
if (Strings.isNullOrEmpty(event.getMenuTarget()))
|
||||
if (Strings.isNullOrEmpty(event.getTarget()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle clicks on "Add Note" or "Edit Note"
|
||||
if (event.getMenuOption().equals(ADD_NOTE) || event.getMenuOption().equals(EDIT_NOTE))
|
||||
if (event.getOption().equals(ADD_NOTE) || event.getOption().equals(EDIT_NOTE))
|
||||
{
|
||||
event.consume();
|
||||
|
||||
//Friends have color tags
|
||||
final String sanitizedTarget = Text.toJagexName(Text.removeTags(event.getMenuTarget()));
|
||||
final String sanitizedTarget = Text.toJagexName(Text.removeTags(event.getTarget()));
|
||||
final String note = getFriendNote(sanitizedTarget);
|
||||
|
||||
// Open the new chatbox input dialog
|
||||
|
||||
@@ -162,16 +162,16 @@ public class FriendTaggingPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (WidgetInfo.TO_GROUP(event.getWidgetId()) == WidgetInfo.FRIENDS_LIST.getGroupId())
|
||||
if (WidgetInfo.TO_GROUP(event.getActionParam1()) == WidgetInfo.FRIENDS_LIST.getGroupId())
|
||||
{
|
||||
if (Strings.isNullOrEmpty(event.getMenuTarget()))
|
||||
if (Strings.isNullOrEmpty(event.getTarget()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String sanitizedTarget = Text.removeTags(event.getMenuTarget());
|
||||
final String sanitizedTarget = Text.removeTags(event.getTarget());
|
||||
|
||||
if (event.getMenuOption().equals(ADD_TAG))
|
||||
if (event.getOption().equals(ADD_TAG))
|
||||
{
|
||||
event.consume();
|
||||
final ChatboxTextInput build = chatboxPanelManager.openTextInput("Enter the tag").value("")
|
||||
@@ -185,7 +185,7 @@ public class FriendTaggingPlugin extends Plugin
|
||||
setTag(sanitizedTarget, content);
|
||||
}).build();
|
||||
}
|
||||
if (event.getMenuOption().equals(DELETE_TAG))
|
||||
if (event.getOption().equals(DELETE_TAG))
|
||||
{
|
||||
event.consume();
|
||||
client.getLogger().info(sanitizedTarget);
|
||||
|
||||
@@ -46,6 +46,7 @@ class GroundItem
|
||||
private int offset;
|
||||
private boolean tradeable;
|
||||
private boolean isMine;
|
||||
private int ticks;
|
||||
private int durationMillis;
|
||||
private boolean isAlwaysPrivate;
|
||||
private boolean isOwnedByPlayer;
|
||||
|
||||
@@ -606,4 +606,16 @@ public interface GroundItemsConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTimer",
|
||||
name = "Show ground item tick countdown timer",
|
||||
description = "Shows how many ticks left until disappearing.",
|
||||
position = 48,
|
||||
parent = "miscStub"
|
||||
)
|
||||
default boolean showTimer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +277,13 @@ public class GroundItemsOverlay extends Overlay
|
||||
}
|
||||
}
|
||||
|
||||
if (item.getTicks() > 0 && config.showTimer())
|
||||
{
|
||||
itemStringBuilder
|
||||
.append(" - ")
|
||||
.append(item.getTicks());
|
||||
}
|
||||
|
||||
final String itemString = itemStringBuilder.toString();
|
||||
itemStringBuilder.setLength(0);
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemQuantityChanged;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
@@ -204,6 +205,16 @@ public class GroundItemsPlugin extends Plugin
|
||||
collectedGroundItems.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
for (GroundItem item : collectedGroundItems.values())
|
||||
{
|
||||
if (item.getTicks() == -1) continue;
|
||||
item.setTicks(item.getTicks() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
@@ -461,6 +472,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
if (groundItem != null)
|
||||
{
|
||||
groundItem.setMine(true);
|
||||
groundItem.setTicks(200);
|
||||
|
||||
boolean shouldNotify = config.onlyShowLoot() && config.highlightedColor().equals(getHighlighted(
|
||||
groundItem.getName(),
|
||||
@@ -511,6 +523,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
.durationMillis(durationMillis)
|
||||
.isAlwaysPrivate(client.isInInstancedRegion() || (!itemComposition.isTradeable() && realItemId != COINS))
|
||||
.isOwnedByPlayer(tile.getWorldLocation().equals(playerLocation))
|
||||
.ticks(tile.getWorldLocation().equals(client.getLocalPlayer().getWorldLocation()) ? 200 : 100)
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
@@ -315,13 +315,13 @@ public class GroundMarkerPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (!event.getMenuOption().contains(MARK) && !event.getMenuOption().contains(UNMARK))
|
||||
if (!event.getOption().contains(MARK) && !event.getOption().contains(UNMARK))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int group = 1;
|
||||
Matcher m = GROUP_MATCHER.matcher(event.getMenuOption());
|
||||
Matcher m = GROUP_MATCHER.matcher(event.getOption());
|
||||
if (m.matches())
|
||||
{
|
||||
group = Integer.parseInt(m.group(1));
|
||||
|
||||
@@ -36,7 +36,9 @@ import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HashTable;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.WidgetNode;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
@@ -120,6 +122,7 @@ public class HidePrayersPlugin extends Plugin
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
reallyHidePrayers();
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
@@ -506,9 +509,19 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(9).setHidden(false); // Rapid Heal
|
||||
}
|
||||
|
||||
if (WorldType.isHighRiskWorld(client.getWorldType()) || client.getRealSkillLevel(Skill.PRAYER) <= 24)
|
||||
{
|
||||
prayerWidgets.get(10).setHidden(true); // Protect Item
|
||||
}
|
||||
else
|
||||
{
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
}
|
||||
|
||||
switch (config.pvpprayers())
|
||||
{
|
||||
case DISABLED:
|
||||
reallyHidePrayers();
|
||||
break;
|
||||
case PRAY1:
|
||||
prayerWidgets.get(0).setHidden(false); // Thick Skin
|
||||
@@ -521,30 +534,21 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(6).setHidden(false); // Super Human Strength
|
||||
break;
|
||||
case PRAY16:
|
||||
prayerWidgets.get(3).setHidden(false); // Sharp Eye
|
||||
prayerWidgets.get(4).setHidden(false); // Mystic Will
|
||||
prayerWidgets.get(5).setHidden(false); // Rock Skin
|
||||
prayerWidgets.get(6).setHidden(false); // Super Human Strength
|
||||
prayerWidgets.get(7).setHidden(false); // Improved Reflexed
|
||||
break;
|
||||
case PRAY25:
|
||||
prayerWidgets.get(3).setHidden(false); // Sharp Eye
|
||||
prayerWidgets.get(4).setHidden(false); // Mystic Will
|
||||
prayerWidgets.get(5).setHidden(false); // Rock Skin
|
||||
prayerWidgets.get(6).setHidden(false); // Super Human Strength
|
||||
prayerWidgets.get(7).setHidden(false); // Improved Reflexed
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
break;
|
||||
case PRAY31:
|
||||
prayerWidgets.get(7).setHidden(false); // Improved Reflexed
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(11).setHidden(false); // Hawk Eye
|
||||
prayerWidgets.get(12).setHidden(false); // Mystic Lore
|
||||
prayerWidgets.get(13).setHidden(false); // Steel Skin
|
||||
prayerWidgets.get(14).setHidden(false); // Ultimate Strength
|
||||
break;
|
||||
case PRAY43:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(11).setHidden(false); // Hawk Eye
|
||||
prayerWidgets.get(12).setHidden(false); // Mystic Lore
|
||||
prayerWidgets.get(13).setHidden(false); // Steel Skin
|
||||
@@ -555,7 +559,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(18).setHidden(false); // Protect from Melee
|
||||
break;
|
||||
case PRAY44:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(12).setHidden(false); // Mystic Lore
|
||||
prayerWidgets.get(13).setHidden(false); // Steel Skin
|
||||
prayerWidgets.get(14).setHidden(false); // Ultimate Strength
|
||||
@@ -566,7 +569,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(19).setHidden(false); // Eagle Eye
|
||||
break;
|
||||
case PRAY45:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(13).setHidden(false); // Steel Skin
|
||||
prayerWidgets.get(14).setHidden(false); // Ultimate Strength
|
||||
prayerWidgets.get(15).setHidden(false); // Incredible Reflexes
|
||||
@@ -577,7 +579,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(20).setHidden(false); // Mystic Might
|
||||
break;
|
||||
case PRAY52:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(13).setHidden(false); // Steel Skin
|
||||
prayerWidgets.get(14).setHidden(false); // Ultimate Strength
|
||||
prayerWidgets.get(15).setHidden(false); // Incredible Reflexes
|
||||
@@ -590,7 +591,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(23).setHidden(false); // Smite
|
||||
break;
|
||||
case PRAY55:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(13).setHidden(false); // Steel Skin
|
||||
prayerWidgets.get(14).setHidden(false); // Ultimate Strength
|
||||
prayerWidgets.get(15).setHidden(false); // Incredible Reflexes
|
||||
@@ -604,7 +604,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(24).setHidden(false); // Preserve
|
||||
break;
|
||||
case PRAY60:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(16).setHidden(false); // Protect from Magic
|
||||
prayerWidgets.get(17).setHidden(false); // Protect from Range
|
||||
prayerWidgets.get(18).setHidden(false); // Protect from Melee
|
||||
@@ -616,7 +615,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(25).setHidden(false); // Chivalry
|
||||
break;
|
||||
case PRAY70:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(16).setHidden(false); // Protect from Magic
|
||||
prayerWidgets.get(17).setHidden(false); // Protect from Range
|
||||
prayerWidgets.get(18).setHidden(false); // Protect from Melee
|
||||
@@ -628,7 +626,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(26).setHidden(false); // Piety
|
||||
break;
|
||||
case PRAY74:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(16).setHidden(false); // Protect from Magic
|
||||
prayerWidgets.get(17).setHidden(false); // Protect from Range
|
||||
prayerWidgets.get(18).setHidden(false); // Protect from Melee
|
||||
@@ -640,7 +637,6 @@ public class HidePrayersPlugin extends Plugin
|
||||
prayerWidgets.get(27).setHidden(false); // Rigour
|
||||
break;
|
||||
case PRAY77:
|
||||
prayerWidgets.get(10).setHidden(false); // Protect Item
|
||||
prayerWidgets.get(16).setHidden(false); // Protect from Magic
|
||||
prayerWidgets.get(17).setHidden(false); // Protect from Range
|
||||
prayerWidgets.get(18).setHidden(false); // Protect from Melee
|
||||
|
||||
@@ -27,40 +27,63 @@ package net.runelite.client.plugins.inferno;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import java.awt.Color;
|
||||
|
||||
@ConfigGroup("inferno")
|
||||
public interface InfernoConfig extends Config
|
||||
{
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "Nibbler Overlay",
|
||||
name = "Nibbler Overlay",
|
||||
description = "Shows if there are any Nibblers left"
|
||||
position = 0,
|
||||
keyName = "Nibbler Overlay",
|
||||
name = "Nibbler Overlay",
|
||||
description = "Shows if there are any Nibblers left"
|
||||
)
|
||||
default boolean displayNibblerOverlay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "Prayer Helper",
|
||||
name = "Prayer Helper",
|
||||
description = "Tells you what to flick in how many ticks"
|
||||
position = 1,
|
||||
keyName = "Prayer Helper",
|
||||
name = "Prayer Helper",
|
||||
description = "Tells you what to flick in how many ticks"
|
||||
)
|
||||
default boolean showPrayerHelp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "Wave Display",
|
||||
name = "Wave display",
|
||||
description = "Shows monsters that will spawn on the selected wave(s)."
|
||||
position = 2,
|
||||
keyName = "waveDisplay",
|
||||
name = "Wave display",
|
||||
description = "Shows monsters that will spawn on the selected wave(s)."
|
||||
)
|
||||
default InfernoWaveDisplayMode waveDisplay()
|
||||
{
|
||||
return InfernoWaveDisplayMode.BOTH;
|
||||
}
|
||||
}
|
||||
{
|
||||
return InfernoWaveDisplayMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "getWaveOverlayHeaderColor",
|
||||
name = "Wave Header",
|
||||
description = "Color for Wave Header"
|
||||
)
|
||||
default Color getWaveOverlayHeaderColor()
|
||||
{
|
||||
return Color.ORANGE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "getWaveTextColor",
|
||||
name = "Wave Text Color",
|
||||
description = "Color for Wave Texts"
|
||||
)
|
||||
default Color getWaveTextColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
}
|
||||
@@ -1,427 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.inferno;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Inferno",
|
||||
description = "Inferno helper",
|
||||
tags = {"combat", "overlay", "pve", "pvm"},
|
||||
type = PluginType.PVM
|
||||
)
|
||||
public class InfernoPlugin extends Plugin
|
||||
{
|
||||
|
||||
private static final Pattern WAVE_PATTERN = Pattern.compile(".*Wave: (\\d+).*");
|
||||
private static final int MAX_MONSTERS_OF_TYPE_PER_WAVE = 6;
|
||||
private static final int INFERNO_REGION = 9043;
|
||||
static final int MAX_WAVE = 69;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private InfernoOverlay infernoOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoWaveOverlay waveOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoJadOverlay jadOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoInfobox infernoInfobox;
|
||||
|
||||
@Inject
|
||||
private InfernoNibblerOverlay nibblerOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoConfig config;
|
||||
|
||||
@Getter
|
||||
static final List<EnumMap<InfernoWaveMonster, Integer>> WAVES = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private int currentWave = -1;
|
||||
|
||||
@Getter
|
||||
private Map<NPC, InfernoNPC> monsters;
|
||||
|
||||
@Getter
|
||||
private Map<Integer, ArrayList<InfernoNPC>> monsterCurrentAttackMap;
|
||||
|
||||
@Getter
|
||||
private List<NPC> nibblers;
|
||||
|
||||
@Getter
|
||||
private InfernoNPC[] priorityNPC;
|
||||
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Nullable
|
||||
private InfernoJadAttack attack;
|
||||
|
||||
private NPC jad;
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
final InfernoWaveMonster[] waveMonsters = InfernoWaveMonster.values();
|
||||
|
||||
// Add wave 1, future waves are derived from its contents
|
||||
final EnumMap<InfernoWaveMonster, Integer> waveOne = new EnumMap<>(InfernoWaveMonster.class);
|
||||
waveOne.put(waveMonsters[0], 1);
|
||||
WAVES.add(waveOne);
|
||||
|
||||
for (int wave = 1; wave < MAX_WAVE; wave++)
|
||||
{
|
||||
final EnumMap<InfernoWaveMonster, Integer> prevWave = WAVES.get(wave - 1).clone();
|
||||
int maxMonsterOrdinal = -1;
|
||||
|
||||
for (int i = 0; i < waveMonsters.length; i++)
|
||||
{
|
||||
final int ordinalMonsterQuantity = prevWave.getOrDefault(waveMonsters[i], 0);
|
||||
|
||||
if (ordinalMonsterQuantity == MAX_MONSTERS_OF_TYPE_PER_WAVE)
|
||||
{
|
||||
maxMonsterOrdinal = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxMonsterOrdinal >= 0)
|
||||
{
|
||||
prevWave.remove(waveMonsters[maxMonsterOrdinal]);
|
||||
}
|
||||
|
||||
final int addedMonsterOrdinal = maxMonsterOrdinal >= 0 ? maxMonsterOrdinal + 1 : 0;
|
||||
final InfernoWaveMonster addedMonster = waveMonsters[addedMonsterOrdinal];
|
||||
final int addedMonsterQuantity = prevWave.getOrDefault(addedMonster, 0);
|
||||
|
||||
prevWave.put(addedMonster, addedMonsterQuantity + 1);
|
||||
|
||||
WAVES.add(prevWave);
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
InfernoConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(InfernoConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(infernoOverlay);
|
||||
overlayManager.add(infernoInfobox);
|
||||
overlayManager.add(nibblerOverlay);
|
||||
overlayManager.add(waveOverlay);
|
||||
overlayManager.add(jadOverlay);
|
||||
monsters = new HashMap<>();
|
||||
monsterCurrentAttackMap = new HashMap<>(6);
|
||||
for (int i = 1; i <= 6; i++)
|
||||
{
|
||||
monsterCurrentAttackMap.put(i, new ArrayList<>());
|
||||
}
|
||||
nibblers = new ArrayList<>();
|
||||
priorityNPC = new InfernoNPC[4];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(infernoInfobox);
|
||||
overlayManager.remove(infernoOverlay);
|
||||
overlayManager.remove(nibblerOverlay);
|
||||
overlayManager.remove(waveOverlay);
|
||||
overlayManager.remove(jadOverlay);
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
if (client.getMapRegions()[0] != 9043) return;
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
if (isValidInfernoMob(npc))
|
||||
{
|
||||
monsters.put(npc, new InfernoNPC(npc));
|
||||
System.out.println(monsters.size());
|
||||
}
|
||||
if (npc.getId() == NpcID.JALNIB)
|
||||
{
|
||||
nibblers.add(npc);
|
||||
}
|
||||
|
||||
final int id = event.getNpc().getId();
|
||||
|
||||
if (id == NpcID.JALTOKJAD || id == NpcID.JALTOKJAD_7704)
|
||||
{
|
||||
jad = event.getNpc();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (client.getMapRegions()[0] != 9043) return;
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
if (monsters.containsKey(npc))
|
||||
{
|
||||
monsters.remove(npc);
|
||||
System.out.println(monsters.size());
|
||||
}
|
||||
|
||||
if (npc.getId() == NpcID.JALNIB)
|
||||
{
|
||||
nibblers.remove(npc);
|
||||
}
|
||||
|
||||
if (jad == event.getNpc())
|
||||
{
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inInferno())
|
||||
{
|
||||
currentWave = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage());
|
||||
|
||||
if (event.getType() != ChatMessageType.GAMEMESSAGE
|
||||
|| !inInferno()
|
||||
|| !waveMatcher.matches())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentWave = Integer.parseInt(waveMatcher.group(1));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (client.getMapRegions()[0] != 9043) return;
|
||||
|
||||
clearMapAndPriority();
|
||||
|
||||
for (InfernoNPC monster : monsters.values())
|
||||
{
|
||||
calculateDistanceToPlayer(monster);
|
||||
|
||||
NPC npc = monster.getNpc();
|
||||
|
||||
// if they are not attacking but are still attacking
|
||||
if (monster.isAttacking())
|
||||
{
|
||||
monster.setTicksTillAttack(monster.getTicksTillAttack() - 1);
|
||||
|
||||
// sets the blobs attack style
|
||||
if (monster.getName().equals("blob") && monster.getTicksTillAttack() == 3 && monster.getDistanceToPlayer() <= 15)
|
||||
{
|
||||
if (client.getLocalPlayer().getOverheadIcon() == null)
|
||||
{
|
||||
monster.setAttackstyle(InfernoNPC.Attackstyle.RANDOM);
|
||||
}
|
||||
else if (client.getLocalPlayer().getOverheadIcon().equals(HeadIcon.MAGIC))
|
||||
{
|
||||
monster.setAttackstyle(InfernoNPC.Attackstyle.RANGE);
|
||||
}
|
||||
else if (client.getLocalPlayer().getOverheadIcon().equals(HeadIcon.RANGED))
|
||||
{
|
||||
monster.setAttackstyle(InfernoNPC.Attackstyle.MAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// we know the monster is not attacking because it should have attacked and is idling
|
||||
if (monster.getTicksTillAttack() == 0)
|
||||
{
|
||||
if (npc.getAnimation() == -1)
|
||||
{
|
||||
monster.setAttacking(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// want to reset the monsters attack back to attacking
|
||||
monster.attacked();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// they've just attacked
|
||||
if (npc.getAnimation() == monster.getAttackAnimation() || npc.getAnimation() == 7581) // special case for blob
|
||||
{
|
||||
monster.attacked();
|
||||
}
|
||||
}
|
||||
|
||||
if (monster.getTicksTillAttack() >= 1)
|
||||
{
|
||||
monsterCurrentAttackMap.get(monster.getTicksTillAttack()).add(monster);
|
||||
}
|
||||
}
|
||||
|
||||
calculatePriorityNPC();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(final AnimationChanged event)
|
||||
{
|
||||
if (event.getActor() != jad)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (jad.getAnimation() == InfernoJadAttack.MAGIC.getAnimation())
|
||||
{
|
||||
attack = InfernoJadAttack.MAGIC;
|
||||
}
|
||||
else if (jad.getAnimation() == InfernoJadAttack.RANGE.getAnimation())
|
||||
{
|
||||
attack = InfernoJadAttack.RANGE;
|
||||
}
|
||||
}
|
||||
|
||||
private void calculatePriorityNPC()
|
||||
{
|
||||
for (int i = 0; i < priorityNPC.length; i++)
|
||||
{
|
||||
ArrayList<InfernoNPC> monsters = monsterCurrentAttackMap.get(i + 1);
|
||||
|
||||
if ( monsters.size() == 0) continue;
|
||||
|
||||
int priority = monsters.get(0).getPriority();
|
||||
|
||||
InfernoNPC infernoNPC = monsters.get(0);
|
||||
|
||||
for (InfernoNPC npc : monsters)
|
||||
{
|
||||
if (npc.getPriority() < priority)
|
||||
{
|
||||
priority = npc.getPriority();
|
||||
infernoNPC = npc;
|
||||
}
|
||||
}
|
||||
priorityNPC[i] = infernoNPC;
|
||||
System.out.println("i: " + i + " " + infernoNPC.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: blob calculator
|
||||
private void calculateDistanceToPlayer(InfernoNPC monster)
|
||||
{
|
||||
monster.setDistanceToPlayer(client.getLocalPlayer().getWorldLocation().distanceTo(monster.getNpc().getWorldArea()));
|
||||
}
|
||||
|
||||
private void clearMapAndPriority()
|
||||
{
|
||||
for (List<InfernoNPC> l : monsterCurrentAttackMap.values())
|
||||
{
|
||||
l.clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < priorityNPC.length; i++)
|
||||
{
|
||||
priorityNPC[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValidInfernoMob(NPC npc)
|
||||
{
|
||||
// we only want the bat, blob, melee, ranger and mager
|
||||
if (npc.getId() == NpcID.JALMEJRAH ||
|
||||
npc.getId() == NpcID.JALAK ||
|
||||
npc.getId() == NpcID.JALIMKOT ||
|
||||
npc.getId() == NpcID.JALXIL ||
|
||||
npc.getId() == NpcID.JALZEK) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean inInferno()
|
||||
{
|
||||
return ArrayUtils.contains(client.getMapRegions(), INFERNO_REGION);
|
||||
}
|
||||
|
||||
static String formatMonsterQuantity(final InfernoWaveMonster monster, final int quantity)
|
||||
{
|
||||
return String.format("%dx %s", quantity, monster);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.inferno;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Inferno",
|
||||
description = "Inferno helper",
|
||||
tags = {"combat", "overlay", "pve", "pvm"},
|
||||
type = PluginType.PVM
|
||||
)
|
||||
@Slf4j
|
||||
public class InfernoPlugin extends Plugin
|
||||
{
|
||||
private static final int INFERNO_REGION = 9043;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private InfernoOverlay infernoOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoWaveOverlay waveOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoJadOverlay jadOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoInfobox infernoInfobox;
|
||||
|
||||
@Inject
|
||||
private InfernoNibblerOverlay nibblerOverlay;
|
||||
|
||||
@Inject
|
||||
private InfernoConfig config;
|
||||
|
||||
@Getter
|
||||
private int currentWave = -1;
|
||||
|
||||
@Getter
|
||||
private Map<NPC, InfernoNPC> monsters;
|
||||
|
||||
@Getter
|
||||
private Map<Integer, ArrayList<InfernoNPC>> monsterCurrentAttackMap;
|
||||
|
||||
@Getter
|
||||
private List<NPC> nibblers;
|
||||
|
||||
@Getter
|
||||
private InfernoNPC[] priorityNPC;
|
||||
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Nullable
|
||||
private InfernoJadAttack attack;
|
||||
|
||||
private NPC jad;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int currentWaveNumber;
|
||||
|
||||
private List<Actor> waveMonsters;
|
||||
|
||||
public InfernoPlugin()
|
||||
{
|
||||
waveMonsters = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Provides
|
||||
InfernoConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(InfernoConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
waveOverlay.setDisplayMode(config.waveDisplay());
|
||||
|
||||
if (isInInferno())
|
||||
{
|
||||
overlayManager.add(infernoOverlay);
|
||||
overlayManager.add(infernoInfobox);
|
||||
overlayManager.add(nibblerOverlay);
|
||||
|
||||
if (config.waveDisplay() != InfernoWaveDisplayMode.NONE)
|
||||
{
|
||||
overlayManager.add(waveOverlay);
|
||||
}
|
||||
|
||||
overlayManager.add(jadOverlay);
|
||||
}
|
||||
|
||||
waveOverlay.setWaveHeaderColor(config.getWaveOverlayHeaderColor());
|
||||
waveOverlay.setWaveTextColor(config.getWaveTextColor());
|
||||
|
||||
monsters = new HashMap<>();
|
||||
monsterCurrentAttackMap = new HashMap<>(6);
|
||||
|
||||
for (int i = 1; i <= 6; i++)
|
||||
{
|
||||
monsterCurrentAttackMap.put(i, new ArrayList<>());
|
||||
}
|
||||
|
||||
nibblers = new ArrayList<>();
|
||||
priorityNPC = new InfernoNPC[4];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(infernoInfobox);
|
||||
overlayManager.remove(infernoOverlay);
|
||||
overlayManager.remove(nibblerOverlay);
|
||||
overlayManager.remove(waveOverlay);
|
||||
overlayManager.remove(jadOverlay);
|
||||
jad = null;
|
||||
attack = null;
|
||||
monsters = null;
|
||||
currentWaveNumber = -1;
|
||||
}
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!"inferno".equals(event.getGroup()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getKey().endsWith("color"))
|
||||
{
|
||||
waveOverlay.setWaveHeaderColor(config.getWaveOverlayHeaderColor());
|
||||
waveOverlay.setWaveTextColor(config.getWaveTextColor());
|
||||
}
|
||||
else if ("waveDisplay".equals(event.getKey()))
|
||||
{
|
||||
overlayManager.remove(waveOverlay);
|
||||
|
||||
waveOverlay.setDisplayMode(config.waveDisplay());
|
||||
|
||||
if (isInInferno() && config.waveDisplay() != InfernoWaveDisplayMode.NONE)
|
||||
{
|
||||
overlayManager.add(waveOverlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
if (client.getMapRegions()[0] != 9043) return;
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
if (isValidInfernoMob(npc))
|
||||
{
|
||||
monsters.put(npc, new InfernoNPC(npc));
|
||||
log.debug(String.valueOf(monsters.size()));
|
||||
}
|
||||
|
||||
if (npc.getId() == NpcID.JALNIB)
|
||||
{
|
||||
nibblers.add(npc);
|
||||
}
|
||||
|
||||
final int id = event.getNpc().getId();
|
||||
|
||||
if (id == NpcID.JALTOKJAD || id == NpcID.JALTOKJAD_7704)
|
||||
{
|
||||
jad = event.getNpc();
|
||||
}
|
||||
|
||||
final Actor actor = event.getActor();
|
||||
|
||||
if (actor != null)
|
||||
{
|
||||
waveMonsters.add(actor);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (client.getMapRegions()[0] != 9043) return;
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
if (monsters.containsKey(npc))
|
||||
{
|
||||
monsters.remove(npc);
|
||||
log.debug(String.valueOf(monsters.size()));
|
||||
}
|
||||
|
||||
if (npc.getId() == NpcID.JALNIB)
|
||||
{
|
||||
nibblers.remove(npc);
|
||||
}
|
||||
|
||||
if (jad == event.getNpc())
|
||||
{
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
final Actor actor = event.getActor();
|
||||
if (actor != null)
|
||||
{
|
||||
waveMonsters.remove(actor);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isInInferno())
|
||||
{
|
||||
currentWaveNumber = -1;
|
||||
overlayManager.remove(infernoInfobox);
|
||||
overlayManager.remove(infernoOverlay);
|
||||
overlayManager.remove(nibblerOverlay);
|
||||
overlayManager.remove(waveOverlay);
|
||||
overlayManager.remove(jadOverlay);
|
||||
}
|
||||
else if (currentWaveNumber == -1)
|
||||
{
|
||||
currentWaveNumber = 1;
|
||||
overlayManager.add(infernoOverlay);
|
||||
overlayManager.add(infernoInfobox);
|
||||
overlayManager.add(nibblerOverlay);
|
||||
|
||||
if (config.waveDisplay() != InfernoWaveDisplayMode.NONE)
|
||||
{
|
||||
overlayManager.add(waveOverlay);
|
||||
}
|
||||
|
||||
overlayManager.add(jadOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (!isInInferno() || event.getType() != ChatMessageType.GAMEMESSAGE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String message = event.getMessage();
|
||||
|
||||
if (event.getMessage().contains("Wave:"))
|
||||
{
|
||||
message = message.substring(message.indexOf(": ") + 2);
|
||||
currentWaveNumber = Integer.parseInt(message.substring(0, message.indexOf("<")));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (client.getMapRegions()[0] != 9043) return;
|
||||
|
||||
clearMapAndPriority();
|
||||
|
||||
for (InfernoNPC monster : monsters.values())
|
||||
{
|
||||
calculateDistanceToPlayer(monster);
|
||||
|
||||
NPC npc = monster.getNpc();
|
||||
|
||||
// if they are not attacking but are still attacking
|
||||
if (monster.isAttacking())
|
||||
{
|
||||
monster.setTicksTillAttack(monster.getTicksTillAttack() - 1);
|
||||
|
||||
// sets the blobs attack style
|
||||
if (monster.getName().equals("blob") && monster.getTicksTillAttack() == 3 && monster.getDistanceToPlayer() <= 15)
|
||||
{
|
||||
if (client.getLocalPlayer().getOverheadIcon() == null)
|
||||
{
|
||||
monster.setAttackstyle(InfernoNPC.Attackstyle.RANDOM);
|
||||
}
|
||||
else if (client.getLocalPlayer().getOverheadIcon().equals(HeadIcon.MAGIC))
|
||||
{
|
||||
monster.setAttackstyle(InfernoNPC.Attackstyle.RANGE);
|
||||
}
|
||||
else if (client.getLocalPlayer().getOverheadIcon().equals(HeadIcon.RANGED))
|
||||
{
|
||||
monster.setAttackstyle(InfernoNPC.Attackstyle.MAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// we know the monster is not attacking because it should have attacked and is idling
|
||||
if (monster.getTicksTillAttack() == 0)
|
||||
{
|
||||
if (npc.getAnimation() == -1)
|
||||
{
|
||||
monster.setAttacking(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// want to reset the monsters attack back to attacking
|
||||
monster.attacked();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// they've just attacked
|
||||
if (npc.getAnimation() == monster.getAttackAnimation() || npc.getAnimation() == 7581) // special case for blob
|
||||
{
|
||||
monster.attacked();
|
||||
}
|
||||
}
|
||||
|
||||
if (monster.getTicksTillAttack() >= 1)
|
||||
{
|
||||
monsterCurrentAttackMap.get(monster.getTicksTillAttack()).add(monster);
|
||||
}
|
||||
}
|
||||
|
||||
calculatePriorityNPC();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(final AnimationChanged event)
|
||||
{
|
||||
if (event.getActor() != jad)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (jad.getAnimation() == InfernoJadAttack.MAGIC.getAnimation())
|
||||
{
|
||||
attack = InfernoJadAttack.MAGIC;
|
||||
}
|
||||
else if (jad.getAnimation() == InfernoJadAttack.RANGE.getAnimation())
|
||||
{
|
||||
attack = InfernoJadAttack.RANGE;
|
||||
}
|
||||
}
|
||||
|
||||
private void calculatePriorityNPC()
|
||||
{
|
||||
for (int i = 0; i < priorityNPC.length; i++)
|
||||
{
|
||||
ArrayList<InfernoNPC> monsters = monsterCurrentAttackMap.get(i + 1);
|
||||
|
||||
if (monsters.size() == 0) continue;
|
||||
|
||||
int priority = monsters.get(0).getPriority();
|
||||
|
||||
InfernoNPC infernoNPC = monsters.get(0);
|
||||
|
||||
for (InfernoNPC npc : monsters)
|
||||
{
|
||||
if (npc.getPriority() < priority)
|
||||
{
|
||||
priority = npc.getPriority();
|
||||
infernoNPC = npc;
|
||||
}
|
||||
}
|
||||
|
||||
priorityNPC[i] = infernoNPC;
|
||||
|
||||
log.debug("i: " + i + " " + infernoNPC.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: blob calculator
|
||||
private void calculateDistanceToPlayer(InfernoNPC monster)
|
||||
{
|
||||
monster.setDistanceToPlayer(client.getLocalPlayer().getWorldLocation().distanceTo(monster.getNpc().getWorldArea()));
|
||||
}
|
||||
|
||||
private void clearMapAndPriority()
|
||||
{
|
||||
for (List<InfernoNPC> l : monsterCurrentAttackMap.values())
|
||||
{
|
||||
l.clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < priorityNPC.length; i++)
|
||||
{
|
||||
priorityNPC[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidInfernoMob(NPC npc)
|
||||
{
|
||||
// we only want the bat, blob, melee, ranger and mager
|
||||
return npc.getId() == NpcID.JALMEJRAH ||
|
||||
npc.getId() == NpcID.JALAK ||
|
||||
npc.getId() == NpcID.JALIMKOT ||
|
||||
npc.getId() == NpcID.JALXIL ||
|
||||
npc.getId() == NpcID.JALZEK;
|
||||
}
|
||||
|
||||
private boolean isInInferno()
|
||||
{
|
||||
return ArrayUtils.contains(client.getMapRegions(), INFERNO_REGION);
|
||||
}
|
||||
|
||||
boolean isNotFinalWave()
|
||||
{
|
||||
return currentWaveNumber <= 68;
|
||||
}
|
||||
|
||||
List<Actor> getWaveMonsters()
|
||||
{
|
||||
return waveMonsters;
|
||||
}
|
||||
|
||||
int getNextWaveNumber()
|
||||
{
|
||||
return currentWaveNumber == -1 || currentWaveNumber == 69 ? -1 : currentWaveNumber + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ public enum InfernoWaveDisplayMode
|
||||
{
|
||||
CURRENT("Current wave"),
|
||||
NEXT("Next wave"),
|
||||
BOTH("Both");
|
||||
BOTH("Both"),
|
||||
NONE("None");
|
||||
|
||||
private final String name;
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Kyleeld <https://github.com/kyleeld>
|
||||
* Copyright (c) 2019, RuneLitePlus <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.inferno;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.Color;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class InfernoWaveMappings
|
||||
{
|
||||
@Getter
|
||||
private static final ImmutableMap<Integer, int[]> waveMapping;
|
||||
|
||||
@Getter
|
||||
private static final ImmutableMap<Integer, String> npcNameMapping;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, int[]> waveMapBuilder = new ImmutableMap.Builder<>();
|
||||
|
||||
waveMapBuilder.put(1, new int[]{32, 32, 32, 85});
|
||||
waveMapBuilder.put(2, new int[]{32, 32, 32, 85, 85});
|
||||
waveMapBuilder.put(3, new int[]{32, 32, 32, 32, 32, 32});
|
||||
waveMapBuilder.put(4, new int[]{32, 32, 32, 165});
|
||||
waveMapBuilder.put(5, new int[]{32, 32, 32, 85, 165});
|
||||
waveMapBuilder.put(6, new int[]{32, 32, 32, 85, 85, 165});
|
||||
waveMapBuilder.put(7, new int[]{32, 32, 32, 165, 165});
|
||||
waveMapBuilder.put(8, new int[]{32, 32, 32, 32, 32, 32});
|
||||
waveMapBuilder.put(9, new int[]{32, 32, 32, 240});
|
||||
waveMapBuilder.put(10, new int[]{32, 32, 32, 85, 240});
|
||||
waveMapBuilder.put(11, new int[]{32, 32, 32, 85, 85, 240});
|
||||
waveMapBuilder.put(12, new int[]{32, 32, 32, 165, 240});
|
||||
waveMapBuilder.put(13, new int[]{32, 32, 32, 85, 165, 240});
|
||||
waveMapBuilder.put(14, new int[]{32, 32, 32, 85, 85, 165, 240});
|
||||
waveMapBuilder.put(15, new int[]{32, 32, 32, 165, 165, 240});
|
||||
waveMapBuilder.put(16, new int[]{32, 32, 32, 240, 240});
|
||||
waveMapBuilder.put(17, new int[]{32, 32, 32, 32, 32, 32});
|
||||
waveMapBuilder.put(18, new int[]{32, 32, 32, 370});
|
||||
waveMapBuilder.put(19, new int[]{32, 32, 32, 85, 370});
|
||||
waveMapBuilder.put(20, new int[]{32, 32, 32, 85, 85, 370});
|
||||
waveMapBuilder.put(21, new int[]{32, 32, 32, 165, 370});
|
||||
waveMapBuilder.put(22, new int[]{32, 32, 32, 85, 165, 370});
|
||||
waveMapBuilder.put(23, new int[]{32, 32, 32, 85, 85, 165, 370});
|
||||
waveMapBuilder.put(24, new int[]{32, 32, 32, 165, 165, 370});
|
||||
waveMapBuilder.put(25, new int[]{32, 32, 32, 240, 370});
|
||||
waveMapBuilder.put(26, new int[]{32, 32, 32, 85, 240, 370});
|
||||
waveMapBuilder.put(27, new int[]{32, 32, 32, 85, 85, 240, 370});
|
||||
waveMapBuilder.put(28, new int[]{32, 32, 32, 165, 240, 370});
|
||||
waveMapBuilder.put(29, new int[]{32, 32, 32, 85, 165, 240, 370});
|
||||
waveMapBuilder.put(30, new int[]{32, 32, 32, 85, 85, 165, 240, 370});
|
||||
waveMapBuilder.put(31, new int[]{32, 32, 32, 165, 165, 240, 370});
|
||||
waveMapBuilder.put(32, new int[]{32, 32, 32, 240, 240, 370});
|
||||
waveMapBuilder.put(33, new int[]{32, 32, 32, 370, 370});
|
||||
waveMapBuilder.put(34, new int[]{32, 32, 32, 32, 32, 32});
|
||||
waveMapBuilder.put(35, new int[]{32, 32, 32, 490});
|
||||
waveMapBuilder.put(36, new int[]{32, 32, 32, 85, 490});
|
||||
waveMapBuilder.put(37, new int[]{32, 32, 32, 85, 85, 490});
|
||||
waveMapBuilder.put(38, new int[]{32, 32, 32, 165, 490});
|
||||
waveMapBuilder.put(39, new int[]{32, 32, 32, 85, 165, 490});
|
||||
waveMapBuilder.put(40, new int[]{32, 32, 32, 85, 85, 165, 490});
|
||||
waveMapBuilder.put(41, new int[]{32, 32, 32, 165, 165, 490});
|
||||
waveMapBuilder.put(42, new int[]{32, 32, 32, 240, 490});
|
||||
waveMapBuilder.put(43, new int[]{32, 32, 32, 85, 240, 490});
|
||||
waveMapBuilder.put(44, new int[]{32, 32, 32, 85, 85, 240, 490});
|
||||
waveMapBuilder.put(45, new int[]{32, 32, 32, 165, 240, 490 });
|
||||
waveMapBuilder.put(46, new int[]{32, 32, 32, 85, 165, 240, 490});
|
||||
waveMapBuilder.put(47, new int[]{32, 32, 32, 85, 85, 165, 240, 490});
|
||||
waveMapBuilder.put(48, new int[]{32, 32, 32, 165, 165, 240, 490});
|
||||
waveMapBuilder.put(49, new int[]{32, 32, 32, 240, 240, 490});
|
||||
waveMapBuilder.put(50, new int[]{32, 32, 32, 370, 490});
|
||||
waveMapBuilder.put(51, new int[]{32, 32, 32, 85, 370, 490});
|
||||
waveMapBuilder.put(52, new int[]{32, 32, 32, 85, 85, 370, 490});
|
||||
waveMapBuilder.put(53, new int[]{32, 32, 32, 165, 370, 490});
|
||||
waveMapBuilder.put(54, new int[]{32, 32, 32, 85, 165, 370, 490});
|
||||
waveMapBuilder.put(55, new int[]{32, 32, 32, 85, 85, 165, 370, 490});
|
||||
waveMapBuilder.put(56, new int[]{32, 32, 32, 165, 165, 370, 490});
|
||||
waveMapBuilder.put(57, new int[]{32, 32, 32, 240, 370, 490});
|
||||
waveMapBuilder.put(58, new int[]{32, 32, 32, 85, 240, 370, 490});
|
||||
waveMapBuilder.put(59, new int[]{32, 32, 32, 85, 85, 240, 370, 490});
|
||||
waveMapBuilder.put(60, new int[]{32, 32, 32, 165, 240, 370, 490});
|
||||
waveMapBuilder.put(61, new int[]{32, 32, 32, 85, 165, 240, 370, 490});
|
||||
waveMapBuilder.put(62, new int[]{32, 32, 32, 85, 85, 165, 240, 370, 490});
|
||||
waveMapBuilder.put(63, new int[]{32, 32, 32, 165, 165, 240, 370, 490});
|
||||
waveMapBuilder.put(64, new int[]{32, 32, 32, 85, 240, 240, 370, 490});
|
||||
waveMapBuilder.put(65, new int[]{32, 32, 32, 85, 370, 370, 490});
|
||||
waveMapBuilder.put(66, new int[]{32, 32, 32, 85, 490, 490});
|
||||
waveMapBuilder.put(67, new int[]{900});
|
||||
waveMapBuilder.put(68, new int[]{900, 900, 900});
|
||||
waveMapBuilder.put(69, new int[]{1400});
|
||||
|
||||
waveMapping = waveMapBuilder.build();
|
||||
|
||||
ImmutableMap.Builder<Integer, String> nameMapBuilder = new ImmutableMap.Builder<>();
|
||||
|
||||
nameMapBuilder.put(32, "Jal-Nib - Level 32");
|
||||
nameMapBuilder.put(85, "Jal-MejRah - Level 85");
|
||||
nameMapBuilder.put(165, "Jal-Ak - Level 165");
|
||||
nameMapBuilder.put(240, "Jal-ImKot - Level 240");
|
||||
nameMapBuilder.put(370, "Jal-Xil - Level 370");
|
||||
nameMapBuilder.put(490, "Jal-Zek - Level 490");
|
||||
nameMapBuilder.put(900, "JalTok-Jad - Level 900");
|
||||
nameMapBuilder.put(1400, "TzKal-Zuk - Level 1400");
|
||||
|
||||
npcNameMapping = nameMapBuilder.build();
|
||||
}
|
||||
|
||||
static void addWaveComponent(PanelComponent panelComponent, String header, int wave, Color titleColor, Color color)
|
||||
{
|
||||
int[] monsters = waveMapping.get(wave);
|
||||
|
||||
if (monsters == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
panelComponent.getChildren()
|
||||
.add(TitleComponent.builder()
|
||||
.text(header)
|
||||
.color(titleColor)
|
||||
.build()
|
||||
);
|
||||
|
||||
|
||||
for (int i = 0; i < monsters.length; i++)
|
||||
{
|
||||
int monsterType = monsters[i];
|
||||
int count = 1;
|
||||
|
||||
for (; i < monsters.length - 1 && monsters[i + 1] == monsterType; i++)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
TitleComponent.TitleComponentBuilder builder = TitleComponent.builder();
|
||||
|
||||
builder.text(count + "x " + npcNameMapping.get(monsterType));
|
||||
builder.color(color);
|
||||
|
||||
panelComponent.getChildren().add(builder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,127 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.inferno;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import com.google.inject.Inject;
|
||||
import lombok.Setter;
|
||||
import static net.runelite.client.plugins.inferno.InfernoWaveMappings.addWaveComponent;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import java.awt.Dimension;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
|
||||
class InfernoWaveOverlay extends Overlay
|
||||
{
|
||||
private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE;
|
||||
|
||||
private final InfernoConfig config;
|
||||
public class InfernoWaveOverlay extends Overlay
|
||||
{
|
||||
private final InfernoPlugin plugin;
|
||||
private final PanelComponent panelComponent;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
@Setter
|
||||
private Color waveHeaderColor;
|
||||
|
||||
@Setter
|
||||
private Color waveTextColor;
|
||||
|
||||
@Setter
|
||||
private InfernoWaveDisplayMode displayMode;
|
||||
|
||||
@Inject
|
||||
private InfernoWaveOverlay(InfernoConfig config, InfernoPlugin plugin)
|
||||
InfernoWaveOverlay(final InfernoPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.config = config;
|
||||
this.panelComponent = new PanelComponent();
|
||||
this.setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.setPriority(OverlayPriority.HIGH);
|
||||
this.plugin = plugin;
|
||||
|
||||
panelComponent.setPreferredSize(new Dimension(160, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
public Dimension render(final Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.inInferno()
|
||||
|| plugin.getCurrentWave() < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
final int currentWave = plugin.getCurrentWave();
|
||||
final int waveIndex = currentWave - 1;
|
||||
|
||||
if (config.waveDisplay() == InfernoWaveDisplayMode.CURRENT
|
||||
|| config.waveDisplay() == InfernoWaveDisplayMode.BOTH)
|
||||
if (displayMode == InfernoWaveDisplayMode.CURRENT ||
|
||||
displayMode == InfernoWaveDisplayMode.BOTH)
|
||||
{
|
||||
final Map<InfernoWaveMonster, Integer> waveContents = InfernoPlugin.getWAVES().get(waveIndex);
|
||||
|
||||
addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents);
|
||||
addWaveComponent(
|
||||
panelComponent,
|
||||
"Current Wave (Wave " + plugin.getCurrentWaveNumber() + ")",
|
||||
plugin.getCurrentWaveNumber(),
|
||||
waveHeaderColor,
|
||||
waveTextColor
|
||||
);
|
||||
}
|
||||
|
||||
if ((config.waveDisplay() == InfernoWaveDisplayMode.NEXT
|
||||
|| config.waveDisplay() == InfernoWaveDisplayMode.BOTH)
|
||||
&& currentWave != InfernoPlugin.MAX_WAVE)
|
||||
if (displayMode == InfernoWaveDisplayMode.NEXT ||
|
||||
displayMode == InfernoWaveDisplayMode.BOTH)
|
||||
{
|
||||
final Map<InfernoWaveMonster, Integer> waveContents = InfernoPlugin.getWAVES().get(waveIndex + 1);
|
||||
|
||||
addWaveInfo("Next wave", waveContents);
|
||||
addWaveComponent(
|
||||
panelComponent,
|
||||
"Next Wave (Wave " + plugin.getNextWaveNumber() + ")",
|
||||
plugin.getNextWaveNumber(),
|
||||
waveHeaderColor,
|
||||
waveTextColor
|
||||
);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private void addWaveInfo(final String headerText, final Map<InfernoWaveMonster, Integer> waveContents)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(headerText)
|
||||
.color(HEADER_COLOR)
|
||||
.build());
|
||||
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
|
||||
for (String line : buildWaveLines(waveContents))
|
||||
{
|
||||
tableComponent.addRow(line);
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
|
||||
private static Collection<String> buildWaveLines(final Map<InfernoWaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<InfernoWaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<String> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<InfernoWaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final InfernoWaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final String line = InfernoPlugin.formatMonsterQuantity(monster, quantity);
|
||||
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.interfacestyles;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import static net.runelite.api.SpriteID.*;
|
||||
import net.runelite.client.game.SpriteOverride;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
enum HealthbarOverride implements SpriteOverride
|
||||
{
|
||||
BACK_30PX(HEALTHBAR_DEFAULT_BACK_30PX, "back_30px.png"),
|
||||
BACK_50PX(HEALTHBAR_DEFAULT_BACK_50PX, "back_30px.png"),
|
||||
BACK_60PX(HEALTHBAR_DEFAULT_BACK_60PX, "back_30px.png"),
|
||||
BACK_80PX(HEALTHBAR_DEFAULT_BACK_80PX, "back_90px.png"),
|
||||
BACK_100PX(HEALTHBAR_DEFAULT_BACK_100PX, "back_90px.png"),
|
||||
BACK_120PX(HEALTHBAR_DEFAULT_BACK_120PX, "back_90px.png"),
|
||||
BACK_140PX(HEALTHBAR_DEFAULT_BACK_140PX, "back_90px.png"),
|
||||
BACK_160PX(HEALTHBAR_DEFAULT_BACK_160PX, "back_90px.png"),
|
||||
|
||||
FRONT_30PX(HEALTHBAR_DEFAULT_FRONT_30PX, "front_30px.png"),
|
||||
FRONT_50PX(HEALTHBAR_DEFAULT_FRONT_50PX, "front_30px.png"),
|
||||
FRONT_60PX(HEALTHBAR_DEFAULT_FRONT_60PX, "front_30px.png"),
|
||||
FRONT_80PX(HEALTHBAR_DEFAULT_FRONT_80PX, "front_90px.png"),
|
||||
FRONT_100PX(HEALTHBAR_DEFAULT_FRONT_100PX, "front_90px.png"),
|
||||
FRONT_120PX(HEALTHBAR_DEFAULT_FRONT_120PX, "front_90px.png"),
|
||||
FRONT_140PX(HEALTHBAR_DEFAULT_FRONT_140PX, "front_90px.png"),
|
||||
FRONT_160PX(HEALTHBAR_DEFAULT_FRONT_160PX, "front_90px.png");
|
||||
|
||||
@Getter
|
||||
private final int spriteId;
|
||||
|
||||
private final String fileName;
|
||||
|
||||
@Getter
|
||||
private int padding = 1;
|
||||
|
||||
private static final Map<Integer, HealthbarOverride> MAP;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, HealthbarOverride> builder = new ImmutableMap.Builder<>();
|
||||
|
||||
for (HealthbarOverride override : values())
|
||||
{
|
||||
builder.put(override.spriteId, override);
|
||||
}
|
||||
|
||||
MAP = builder.build();
|
||||
}
|
||||
|
||||
static HealthbarOverride get(int spriteID)
|
||||
{
|
||||
return MAP.get(spriteID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName()
|
||||
{
|
||||
return Skin.AROUND_2010.toString() + "/healthbar/" + this.fileName;
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,6 @@ import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.HealthBar;
|
||||
import net.runelite.api.HealthBarOverride;
|
||||
import net.runelite.api.NodeCache;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.Sprite;
|
||||
import net.runelite.api.events.BeforeMenuRender;
|
||||
@@ -71,8 +69,6 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
private HealthBarOverride healthBarOverride;
|
||||
|
||||
@Provides
|
||||
InterfaceStylesConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -92,10 +88,7 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
{
|
||||
restoreWidgetDimensions();
|
||||
removeGameframe();
|
||||
healthBarOverride = null;
|
||||
client.setHealthBarOverride(null);
|
||||
NodeCache heathBarCache = client.getHealthBarCache();
|
||||
heathBarCache.reset(); // invalidate healthbar cache so padding resets
|
||||
restoreHealthBars();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -117,19 +110,19 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onPostHealthBar(PostHealthBar postHealthBar)
|
||||
{
|
||||
if (healthBarOverride == null || !config.hdHealthBars())
|
||||
if (!config.hdHealthBars())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HealthBar healthBar = postHealthBar.getHealthBar();
|
||||
Sprite frontSprite = healthBar.getHealthBarFrontSprite();
|
||||
HealthbarOverride override = HealthbarOverride.get(healthBar.getHealthBarFrontSpriteId());
|
||||
|
||||
// Check if this is the health bar we are replacing
|
||||
if (frontSprite == healthBarOverride.getFrontSprite() || frontSprite == healthBarOverride.getFrontSpriteLarge())
|
||||
if (override != null)
|
||||
{
|
||||
// Increase padding to show some more green at very low hp percentages
|
||||
healthBar.setPadding(1);
|
||||
healthBar.setPadding(override.getPadding());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +155,7 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
if (skin == config.skin())
|
||||
{
|
||||
String file = config.skin().toString() + "/" + spriteOverride.getSpriteID() + ".png";
|
||||
Sprite spritePixels = getFileSprite(file);
|
||||
Sprite spritePixels = getFileSpritePixels(file);
|
||||
|
||||
if (spriteOverride.getSpriteID() == SpriteID.COMPASS_TEXTURE)
|
||||
{
|
||||
@@ -194,7 +187,7 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
if (widgetOverride.getSkin() == config.skin())
|
||||
{
|
||||
String file = config.skin().toString() + "/widget/" + widgetOverride.getName() + ".png";
|
||||
Sprite spritePixels = getFileSprite(file);
|
||||
Sprite spritePixels = getFileSpritePixels(file);
|
||||
|
||||
if (spritePixels != null)
|
||||
{
|
||||
@@ -218,7 +211,7 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite getFileSprite(String file)
|
||||
private Sprite getFileSpritePixels(String file)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -272,31 +265,24 @@ public class InterfaceStylesPlugin extends Plugin
|
||||
|
||||
private void overrideHealthBars()
|
||||
{
|
||||
// Reset health bar cache to reset applied padding
|
||||
NodeCache healthBarCache = client.getHealthBarCache();
|
||||
healthBarCache.reset();
|
||||
|
||||
if (config.hdHealthBars())
|
||||
{
|
||||
String fileBase = Skin.AROUND_2010.toString() + "/healthbar/";
|
||||
|
||||
Sprite frontSprite = getFileSprite(fileBase + "front.png");
|
||||
Sprite backSprite = getFileSprite(fileBase + "back.png");
|
||||
|
||||
Sprite frontSpriteLarge = getFileSprite(fileBase + "front_large.png");
|
||||
Sprite backSpriteLarge = getFileSprite(fileBase + "back_large.png");
|
||||
|
||||
HealthBarOverride override = new HealthBarOverride(frontSprite, backSprite, frontSpriteLarge, backSpriteLarge);
|
||||
healthBarOverride = override;
|
||||
client.setHealthBarOverride(override);
|
||||
spriteManager.addSpriteOverrides(HealthbarOverride.values());
|
||||
// Reset health bar caches to apply the override
|
||||
clientThread.invokeLater(client::resetHealthBarCaches);
|
||||
}
|
||||
else
|
||||
{
|
||||
healthBarOverride = null;
|
||||
client.setHealthBarOverride(null);
|
||||
restoreHealthBars();
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreHealthBars()
|
||||
{
|
||||
spriteManager.removeSpriteOverrides(HealthbarOverride.values());
|
||||
clientThread.invokeLater(client::resetHealthBarCaches);
|
||||
}
|
||||
|
||||
private void restoreWidgetDimensions()
|
||||
{
|
||||
for (WidgetOffset widgetOffset : WidgetOffset.values())
|
||||
|
||||
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.inventorygrid;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
|
||||
@ConfigGroup("inventorygrid")
|
||||
public interface InventoryGridConfig extends Config
|
||||
@@ -60,4 +61,15 @@ public interface InventoryGridConfig extends Config
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "dragDelay",
|
||||
name = "Drag Delay",
|
||||
description = "Time in ms to wait after item press before showing grid"
|
||||
)
|
||||
@Range(min = 100)
|
||||
default int dragDelay()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
@@ -45,7 +46,6 @@ import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
class InventoryGridOverlay extends Overlay
|
||||
{
|
||||
private static final int INVENTORY_SIZE = 28;
|
||||
private static final int DRAG_DELAY = 5;
|
||||
|
||||
private static final Color HIGHLIGHT = new Color(0, 255, 0, 45);
|
||||
private static final Color GRID = new Color(255, 255, 255, 45);
|
||||
@@ -72,7 +72,7 @@ class InventoryGridOverlay extends Overlay
|
||||
final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY);
|
||||
|
||||
if (if1DraggingWidget == null || if1DraggingWidget != inventoryWidget
|
||||
|| client.getItemPressedDuration() < DRAG_DELAY)
|
||||
|| client.getItemPressedDuration() < config.dragDelay() / Constants.CLIENT_TICK_LENGTH)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.JOptionPane;
|
||||
@@ -102,7 +103,7 @@ public class InventorySetupPlugin extends Plugin
|
||||
|
||||
private InventorySetupPluginPanel panel;
|
||||
|
||||
private HashMap<String, InventorySetup> inventorySetups;
|
||||
private Map<String, InventorySetup> inventorySetups = new HashMap<>();
|
||||
|
||||
private NavigationButton navButton;
|
||||
|
||||
@@ -270,7 +271,7 @@ public class InventorySetupPlugin extends Plugin
|
||||
final String json = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY);
|
||||
if (json == null || json.isEmpty())
|
||||
{
|
||||
inventorySetups = new HashMap<>();
|
||||
inventorySetups.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -280,7 +281,8 @@ public class InventorySetupPlugin extends Plugin
|
||||
{
|
||||
|
||||
}.getType();
|
||||
inventorySetups = gson.fromJson(json, type);
|
||||
inventorySetups.clear();
|
||||
inventorySetups.putAll(gson.fromJson(json, type));
|
||||
}
|
||||
|
||||
for (final String key : inventorySetups.keySet())
|
||||
|
||||
@@ -165,15 +165,15 @@ public class InventoryTagsPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
final String selectedMenu = Text.removeTags(event.getMenuTarget());
|
||||
final String selectedMenu = Text.removeTags(event.getTarget());
|
||||
|
||||
if (event.getMenuOption().equals(MENU_SET))
|
||||
if (event.getOption().equals(MENU_SET))
|
||||
{
|
||||
setTag(event.getId(), selectedMenu);
|
||||
setTag(event.getIdentifier(), selectedMenu);
|
||||
}
|
||||
else if (event.getMenuOption().equals(MENU_REMOVE))
|
||||
else if (event.getOption().equals(MENU_REMOVE))
|
||||
{
|
||||
unsetTag(event.getId());
|
||||
unsetTag(event.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,14 @@ import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import static net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay.PLACEHOLDER_WIDTH;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
@@ -51,9 +53,8 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
class InventoryViewerOverlay extends Overlay
|
||||
{
|
||||
private static final int INVENTORY_SIZE = 28;
|
||||
private static final int PLACEHOLDER_WIDTH = 36;
|
||||
private static final int PLACEHOLDER_HEIGHT = 32;
|
||||
private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR));
|
||||
private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(
|
||||
new BufferedImage(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR));
|
||||
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
@@ -93,6 +94,8 @@ class ItemPricesOverlay extends Overlay
|
||||
// Tooltip action type handling
|
||||
switch (action)
|
||||
{
|
||||
case ITEM_USE_ON_WIDGET:
|
||||
if (!menuEntry.getTarget().contains("High Level Alchemy") || !config.showAlchProfit()) return null;
|
||||
case WIDGET_DEFAULT:
|
||||
case ITEM_USE:
|
||||
case ITEM_FIRST_OPTION:
|
||||
@@ -194,6 +197,7 @@ class ItemPricesOverlay extends Overlay
|
||||
int gePrice = 0;
|
||||
int haPrice = 0;
|
||||
int haProfit = 0;
|
||||
final int itemHaPrice = Math.round(itemDef.getPrice() * Constants.HIGH_ALCHEMY_MULTIPLIER);
|
||||
|
||||
if (config.showGEPrice())
|
||||
{
|
||||
@@ -203,9 +207,9 @@ class ItemPricesOverlay extends Overlay
|
||||
{
|
||||
haPrice = itemManager.getAlchValue(id);
|
||||
}
|
||||
if (gePrice > 0 && haPrice > 0 && config.showAlchProfit())
|
||||
if (gePrice > 0 && itemHaPrice > 0 && config.showAlchProfit())
|
||||
{
|
||||
haProfit = calculateHAProfit(haPrice, gePrice);
|
||||
haProfit = calculateHAProfit(itemHaPrice, gePrice);
|
||||
}
|
||||
|
||||
if (gePrice > 0 || haPrice > 0)
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* 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.itemskeptondeath;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
|
||||
/**
|
||||
* Certain Items receive a white outline by Jagex as they are always lost on death. This is sometimes incorrectly
|
||||
* added to Items by Jagex as the item is actually kept in non-pvp areas of the game, such as the Rune Pouch.
|
||||
*
|
||||
* The white outline will be added to these items when they are lost on death.
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
enum AlwaysLostItem
|
||||
{
|
||||
RUNE_POUCH(ItemID.RUNE_POUCH, true),
|
||||
LOOTING_BAG(ItemID.LOOTING_BAG, false),
|
||||
CLUE_BOX(ItemID.CLUE_BOX, false);
|
||||
|
||||
private final int itemID;
|
||||
private final boolean keptOutsideOfWilderness;
|
||||
|
||||
private static final ImmutableMap<Integer, AlwaysLostItem> ID_MAP;
|
||||
|
||||
static
|
||||
{
|
||||
final ImmutableMap.Builder<Integer, AlwaysLostItem> map = ImmutableMap.builder();
|
||||
for (final AlwaysLostItem p : values())
|
||||
{
|
||||
map.put(p.itemID, p);
|
||||
}
|
||||
ID_MAP = map.build();
|
||||
}
|
||||
|
||||
static AlwaysLostItem getByItemID(final int itemID)
|
||||
{
|
||||
return ID_MAP.get(itemID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* 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.itemskeptondeath;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.runelite.api.ItemID;
|
||||
|
||||
/**
|
||||
* Some non tradeable items are kept on death inside low level wilderness (1-20) but are turned into a broken variant.
|
||||
*
|
||||
* The non-broken variant will be shown inside the interface.
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
enum BrokenOnDeathItem
|
||||
{
|
||||
// Capes
|
||||
FIRE_CAPE(ItemID.FIRE_CAPE),
|
||||
FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE),
|
||||
INFERNAL_CAPE(ItemID.INFERNAL_CAPE),
|
||||
INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE),
|
||||
AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER),
|
||||
ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE),
|
||||
|
||||
// Defenders
|
||||
BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER),
|
||||
IRON_DEFENDER(ItemID.IRON_DEFENDER),
|
||||
STEEL_DEFENDER(ItemID.STEEL_DEFENDER),
|
||||
BLACK_DEFENDER(ItemID.BLACK_DEFENDER),
|
||||
MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER),
|
||||
ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER),
|
||||
RUNE_DEFENDER(ItemID.RUNE_DEFENDER),
|
||||
DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER),
|
||||
AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER),
|
||||
|
||||
// Void
|
||||
VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM),
|
||||
VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM),
|
||||
VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM),
|
||||
VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP),
|
||||
VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE),
|
||||
VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES),
|
||||
VOID_KNIGHT_MACE(ItemID.VOID_KNIGHT_MACE),
|
||||
ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP),
|
||||
ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE),
|
||||
|
||||
// Barb Assault
|
||||
FIGHTER_HAT(ItemID.FIGHTER_HAT),
|
||||
RANGER_HAT(ItemID.RANGER_HAT),
|
||||
HEALER_HAT(ItemID.HEALER_HAT),
|
||||
FIGHTER_TORSO(ItemID.FIGHTER_TORSO),
|
||||
PENANCE_SKIRT(ItemID.PENANCE_SKIRT),
|
||||
|
||||
// Castle Wars
|
||||
SARADOMIN_HALO(ItemID.SARADOMIN_HALO),
|
||||
ZAMORAK_HALO(ItemID.ZAMORAK_HALO),
|
||||
GUTHIX_HALO(ItemID.GUTHIX_HALO),
|
||||
DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898),
|
||||
DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896),
|
||||
DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897),
|
||||
DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899),
|
||||
DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900),
|
||||
DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901),
|
||||
GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511),
|
||||
GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509),
|
||||
GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510),
|
||||
GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895),
|
||||
GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512),
|
||||
GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508);
|
||||
|
||||
private final int itemID;
|
||||
|
||||
private static final ImmutableSet<Integer> ID_SET;
|
||||
|
||||
static
|
||||
{
|
||||
final ImmutableSet.Builder<Integer> set = new ImmutableSet.Builder<>();
|
||||
for (final BrokenOnDeathItem p : values())
|
||||
{
|
||||
set.add(p.itemID);
|
||||
}
|
||||
ID_SET = set.build();
|
||||
}
|
||||
|
||||
static boolean isBrokenOnDeath(final int itemID)
|
||||
{
|
||||
return ID_SET.contains(itemID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* 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.itemskeptondeath;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
|
||||
/**
|
||||
* Some items have a fixed price that is added to its default value when calculating death prices.
|
||||
* These are typically imbued items, such as Berserker ring (i), to help it protect over the non-imbued variants.
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
enum FixedPriceItem
|
||||
{
|
||||
IMBUED_BLACK_MASK_I(ItemID.BLACK_MASK_I, 5000),
|
||||
IMBUED_BLACK_MASK_1_I(ItemID.BLACK_MASK_1_I, 5000),
|
||||
IMBUED_BLACK_MASK_2_I(ItemID.BLACK_MASK_2_I, 5000),
|
||||
IMBUED_BLACK_MASK_3_I(ItemID.BLACK_MASK_3_I, 5000),
|
||||
IMBUED_BLACK_MASK_4_I(ItemID.BLACK_MASK_4_I, 5000),
|
||||
IMBUED_BLACK_MASK_5_I(ItemID.BLACK_MASK_5_I, 5000),
|
||||
IMBUED_BLACK_MASK_6_I(ItemID.BLACK_MASK_6_I, 5000),
|
||||
IMBUED_BLACK_MASK_7_I(ItemID.BLACK_MASK_7_I, 5000),
|
||||
IMBUED_BLACK_MASK_8_I(ItemID.BLACK_MASK_8_I, 5000),
|
||||
IMBUED_BLACK_MASK_9_I(ItemID.BLACK_MASK_9_I, 5000),
|
||||
IMBUED_BLACK_MASK_10_I(ItemID.BLACK_MASK_10_I, 5000),
|
||||
|
||||
IMBUED_SLAYER_HELMET_I(ItemID.SLAYER_HELMET_I, 1000),
|
||||
IMBUED_BLACK_SLAYER_HELMET_I(ItemID.BLACK_SLAYER_HELMET_I, 1000),
|
||||
IMBUED_PURPLE_SLAYER_HELMET_I(ItemID.PURPLE_SLAYER_HELMET_I, 1000),
|
||||
IMBUED_RED_SLAYER_HELMET_I(ItemID.RED_SLAYER_HELMET_I, 1000),
|
||||
IMBUED_GREEN_SLAYER_HELMET_I(ItemID.GREEN_SLAYER_HELMET_I, 1000),
|
||||
IMBUED_TURQUOISE_SLAYER_HELMET_I(ItemID.TURQUOISE_SLAYER_HELMET_I, 1000),
|
||||
IMBUED_HYDRA_SLAYER_HELMET_I(ItemID.HYDRA_SLAYER_HELMET_I, 1000),
|
||||
|
||||
IMBUED_ARCHERS_RING_I(ItemID.ARCHERS_RING_I, 2000),
|
||||
IMBUED_BERSERKER_RING_I(ItemID.BERSERKER_RING_I, 2000),
|
||||
IMBUED_SEERS_RING_I(ItemID.SEERS_RING_I, 2000),
|
||||
|
||||
IMBUED_RING_OF_THE_GODS_I(ItemID.RING_OF_THE_GODS_I, 2000),
|
||||
IMBUED_TREASONOUS_RING_I(ItemID.TREASONOUS_RING_I, 2000),
|
||||
IMBUED_TYRANNICAL_RING_I(ItemID.TYRANNICAL_RING_I, 2000);
|
||||
|
||||
private final int itemId;
|
||||
private final int offset;
|
||||
|
||||
private static final Map<Integer, FixedPriceItem> FIXED_ITEMS;
|
||||
|
||||
static
|
||||
{
|
||||
final ImmutableMap.Builder<Integer, FixedPriceItem> map = ImmutableMap.builder();
|
||||
for (final FixedPriceItem p : values())
|
||||
{
|
||||
map.put(p.itemId, p);
|
||||
}
|
||||
FIXED_ITEMS = map.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static FixedPriceItem find(int itemId)
|
||||
{
|
||||
return FIXED_ITEMS.get(itemId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.itemskeptondeath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.SkullIcon;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.vars.AccountType;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Items Kept on Death",
|
||||
description = "Updates the Items Kept on Death interface to be more accurate",
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Slf4j
|
||||
public class ItemsKeptOnDeathPlugin extends Plugin
|
||||
{
|
||||
private static final int DEEP_WILDY = 20;
|
||||
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+).*");
|
||||
|
||||
// Item Container helpers
|
||||
private static final int MAX_ROW_ITEMS = 8;
|
||||
private static final int ITEM_X_OFFSET = 5;
|
||||
private static final int ITEM_Y_OFFSET = 25;
|
||||
private static final int ITEM_X_STRIDE = 38;
|
||||
private static final int ITEM_Y_STRIDE = 38;
|
||||
private static final int ORIGINAL_LOST_HEIGHT = 209;
|
||||
private static final int ORIGINAL_LOST_Y = 107;
|
||||
|
||||
// Information panel text helpers
|
||||
private static final String LINE_BREAK = "<br>";
|
||||
private static final int INFORMATION_CONTAINER_HEIGHT = 183;
|
||||
private static final int FONT_COLOR = 0xFF981F;
|
||||
|
||||
// Button Images
|
||||
private static final int PROTECT_ITEM_SPRITE_ID = SpriteID.PRAYER_PROTECT_ITEM;
|
||||
private static final int SKULL_SPRITE_ID = SpriteID.PLAYER_KILLER_SKULL_523;
|
||||
private static final int SWORD_SPRITE_ID = SpriteID.MULTI_COMBAT_ZONE_CROSSED_SWORDS;
|
||||
private static final int SKULL_2_SPRITE_ID = SpriteID.FIGHT_PITS_WINNER_SKULL_RED;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
private WidgetButton deepWildyButton;
|
||||
private WidgetButton lowWildyButton;
|
||||
|
||||
private boolean isSkulled;
|
||||
private boolean protectingItem;
|
||||
private int wildyLevel;
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (event.getEventName().equals("itemsKeptOnDeath"))
|
||||
{
|
||||
// The script in charge of building the Items Kept on Death interface has finished running.
|
||||
// Make all necessary changes now.
|
||||
|
||||
// Players inside Safe Areas (POH/Clan Wars) or playing DMM see the default interface
|
||||
if (isInSafeArea() || client.getWorldType().contains(WorldType.DEADMAN))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
syncSettings();
|
||||
createWidgetButtons();
|
||||
rebuildItemsKeptOnDeathInterface();
|
||||
|
||||
final Widget keptText = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_TEXT);
|
||||
keptText.setText("Items you will keep on death:");
|
||||
|
||||
final Widget lostText = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_TEXT);
|
||||
lostText.setText("Items you will lose on death:");
|
||||
}
|
||||
}
|
||||
|
||||
// Sync user settings
|
||||
private void syncSettings()
|
||||
{
|
||||
final SkullIcon s = client.getLocalPlayer().getSkullIcon();
|
||||
// Ultimate iron men deaths are treated like they are always skulled
|
||||
isSkulled = s == SkullIcon.SKULL || isUltimateIronman();
|
||||
protectingItem = client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1;
|
||||
syncWildernessLevel();
|
||||
}
|
||||
|
||||
private void syncWildernessLevel()
|
||||
{
|
||||
if (client.getVar(Varbits.IN_WILDERNESS) != 1)
|
||||
{
|
||||
// if they are in a PvP world and not in a safe zone act like in lvl 1 wildy
|
||||
if (isInPvpWorld() && !isInPvPSafeZone())
|
||||
{
|
||||
wildyLevel = 1;
|
||||
return;
|
||||
}
|
||||
wildyLevel = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
if (wildernessLevelWidget == null)
|
||||
{
|
||||
wildyLevel = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
final String wildernessLevelText = wildernessLevelWidget.getText();
|
||||
final Matcher m = WILDERNESS_LEVEL_PATTERN.matcher(wildernessLevelText);
|
||||
if (!m.matches())
|
||||
{
|
||||
wildyLevel = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
wildyLevel = Integer.parseInt(m.group(1));
|
||||
}
|
||||
|
||||
private boolean isInPvpWorld()
|
||||
{
|
||||
final EnumSet<WorldType> world = client.getWorldType();
|
||||
return world.contains(WorldType.PVP);
|
||||
}
|
||||
|
||||
private boolean isProtectItemAllowed()
|
||||
{
|
||||
return !client.getWorldType().contains(WorldType.HIGH_RISK)
|
||||
&& !isUltimateIronman();
|
||||
}
|
||||
|
||||
private boolean isInPvPSafeZone()
|
||||
{
|
||||
final Widget w = client.getWidget(WidgetInfo.PVP_WORLD_SAFE_ZONE);
|
||||
return w != null && !w.isHidden();
|
||||
}
|
||||
|
||||
private boolean isInSafeArea()
|
||||
{
|
||||
final Widget w = client.getWidget(WidgetInfo.ITEMS_KEPT_SAFE_ZONE_CONTAINER);
|
||||
return w != null && !w.isHidden();
|
||||
}
|
||||
|
||||
private boolean isUltimateIronman()
|
||||
{
|
||||
return client.getAccountType() == AccountType.ULTIMATE_IRONMAN;
|
||||
}
|
||||
|
||||
private int getDefaultItemsKept()
|
||||
{
|
||||
final int count = isSkulled ? 0 : 3;
|
||||
return count + (protectingItem ? 1 : 0);
|
||||
}
|
||||
|
||||
private void rebuildItemsKeptOnDeathInterface()
|
||||
{
|
||||
final Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
|
||||
final Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
|
||||
if (lost == null || kept == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lost.deleteAllChildren();
|
||||
kept.deleteAllChildren();
|
||||
|
||||
// Grab all items on player
|
||||
final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
|
||||
final Item[] inv = inventory == null ? new Item[0] : inventory.getItems();
|
||||
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
final Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
|
||||
|
||||
final List<Item> items = new ArrayList<>();
|
||||
Collections.addAll(items, inv);
|
||||
Collections.addAll(items, equip);
|
||||
|
||||
// Sort by item price
|
||||
items.sort(Comparator.comparing(this::getDeathPrice).reversed());
|
||||
|
||||
boolean hasAlwaysLost = false;
|
||||
int keepCount = getDefaultItemsKept();
|
||||
|
||||
final List<Widget> keptItems = new ArrayList<>();
|
||||
final List<Widget> lostItems = new ArrayList<>();
|
||||
for (final Item i : items)
|
||||
{
|
||||
final int id = i.getId();
|
||||
int itemQuantity = i.getQuantity();
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final ItemDefinition c = itemManager.getItemDefinition(i.getId());
|
||||
|
||||
// Bonds are always kept and do not count towards the limit.
|
||||
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
|
||||
{
|
||||
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
|
||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
|
||||
keptItems.add(itemWidget);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Certain items are always lost on death and have a white outline which we need to add
|
||||
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(i.getId());
|
||||
if (alwaysLostItem != null)
|
||||
{
|
||||
// Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
|
||||
if (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0)
|
||||
{
|
||||
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
|
||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
|
||||
itemWidget.setBorderType(2); // white outline
|
||||
lostItems.add(itemWidget);
|
||||
hasAlwaysLost = true;
|
||||
continue;
|
||||
}
|
||||
// the rune pouch is "always lost" but its kept outside of pvp, and does not count towards your keep count
|
||||
}
|
||||
else if (keepCount > 0)
|
||||
{
|
||||
// Keep most valuable items regardless of trade-ability.
|
||||
if (i.getQuantity() > keepCount)
|
||||
{
|
||||
final Widget itemWidget = createItemWidget(kept, keepCount, c);
|
||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, keepCount, c.getName());
|
||||
keptItems.add(itemWidget);
|
||||
itemQuantity -= keepCount;
|
||||
keepCount = 0;
|
||||
// Fall through to below to drop the rest of the stack
|
||||
}
|
||||
else
|
||||
{
|
||||
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
|
||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
|
||||
keptItems.add(itemWidget);
|
||||
keepCount -= i.getQuantity();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Items are kept if:
|
||||
// 1) is not tradeable
|
||||
// 2) is under the deep wilderness line
|
||||
// 3) is outside of the wilderness, or item has a broken form
|
||||
if (!Pets.isPet(id)
|
||||
&& !isTradeable(c) && wildyLevel <= DEEP_WILDY
|
||||
&& (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId())))
|
||||
{
|
||||
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
|
||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
|
||||
keptItems.add(itemWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, the item is lost
|
||||
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
|
||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
|
||||
lostItems.add(itemWidget);
|
||||
}
|
||||
}
|
||||
|
||||
int rows = (keptItems.size() + MAX_ROW_ITEMS - 1) / MAX_ROW_ITEMS;
|
||||
// Show an empty row if there isn't anything
|
||||
if (rows > 0)
|
||||
{
|
||||
// ORIGINAL_LOST_Y/HEIGHT includes a row already
|
||||
rows--;
|
||||
}
|
||||
// Adjust items lost container position if new rows were added to kept items container
|
||||
lost.setOriginalY(ORIGINAL_LOST_Y + (rows * ITEM_Y_STRIDE));
|
||||
lost.setOriginalHeight(ORIGINAL_LOST_HEIGHT - (rows * ITEM_Y_STRIDE));
|
||||
positionWidgetItems(kept, keptItems);
|
||||
positionWidgetItems(lost, lostItems);
|
||||
|
||||
updateKeptWidgetInfoText(hasAlwaysLost, keptItems, lostItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price of an item
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
private int getDeathPrice(Item item)
|
||||
{
|
||||
int itemId = item.getId();
|
||||
// Unnote/unplaceholder item
|
||||
int canonicalizedItemId = itemManager.canonicalize(itemId);
|
||||
int exchangePrice = itemManager.getItemPrice(canonicalizedItemId);
|
||||
if (exchangePrice == 0)
|
||||
{
|
||||
final ItemDefinition c1 = itemManager.getItemDefinition(canonicalizedItemId);
|
||||
exchangePrice = c1.getPrice();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some items have artifically applied death prices - such as ring imbues
|
||||
// which are +2k over the non imbues. Check if the item has a fixed price.
|
||||
FixedPriceItem fixedPrice = FixedPriceItem.find(canonicalizedItemId);
|
||||
if (fixedPrice != null)
|
||||
{
|
||||
// Apply fixed price offset
|
||||
exchangePrice += fixedPrice.getOffset();
|
||||
}
|
||||
}
|
||||
return exchangePrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Position a list of widget items in the parent container
|
||||
*/
|
||||
private static void positionWidgetItems(final Widget parent, final List<Widget> widgets)
|
||||
{
|
||||
int startingIndex = 0;
|
||||
for (final Widget w : widgets)
|
||||
{
|
||||
final int originalX = ITEM_X_OFFSET + ((startingIndex % MAX_ROW_ITEMS) * ITEM_X_STRIDE);
|
||||
final int originalY = ITEM_Y_OFFSET + ((startingIndex / MAX_ROW_ITEMS) * ITEM_Y_STRIDE);
|
||||
|
||||
w.setOriginalX(originalX);
|
||||
w.setOriginalY(originalY);
|
||||
w.revalidate();
|
||||
|
||||
++startingIndex;
|
||||
}
|
||||
|
||||
parent.revalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the text to be displayed in the right side of the interface based on current selections
|
||||
*/
|
||||
private String getInfoText(final boolean hasAlwaysLost)
|
||||
{
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (isUltimateIronman())
|
||||
{
|
||||
sb.append("You are an <col=FFFFFF>UIM<col=FF981F> which means <col=FFFFFF>0<col=FF981F> items are protected by default");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("<col=FFFFFF>3<col=FF981F> items protected by default");
|
||||
|
||||
if (isSkulled)
|
||||
{
|
||||
sb.append(LINE_BREAK)
|
||||
.append("<col=ff3333>PK skull<col=ff981f> -3");
|
||||
}
|
||||
|
||||
if (protectingItem)
|
||||
{
|
||||
sb.append(LINE_BREAK)
|
||||
.append("<col=ff3333>Protect Item prayer<col=ff981f> +1");
|
||||
}
|
||||
|
||||
sb.append(LINE_BREAK)
|
||||
.append(String.format("Actually protecting <col=FFFFFF>%s<col=FF981F> items", getDefaultItemsKept()));
|
||||
}
|
||||
|
||||
|
||||
if (wildyLevel < 1)
|
||||
{
|
||||
sb.append(LINE_BREAK)
|
||||
.append(LINE_BREAK)
|
||||
.append("You will have 1 hour to retrieve your lost items.");
|
||||
}
|
||||
|
||||
if (hasAlwaysLost)
|
||||
{
|
||||
sb.append(LINE_BREAK)
|
||||
.append(LINE_BREAK)
|
||||
.append("Items with a <col=ffffff>white outline<col=ff981f> will always be lost.");
|
||||
}
|
||||
|
||||
sb.append(LINE_BREAK)
|
||||
.append(LINE_BREAK)
|
||||
.append("Untradeable items are kept on death in non-pvp scenarios.");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the information panel based on the item containers
|
||||
*/
|
||||
private void updateKeptWidgetInfoText(final boolean hasAlwaysLost, final List<Widget> keptItems, final List<Widget> lostItems)
|
||||
{
|
||||
// Add Information text widget
|
||||
final Widget textWidget = findOrCreateInfoText();
|
||||
textWidget.setText(getInfoText(hasAlwaysLost));
|
||||
textWidget.revalidate();
|
||||
|
||||
// Update Items lost total value
|
||||
long total = 0;
|
||||
for (final Widget w : lostItems)
|
||||
{
|
||||
int cid = itemManager.canonicalize(w.getItemId());
|
||||
int price = itemManager.getItemPrice(cid);
|
||||
if (price == 0)
|
||||
{
|
||||
// Default to alch price
|
||||
price = (int) (itemManager.getItemDefinition(cid).getPrice() * Constants.HIGH_ALCHEMY_MULTIPLIER);
|
||||
}
|
||||
total += (long) price * w.getItemQuantity();
|
||||
}
|
||||
final Widget lostValue = client.getWidget(WidgetInfo.ITEMS_LOST_VALUE);
|
||||
lostValue.setText(StackFormatter.quantityToStackSize(total) + " gp");
|
||||
|
||||
// Update Max items kept
|
||||
final Widget max = client.getWidget(WidgetInfo.ITEMS_KEPT_MAX);
|
||||
final int keptQty = keptItems.stream().mapToInt(Widget::getItemQuantity).sum();
|
||||
max.setText(String.format("<col=ffcc33>Max items kept on death:<br><br><col=ffcc33>~ %d ~", keptQty));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an item is tradeable to another player
|
||||
*
|
||||
* @param c The item
|
||||
* @return
|
||||
*/
|
||||
private static boolean isTradeable(final ItemDefinition c)
|
||||
{
|
||||
// ItemDefinition:: isTradeable checks if they are traded on the grand exchange, some items are trade-able but not via GE
|
||||
if (c.getNote() != -1
|
||||
|| c.getLinkedNoteId() != -1
|
||||
|| c.isTradeable())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final int id = c.getId();
|
||||
switch (id)
|
||||
{
|
||||
case ItemID.COINS_995:
|
||||
case ItemID.PLATINUM_TOKEN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Widget findOrCreateInfoText()
|
||||
{
|
||||
// The text was on the ITEMS_KEPT_INFORMATION_CONTAINER widget - but now that it is a layer,
|
||||
// we need to create a child widget to hold the text
|
||||
final Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
|
||||
|
||||
// Use the text TEXT widget if it already exists. It should be the last child of the parent
|
||||
final Widget[] children = parent.getChildren();
|
||||
if (children != null && children.length > 0)
|
||||
{
|
||||
final Widget w = parent.getChild(children.length - 1);
|
||||
if (w != null && w.getType() == WidgetType.TEXT)
|
||||
{
|
||||
log.debug("Reusing old text widget");
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Creating new text widget");
|
||||
|
||||
final Widget w = parent.createChild(-1, WidgetType.TEXT);
|
||||
// Position under buttons taking remaining space
|
||||
w.setOriginalWidth(parent.getOriginalWidth());
|
||||
w.setOriginalHeight(INFORMATION_CONTAINER_HEIGHT - parent.getOriginalHeight());
|
||||
w.setOriginalY(parent.getOriginalHeight());
|
||||
|
||||
w.setFontId(FontID.PLAIN_11);
|
||||
w.setTextShadowed(true);
|
||||
w.setTextColor(FONT_COLOR);
|
||||
|
||||
// Need to adjust parent height so text is visible
|
||||
parent.setOriginalHeight(INFORMATION_CONTAINER_HEIGHT);
|
||||
parent.revalidate();
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
private void createWidgetButtons()
|
||||
{
|
||||
final Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
|
||||
// Change the information container from a text widget to a layer
|
||||
parent.setType(WidgetType.LAYER);
|
||||
parent.deleteAllChildren();
|
||||
|
||||
// Ultimate Iron men are always skulled and can't use the protect item prayer
|
||||
WidgetButton protectItemButton = isProtectItemAllowed()
|
||||
? new WidgetButton(parent, "Protect Item Prayer", PROTECT_ITEM_SPRITE_ID, protectingItem, selected ->
|
||||
{
|
||||
protectingItem = selected;
|
||||
rebuildItemsKeptOnDeathInterface();
|
||||
}) : null;
|
||||
|
||||
WidgetButton skulledButton = !isUltimateIronman()
|
||||
? new WidgetButton(parent, "Skulled", SKULL_SPRITE_ID, isSkulled, selected ->
|
||||
{
|
||||
isSkulled = selected;
|
||||
rebuildItemsKeptOnDeathInterface();
|
||||
}) : null;
|
||||
|
||||
lowWildyButton = new WidgetButton(parent, "Low Wildy (1-20)", SWORD_SPRITE_ID, wildyLevel > 0 && wildyLevel <= DEEP_WILDY, selected ->
|
||||
{
|
||||
if (!selected)
|
||||
{
|
||||
syncWildernessLevel();
|
||||
}
|
||||
else
|
||||
{
|
||||
wildyLevel = 1;
|
||||
deepWildyButton.setSelected(false);
|
||||
}
|
||||
|
||||
rebuildItemsKeptOnDeathInterface();
|
||||
});
|
||||
|
||||
deepWildyButton = new WidgetButton(parent, "Deep Wildy (21+)", SKULL_2_SPRITE_ID, wildyLevel > DEEP_WILDY, selected ->
|
||||
{
|
||||
if (!selected)
|
||||
{
|
||||
syncWildernessLevel();
|
||||
}
|
||||
else
|
||||
{
|
||||
wildyLevel = DEEP_WILDY + 1;
|
||||
lowWildyButton.setSelected(false);
|
||||
}
|
||||
|
||||
rebuildItemsKeptOnDeathInterface();
|
||||
});
|
||||
|
||||
parent.revalidate();
|
||||
WidgetButton.layoutButtonsToContainer(parent, protectItemButton, skulledButton, lowWildyButton, deepWildyButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Item Widget for use inside the Kept on Death Interface
|
||||
*
|
||||
* @param qty Amount of item
|
||||
* @param c Items Composition
|
||||
* @return
|
||||
*/
|
||||
private static Widget createItemWidget(final Widget parent, final int qty, final ItemDefinition c)
|
||||
{
|
||||
final Widget itemWidget = parent.createChild(-1, WidgetType.GRAPHIC);
|
||||
itemWidget.setItemId(c.getId());
|
||||
itemWidget.setItemQuantity(qty);
|
||||
itemWidget.setHasListener(true);
|
||||
itemWidget.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
|
||||
itemWidget.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
|
||||
itemWidget.setBorderType(1);
|
||||
|
||||
itemWidget.setAction(1, String.format("Item: <col=ff981f>%s", c.getName()));
|
||||
|
||||
return itemWidget;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.itemskeptondeath;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Set;
|
||||
import static net.runelite.api.ItemID.*;
|
||||
|
||||
final class Pets
|
||||
{
|
||||
private Pets()
|
||||
{
|
||||
}
|
||||
|
||||
private static final Set<Integer> PETS = ImmutableSet.of(
|
||||
BABY_MOLE,
|
||||
PRINCE_BLACK_DRAGON,
|
||||
PET_CORPOREAL_CRITTER, PET_DARK_CORE,
|
||||
JALNIBREK, TZREKZUK,
|
||||
KALPHITE_PRINCESS, KALPHITE_PRINCESS_12654,
|
||||
LIL_ZIK,
|
||||
SKOTOS,
|
||||
PET_SNAKELING, PET_SNAKELING_12939, PET_SNAKELING_12940,
|
||||
TZREKJAD,
|
||||
VORKI,
|
||||
|
||||
OLMLET, PUPPADILE, TEKTINY, VANGUARD, VASA_MINIRIO, VESPINA,
|
||||
|
||||
PET_DAGANNOTH_PRIME, PET_DAGANNOTH_REX, PET_DAGANNOTH_SUPREME,
|
||||
|
||||
PET_GENERAL_GRAARDOR, PET_KRIL_TSUTSAROTH, PET_KREEARRA, PET_ZILYANA,
|
||||
|
||||
ABYSSAL_ORPHAN,
|
||||
HELLPUPPY,
|
||||
PET_KRAKEN,
|
||||
MIDNIGHT, NOON,
|
||||
PET_SMOKE_DEVIL, PET_SMOKE_DEVIL_22663,
|
||||
IKKLE_HYDRA, IKKLE_HYDRA_22748, IKKLE_HYDRA_22750, IKKLE_HYDRA_22752,
|
||||
|
||||
CALLISTO_CUB,
|
||||
PET_CHAOS_ELEMENTAL,
|
||||
SCORPIAS_OFFSPRING,
|
||||
VENENATIS_SPIDERLING,
|
||||
VETION_JR, VETION_JR_13180,
|
||||
|
||||
BABY_CHINCHOMPA, BABY_CHINCHOMPA_13324, BABY_CHINCHOMPA_13325, BABY_CHINCHOMPA_13326,
|
||||
BEAVER,
|
||||
GIANT_SQUIRREL,
|
||||
HERON,
|
||||
RIFT_GUARDIAN, RIFT_GUARDIAN_20667, RIFT_GUARDIAN_20669, RIFT_GUARDIAN_20671, RIFT_GUARDIAN_20673, RIFT_GUARDIAN_20675,
|
||||
RIFT_GUARDIAN_20677, RIFT_GUARDIAN_20679, RIFT_GUARDIAN_20681, RIFT_GUARDIAN_20683, RIFT_GUARDIAN_20685, RIFT_GUARDIAN_20687,
|
||||
RIFT_GUARDIAN_20689, RIFT_GUARDIAN_20691, RIFT_GUARDIAN_21990,
|
||||
ROCK_GOLEM, ROCK_GOLEM_21187, ROCK_GOLEM_21188, ROCK_GOLEM_21189, ROCK_GOLEM_21190, ROCK_GOLEM_21191, ROCK_GOLEM_21192,
|
||||
ROCK_GOLEM_21193, ROCK_GOLEM_21194, ROCK_GOLEM_21195, ROCK_GOLEM_21196, ROCK_GOLEM_21197, ROCK_GOLEM_21340, ROCK_GOLEM_21358,
|
||||
ROCK_GOLEM_21359, ROCK_GOLEM_21360,
|
||||
ROCKY,
|
||||
TANGLEROOT,
|
||||
|
||||
PET_KITTEN, PET_KITTEN_1556, PET_KITTEN_1557, PET_KITTEN_1558, PET_KITTEN_1559, PET_KITTEN_1560,
|
||||
PET_CAT, PET_CAT_1562, PET_CAT_1563, PET_CAT_1564, PET_CAT_1565, PET_CAT_1566, PET_CAT_1567, PET_CAT_1568, PET_CAT_1569,
|
||||
PET_CAT_1570, PET_CAT_1571, PET_CAT_1572,
|
||||
LAZY_CAT, LAZY_CAT_6550, LAZY_CAT_6551, LAZY_CAT_6552, LAZY_CAT_6553, LAZY_CAT_6554,
|
||||
WILY_CAT, WILY_CAT_6556, WILY_CAT_6557, WILY_CAT_6558, WILY_CAT_6559, WILY_CAT_6560,
|
||||
OVERGROWN_HELLCAT, HELL_CAT, HELLKITTEN, LAZY_HELL_CAT, WILY_HELLCAT,
|
||||
|
||||
BLOODHOUND,
|
||||
CHOMPY_CHICK,
|
||||
HERBI,
|
||||
PET_PENANCE_QUEEN,
|
||||
PHOENIX
|
||||
);
|
||||
|
||||
public static boolean isPet(int id)
|
||||
{
|
||||
return PETS.contains(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* 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.itemskeptondeath;
|
||||
|
||||
import net.runelite.api.ScriptEvent;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetType;
|
||||
|
||||
class WidgetButton
|
||||
{
|
||||
private static final int ICON_HEIGHT = 26;
|
||||
private static final int ICON_WIDTH = 26;
|
||||
private static final int BACKGROUND_HEIGHT = 32;
|
||||
private static final int BACKGROUND_WIDTH = 32;
|
||||
private static final int PADDING = 5;
|
||||
private static final int ICON_PADDING = (BACKGROUND_HEIGHT - ICON_HEIGHT) / 2;
|
||||
|
||||
private static final int BACKGROUND_SPRITE_ID = SpriteID.EQUIPMENT_SLOT_TILE;
|
||||
private static final int SELECTED_BACKGROUND_SPRITE_ID = SpriteID.EQUIPMENT_SLOT_SELECTED;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface WidgetButtonCallback
|
||||
{
|
||||
void run(boolean newState);
|
||||
}
|
||||
|
||||
private final Widget parent;
|
||||
private final String name;
|
||||
private final int spriteID;
|
||||
private boolean selected;
|
||||
private final WidgetButtonCallback callback;
|
||||
|
||||
private Widget icon;
|
||||
private Widget background;
|
||||
|
||||
WidgetButton(
|
||||
final Widget parent,
|
||||
final String name,
|
||||
final int spriteID,
|
||||
final boolean selectedStartState,
|
||||
final WidgetButtonCallback callback)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.spriteID = spriteID;
|
||||
this.selected = selectedStartState;
|
||||
this.callback = callback;
|
||||
createBackgroundWidget();
|
||||
createIconWidget();
|
||||
}
|
||||
|
||||
private void createBackgroundWidget()
|
||||
{
|
||||
background = createWidget();
|
||||
background.setOriginalWidth(BACKGROUND_WIDTH);
|
||||
background.setOriginalHeight(BACKGROUND_HEIGHT);
|
||||
syncBackgroundSprite();
|
||||
}
|
||||
|
||||
private void createIconWidget()
|
||||
{
|
||||
icon = createWidget();
|
||||
icon.setAction(1, "Toggle:");
|
||||
icon.setOnOpListener((JavaScriptCallback) this::onButtonClicked);
|
||||
icon.setOnMouseRepeatListener((JavaScriptCallback) e -> e.getSource().setOpacity(120));
|
||||
icon.setOnMouseLeaveListener((JavaScriptCallback) e -> e.getSource().setOpacity(0));
|
||||
icon.setHasListener(true);
|
||||
icon.setSpriteId(spriteID);
|
||||
}
|
||||
|
||||
private Widget createWidget()
|
||||
{
|
||||
final Widget w = parent.createChild(-1, WidgetType.GRAPHIC);
|
||||
w.setOriginalWidth(ICON_WIDTH);
|
||||
w.setOriginalHeight(ICON_HEIGHT);
|
||||
w.setName("<col=ff981f>" + this.name);
|
||||
return w;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected)
|
||||
{
|
||||
this.selected = selected;
|
||||
syncBackgroundSprite();
|
||||
}
|
||||
|
||||
private void syncBackgroundSprite()
|
||||
{
|
||||
background.setSpriteId(selected ? SELECTED_BACKGROUND_SPRITE_ID : BACKGROUND_SPRITE_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the collection of WidgetButtons to the container overriding any existing children.
|
||||
*
|
||||
* @param container Widget to add buttons too
|
||||
* @param buttons buttons to add
|
||||
*/
|
||||
static void layoutButtonsToContainer(final Widget container, final WidgetButton... buttons)
|
||||
{
|
||||
// Each button has two widgets, Icon and Background
|
||||
final int xIncrement = BACKGROUND_WIDTH + PADDING;
|
||||
final int yIncrement = BACKGROUND_HEIGHT + PADDING;
|
||||
int maxRowItems = container.getWidth() / xIncrement;
|
||||
// Ensure at least 1 button per row
|
||||
maxRowItems = maxRowItems < 1 ? 1 : maxRowItems;
|
||||
|
||||
int index = 0;
|
||||
for (final WidgetButton w : buttons)
|
||||
{
|
||||
if (w == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final int originalX = ((index % maxRowItems) * xIncrement);
|
||||
final int originalY = ((index / maxRowItems) * yIncrement);
|
||||
w.background.setOriginalX(originalX);
|
||||
w.background.setOriginalY(originalY);
|
||||
w.background.revalidate();
|
||||
|
||||
// Icon must be padded to center inside image
|
||||
w.icon.setOriginalX(originalX + ICON_PADDING);
|
||||
w.icon.setOriginalY(originalY + ICON_PADDING);
|
||||
w.icon.revalidate();
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
final int numButtons = index;
|
||||
final int rows = 1 + (numButtons > maxRowItems ? numButtons / maxRowItems : 0);
|
||||
container.setOriginalHeight(yIncrement * rows);
|
||||
container.revalidate();
|
||||
}
|
||||
|
||||
private void onButtonClicked(ScriptEvent scriptEvent)
|
||||
{
|
||||
setSelected(!selected);
|
||||
callback.run(selected);
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,16 @@ public interface ItemStatConfig extends Config
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showWeight",
|
||||
name = "Show Weight",
|
||||
description = "Show weight in tooltip"
|
||||
)
|
||||
default boolean showWeight()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "colorBetterUncapped",
|
||||
name = "Better (Uncapped)",
|
||||
|
||||
@@ -189,7 +189,10 @@ public class ItemStatOverlay extends Overlay
|
||||
private String buildStatBonusString(ItemStats s)
|
||||
{
|
||||
final StringBuilder b = new StringBuilder();
|
||||
b.append(getChangeString("Weight", s.getWeight(), true, false));
|
||||
if (config.showWeight())
|
||||
{
|
||||
b.append(getChangeString("Weight", s.getWeight(), true, false));
|
||||
}
|
||||
|
||||
ItemStats other = null;
|
||||
final ItemEquipmentStats currentEquipment = s.getEquipment();
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
@@ -232,8 +233,8 @@ public class ItemStatPlugin extends Plugin
|
||||
Widget icon = invContainer.createChild(-1, WidgetType.GRAPHIC);
|
||||
icon.setOriginalX(8);
|
||||
icon.setOriginalY(yPos);
|
||||
icon.setOriginalWidth(36);
|
||||
icon.setOriginalHeight(32);
|
||||
icon.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
|
||||
icon.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
|
||||
icon.setItemId(id);
|
||||
icon.setItemQuantityMode(0);
|
||||
icon.setBorderType(1);
|
||||
|
||||
@@ -179,9 +179,9 @@ public class KourendLibraryPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked menuOpt)
|
||||
{
|
||||
if (MenuAction.GAME_OBJECT_FIRST_OPTION == menuOpt.getMenuAction() && menuOpt.getMenuTarget().contains("Bookshelf"))
|
||||
if (MenuAction.GAME_OBJECT_FIRST_OPTION == menuOpt.getMenuAction() && menuOpt.getTarget().contains("Bookshelf"))
|
||||
{
|
||||
lastBookcaseClick = WorldPoint.fromScene(client, menuOpt.getActionParam(), menuOpt.getWidgetId(), client.getPlane());
|
||||
lastBookcaseClick = WorldPoint.fromScene(client, menuOpt.getActionParam0(), menuOpt.getActionParam1(), client.getPlane());
|
||||
overlay.setHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
class LootingBagViewerOverlay extends Overlay
|
||||
public class LootingBagViewerOverlay extends Overlay
|
||||
{
|
||||
private static final int INVENTORY_SIZE = 28;
|
||||
private static final int PLACEHOLDER_WIDTH = 36;
|
||||
public static final int PLACEHOLDER_WIDTH = 36;
|
||||
private static final int PLACEHOLDER_HEIGHT = 32;
|
||||
private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR));
|
||||
|
||||
|
||||
@@ -35,7 +35,9 @@ public interface LootTrackerConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "ignoredItems",
|
||||
name = "Ignored items",
|
||||
description = "Configures which items should be ignored when calculating loot prices."
|
||||
description = "Configures which items should be ignored when calculating loot prices.",
|
||||
position = 0,
|
||||
group = "Filters"
|
||||
)
|
||||
default String getIgnoredItems()
|
||||
{
|
||||
@@ -91,6 +93,7 @@ public interface LootTrackerConfig extends Config
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "sortType",
|
||||
name = "Sorting",
|
||||
@@ -101,4 +104,59 @@ public interface LootTrackerConfig extends Config
|
||||
return LootRecordSortType.TIMESTAMP;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "whitelistEnabled",
|
||||
name = "NPC Whitelist",
|
||||
description = "Only track drops from specific NPCs",
|
||||
position = 1,
|
||||
group = "Filters",
|
||||
disabledBy = "blacklistEnabled"
|
||||
)
|
||||
default boolean whitelistEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "getWhitelist",
|
||||
name = "Whitelist",
|
||||
description = "Comma-separated list of NPCs to track drops from",
|
||||
position = 2,
|
||||
group = "Filters",
|
||||
hidden = true,
|
||||
unhide = "whitelistEnabled"
|
||||
)
|
||||
default String getWhitelist()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "blacklistEnabled",
|
||||
name = "NPC Blacklist",
|
||||
description = "Track drops from all NPCs except for specified ones",
|
||||
position = 3,
|
||||
group = "Filters",
|
||||
disabledBy = "whitelistEnabled"
|
||||
)
|
||||
default boolean blacklistEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "getBlacklist",
|
||||
name = "Blacklist",
|
||||
description = "Comma-separated list of NPCs to not track drops from",
|
||||
position = 4,
|
||||
group = "Filters",
|
||||
hidden = true,
|
||||
unhide = "blacklistEnabled"
|
||||
)
|
||||
default String getBlacklist()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -323,13 +323,14 @@ public class LootTrackerPlugin extends Plugin
|
||||
log.debug("Loaded {} remote data entries", lootRecords.size());
|
||||
}
|
||||
|
||||
if (config.localPersistence() )
|
||||
if (config.localPersistence())
|
||||
{
|
||||
try
|
||||
{
|
||||
lootRecords.addAll(RuneLiteAPI.GSON.fromJson(new FileReader(LOOT_RECORDS_FILE),
|
||||
new TypeToken<ArrayList<LootRecord>>()
|
||||
{ }.getType()));
|
||||
{
|
||||
}.getType()));
|
||||
}
|
||||
catch (IOException | NullPointerException e)
|
||||
{
|
||||
@@ -370,8 +371,28 @@ public class LootTrackerPlugin extends Plugin
|
||||
final int combat = npc.getCombatLevel();
|
||||
final LootTrackerItem[] entries = buildEntries(stack(items));
|
||||
String localUsername = client.getLocalPlayer().getName();
|
||||
|
||||
if (config.whitelistEnabled())
|
||||
{
|
||||
final String configNpcs = config.getWhitelist().toLowerCase();
|
||||
List<String> whitelist = Text.fromCSV(configNpcs);
|
||||
if (!whitelist.contains(name.toLowerCase()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (config.blacklistEnabled())
|
||||
{
|
||||
final String configNpcs = config.getBlacklist().toLowerCase();
|
||||
List<String> blacklist = Text.fromCSV(configNpcs);
|
||||
if (blacklist.contains(name.toLowerCase()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.add(name, localUsername, combat, entries));
|
||||
LootRecord lootRecord = new LootRecord( name, localUsername, LootRecordType.NPC,
|
||||
LootRecord lootRecord = new LootRecord(name, localUsername, LootRecordType.NPC,
|
||||
toGameItems(items), Instant.now());
|
||||
|
||||
if (lootTrackerClient != null && config.saveLoot())
|
||||
@@ -404,7 +425,7 @@ public class LootTrackerPlugin extends Plugin
|
||||
final LootTrackerItem[] entries = buildEntries(stack(items));
|
||||
String localUsername = client.getLocalPlayer().getName();
|
||||
SwingUtilities.invokeLater(() -> panel.add(name, localUsername, combat, entries));
|
||||
LootRecord lootRecord = new LootRecord( name, localUsername, LootRecordType.PLAYER,
|
||||
LootRecord lootRecord = new LootRecord(name, localUsername, LootRecordType.PLAYER,
|
||||
toGameItems(items), Instant.now());
|
||||
if (lootTrackerClient != null && config.saveLoot())
|
||||
{
|
||||
@@ -599,7 +620,7 @@ public class LootTrackerPlugin extends Plugin
|
||||
SwingUtilities.invokeLater(() -> panel.add(name, client.getLocalPlayer().getName(),
|
||||
client.getLocalPlayer().getCombatLevel(), entries));
|
||||
LootRecord lootRecord = new LootRecord(name, client.getLocalPlayer().getName(), LootRecordType.DEATH,
|
||||
toGameItems(itemsLost), Instant.now());
|
||||
toGameItems(itemsLost), Instant.now());
|
||||
if (lootTrackerClient != null && config.saveLoot())
|
||||
{
|
||||
lootTrackerClient.submit(lootRecord);
|
||||
@@ -685,10 +706,10 @@ public class LootTrackerPlugin extends Plugin
|
||||
.forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity()));
|
||||
}
|
||||
|
||||
if (equipment != null)
|
||||
{
|
||||
Arrays.stream(equipment.getItems())
|
||||
.forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity()));
|
||||
if (equipment != null)
|
||||
{
|
||||
Arrays.stream(equipment.getItems())
|
||||
.forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -474,20 +474,20 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE || event.getWidgetId() != WidgetInfo.INVENTORY.getId())
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE || event.getActionParam1() != WidgetInfo.INVENTORY.getId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = event.getId();
|
||||
int itemId = event.getIdentifier();
|
||||
|
||||
if (itemId == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String option = event.getMenuOption();
|
||||
String target = event.getMenuTarget();
|
||||
String option = event.getOption();
|
||||
String target = event.getTarget();
|
||||
ItemDefinition itemComposition = client.getItemDefinition(itemId);
|
||||
|
||||
if (option.equals(RESET) && target.equals(MENU_TARGET))
|
||||
@@ -862,7 +862,7 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target.equals("magpie impling jar") || (target.equals("nature impling jar")))
|
||||
else if (target.equals("magpie impling jar") || (target.equals("nature impling jar")) || (target.equals("ninja impling jar")))
|
||||
{
|
||||
if (client.getItemContainer(InventoryID.INVENTORY) != null)
|
||||
{
|
||||
@@ -1309,7 +1309,17 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
|
||||
if (!Strings.isNullOrEmpty(config))
|
||||
{
|
||||
Map<String, String> split = NEWLINE_SPLITTER.withKeyValueSeparator(':').split(config);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (String str : config.split("\n"))
|
||||
{
|
||||
if (!str.startsWith("//"))
|
||||
{
|
||||
sb.append(str + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> split = NEWLINE_SPLITTER.withKeyValueSeparator(':').split(sb);
|
||||
|
||||
for (Map.Entry<String, String> entry : split.entrySet())
|
||||
{
|
||||
|
||||
@@ -32,12 +32,22 @@ public class Parse
|
||||
{
|
||||
try
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (String str : value.split("\n"))
|
||||
{
|
||||
if (!str.startsWith("//"))
|
||||
{
|
||||
sb.append(str + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
Splitter NEWLINE_SPLITTER = Splitter
|
||||
.on("\n")
|
||||
.omitEmptyStrings()
|
||||
.trimResults();
|
||||
|
||||
NEWLINE_SPLITTER.withKeyValueSeparator(':').split(value);
|
||||
NEWLINE_SPLITTER.withKeyValueSeparator(':').split(sb);
|
||||
return true;
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
|
||||
@@ -47,7 +47,7 @@ class MiningOverlay extends Overlay
|
||||
{
|
||||
// Range of Motherlode vein respawn time not 100% confirmed but based on observation
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private static final int ORE_VEIN_MAX_RESPAWN_TIME = 123;
|
||||
public static final int ORE_VEIN_MAX_RESPAWN_TIME = 123;
|
||||
private static final int ORE_VEIN_MIN_RESPAWN_TIME = 90;
|
||||
private static final float ORE_VEIN_RANDOM_PERCENT_THRESHOLD = (float) ORE_VEIN_MIN_RESPAWN_TIME / ORE_VEIN_MAX_RESPAWN_TIME;
|
||||
private static final Color DARK_GREEN = new Color(0, 100, 0);
|
||||
|
||||
@@ -168,6 +168,7 @@ public class MiningPlugin extends Plugin
|
||||
case ORE_VEIN_26663: // Motherlode vein
|
||||
case ORE_VEIN_26664: // Motherlode vein
|
||||
{
|
||||
// If the vein respawns before the timer is up, remove it
|
||||
final WorldPoint point = object.getWorldLocation();
|
||||
respawns.removeIf(rockRespawn -> rockRespawn.getWorldPoint().equals(point));
|
||||
break;
|
||||
|
||||
@@ -49,6 +49,7 @@ import static net.runelite.api.ObjectID.ROCKS_11376;
|
||||
import static net.runelite.api.ObjectID.ROCKS_11377;
|
||||
import static net.runelite.api.ObjectID.ROCKS_11386;
|
||||
import static net.runelite.api.ObjectID.ROCKS_11387;
|
||||
import static net.runelite.api.ObjectID.ASH_PILE;
|
||||
|
||||
enum Rock
|
||||
{
|
||||
@@ -98,8 +99,9 @@ enum Rock
|
||||
return inMiningGuild ? Duration.ofMinutes(6) : super.respawnTime;
|
||||
}
|
||||
},
|
||||
ORE_VEIN(Duration.ofSeconds(MiningOverlay.getORE_VEIN_MAX_RESPAWN_TIME()), 150),
|
||||
AMETHYST(Duration.ofSeconds(75), 120);
|
||||
ORE_VEIN(Duration.ofSeconds(MiningOverlay.ORE_VEIN_MAX_RESPAWN_TIME), 150),
|
||||
AMETHYST(Duration.ofSeconds(75), 120),
|
||||
ASH_VEIN(Duration.ofSeconds(30), 0, ASH_PILE);
|
||||
|
||||
private static final Map<Integer, Rock> ROCKS;
|
||||
|
||||
|
||||
@@ -328,11 +328,11 @@ public class MotherlodePlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
if (MINE_SPOTS.contains(menu.getId()) && menu.getMenuAction() == MenuAction.GAME_OBJECT_FIRST_OPTION)
|
||||
if (MINE_SPOTS.contains(menu.getIdentifier()) && menu.getMenuAction() == MenuAction.GAME_OBJECT_FIRST_OPTION)
|
||||
{
|
||||
resetIdleChecks();
|
||||
int veinX = menu.getActionParam();
|
||||
int veinY = menu.getWidgetId();
|
||||
int veinX = menu.getActionParam0();
|
||||
int veinY = menu.getActionParam1();
|
||||
targetVeinLocation = WorldPoint.fromScene(client, veinX, veinY, client.getPlane());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2019, Enza-Denino <https://github.com/Enza-Denino>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,11 +35,12 @@ import net.runelite.api.Constants;
|
||||
|
||||
public class MapLocations
|
||||
{
|
||||
private static final List<Shape>[] MULTICOMBAT = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] NOT_MULTICOMBAT = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] ROUGH_WILDERNESS = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] MULTICOMBAT = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] NOT_MULTICOMBAT = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] ROUGH_WILDERNESS = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] WILDERNESS_LEVEL_LINES = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] DEADMAN_SAFE_ZONES = new List[Constants.MAX_Z];
|
||||
private static final List<Shape>[] PVP_WORLD_SAFE_ZONES = new List[Constants.MAX_Z];
|
||||
|
||||
private static Area getArea(List<Shape> shapes)
|
||||
{
|
||||
@@ -87,6 +89,16 @@ public class MapLocations
|
||||
return getArea(ROUGH_WILDERNESS[plane], view);
|
||||
}
|
||||
|
||||
public static Area getWildernessLevelLines(int plane)
|
||||
{
|
||||
return getArea(WILDERNESS_LEVEL_LINES[plane]);
|
||||
}
|
||||
|
||||
public static Area getWildernessLevelLines(Rectangle view, int plane)
|
||||
{
|
||||
return getArea(WILDERNESS_LEVEL_LINES[plane], view);
|
||||
}
|
||||
|
||||
public static Area getDeadmanSafeZones(int plane)
|
||||
{
|
||||
return getArea(DEADMAN_SAFE_ZONES[plane]);
|
||||
@@ -107,33 +119,28 @@ public class MapLocations
|
||||
return getArea(PVP_WORLD_SAFE_ZONES[plane], view);
|
||||
}
|
||||
|
||||
private static void initializeWithEmptyLists(List<Shape>[] array)
|
||||
{
|
||||
for (int i = 0; i < array.length; i++)
|
||||
{
|
||||
array[i] = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
for (int i = 0; i < MULTICOMBAT.length; i++)
|
||||
{
|
||||
MULTICOMBAT[i] = new ArrayList<>();
|
||||
}
|
||||
for (int i = 0; i < NOT_MULTICOMBAT.length; i++)
|
||||
{
|
||||
NOT_MULTICOMBAT[i] = new ArrayList<>();
|
||||
}
|
||||
for (int i = 0; i < ROUGH_WILDERNESS.length; i++)
|
||||
{
|
||||
ROUGH_WILDERNESS[i] = new ArrayList<>();
|
||||
}
|
||||
for (int i = 0; i < DEADMAN_SAFE_ZONES.length; i++)
|
||||
{
|
||||
DEADMAN_SAFE_ZONES[i] = new ArrayList<>();
|
||||
}
|
||||
for (int i = 0; i < PVP_WORLD_SAFE_ZONES.length; i++)
|
||||
{
|
||||
PVP_WORLD_SAFE_ZONES[i] = new ArrayList<>();
|
||||
}
|
||||
initializeWithEmptyLists(MULTICOMBAT);
|
||||
initializeWithEmptyLists(NOT_MULTICOMBAT);
|
||||
initializeWithEmptyLists(ROUGH_WILDERNESS);
|
||||
initializeWithEmptyLists(WILDERNESS_LEVEL_LINES);
|
||||
initializeWithEmptyLists(DEADMAN_SAFE_ZONES);
|
||||
initializeWithEmptyLists(PVP_WORLD_SAFE_ZONES);
|
||||
|
||||
defineMulticombatAreas();
|
||||
defineDeadmanSafeZones();
|
||||
definePvpSafeZones();
|
||||
defineWilderness();
|
||||
defineWildernessLevelLines();
|
||||
}
|
||||
|
||||
private static void defineMulticombatAreas()
|
||||
@@ -3441,6 +3448,33 @@ public class MapLocations
|
||||
3264, 9918);
|
||||
}
|
||||
|
||||
private static void defineWildernessLevelLines()
|
||||
{
|
||||
int wildyLeftX = 2944;
|
||||
int wildyRightX = 3392;
|
||||
int wildyBottomY = 3525;
|
||||
int wildyTopY = 3971;
|
||||
|
||||
// define wilderness level lines at ground level
|
||||
int accumulatedY = 0;
|
||||
for (int level = 1; level <= 56; level++)
|
||||
{
|
||||
int levelTiles = level == 1 ? 3 : 8;
|
||||
// only draw every 2 levels, otherwise lines on two adjacent levels will collide
|
||||
// and it will not show up
|
||||
if (level % 2 != 0)
|
||||
{
|
||||
addPolygonTo(WILDERNESS_LEVEL_LINES,
|
||||
wildyLeftX, wildyBottomY + accumulatedY,
|
||||
wildyRightX, wildyBottomY + accumulatedY,
|
||||
wildyRightX, wildyBottomY + accumulatedY + levelTiles,
|
||||
wildyLeftX, wildyBottomY + accumulatedY + levelTiles);
|
||||
}
|
||||
accumulatedY += levelTiles;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void addPolygonTo(List<Shape>[] shapes, int... coords)
|
||||
{
|
||||
Polygon poly = new Polygon();
|
||||
@@ -3476,4 +3510,4 @@ public class MapLocations
|
||||
shapes[i].add(poly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2019, Enza-Denino <https://github.com/Enza-Denino>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -66,14 +67,14 @@ public interface MultiIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "collisionDetection",
|
||||
name = "Collision detection",
|
||||
description = "Only show lines where they can be walked through",
|
||||
keyName = "wildernessLevelLines",
|
||||
name = "Wilderness level lines",
|
||||
description = "Show wilderness level lines",
|
||||
position = 4
|
||||
)
|
||||
default boolean collisionDetection()
|
||||
default boolean showWildernessLevelLines()
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
@@ -108,4 +109,16 @@ public interface MultiIndicatorsConfig extends Config
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "wildernessLevelLinesColor",
|
||||
name = "Wilderness level lines color",
|
||||
description = "Choose color to use for marking wilderness level lines",
|
||||
position = 8
|
||||
)
|
||||
default Color wildernessLevelLinesColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2019, Enza-Denino <https://github.com/Enza-Denino>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -102,6 +103,7 @@ public class MultiIndicatorsMinimapOverlay extends Overlay
|
||||
|
||||
GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()];
|
||||
GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()];
|
||||
GeneralPath wildernessLevelLinesPath = plugin.getWildernessLevelLinesPathToDisplay()[client.getPlane()];
|
||||
|
||||
if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null)
|
||||
{
|
||||
@@ -111,6 +113,10 @@ public class MultiIndicatorsMinimapOverlay extends Overlay
|
||||
{
|
||||
renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor()));
|
||||
}
|
||||
if (config.showWildernessLevelLines() && wildernessLevelLinesPath != null)
|
||||
{
|
||||
renderPath(graphics, wildernessLevelLinesPath, getTransparentColorVersion(config.wildernessLevelLinesColor()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2019, Enza-Denino <https://github.com/Enza-Denino>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -98,6 +99,7 @@ public class MultiIndicatorsOverlay extends Overlay
|
||||
{
|
||||
GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()];
|
||||
GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()];
|
||||
GeneralPath wildernessLevelLinesPath = plugin.getWildernessLevelLinesPathToDisplay()[client.getPlane()];
|
||||
|
||||
if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null)
|
||||
{
|
||||
@@ -107,6 +109,10 @@ public class MultiIndicatorsOverlay extends Overlay
|
||||
{
|
||||
renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor()));
|
||||
}
|
||||
if (config.showWildernessLevelLines() && wildernessLevelLinesPath != null)
|
||||
{
|
||||
renderPath(graphics, wildernessLevelLinesPath, getTransparentColorVersion(config.wildernessLevelLinesColor()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2019, Enza-Denino <https://github.com/Enza-Denino>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,6 +28,7 @@ package net.runelite.client.plugins.multiindicators;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
@@ -50,6 +52,7 @@ import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
@@ -86,6 +89,9 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
@Getter
|
||||
private GeneralPath[] pvpPathToDisplay;
|
||||
|
||||
@Getter
|
||||
private GeneralPath[] wildernessLevelLinesPathToDisplay;
|
||||
|
||||
@Getter
|
||||
private boolean inPvp;
|
||||
|
||||
@@ -106,8 +112,7 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(minimapOverlay);
|
||||
|
||||
multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z];
|
||||
pvpPathToDisplay = new GeneralPath[Constants.MAX_Z];
|
||||
initializePaths();
|
||||
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
@@ -124,8 +129,37 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(minimapOverlay);
|
||||
|
||||
uninitializePaths();
|
||||
}
|
||||
|
||||
private void initializePaths()
|
||||
{
|
||||
multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z];
|
||||
pvpPathToDisplay = new GeneralPath[Constants.MAX_Z];
|
||||
wildernessLevelLinesPathToDisplay = new GeneralPath[Constants.MAX_Z];
|
||||
}
|
||||
|
||||
private void uninitializePaths()
|
||||
{
|
||||
multicombatPathToDisplay = null;
|
||||
pvpPathToDisplay = null;
|
||||
wildernessLevelLinesPathToDisplay = null;
|
||||
}
|
||||
|
||||
// sometimes the lines get offset (seems to happen when there is a delay
|
||||
// due to map reloading when walking/running "Loading - please wait")
|
||||
// resetting the lines generation logic fixes this
|
||||
@Schedule(
|
||||
period = 1800,
|
||||
unit = ChronoUnit.MILLIS
|
||||
)
|
||||
public void update()
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
findLinesInScene();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void transformWorldToLocal(float[] coords)
|
||||
@@ -134,7 +168,6 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2;
|
||||
coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2;
|
||||
}
|
||||
|
||||
private boolean isOpenableAt(WorldPoint wp)
|
||||
{
|
||||
int sceneX = wp.getX() - client.getBaseX();
|
||||
@@ -153,6 +186,7 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
}
|
||||
|
||||
ObjectDefinition objectComposition = client.getObjectDefinition(wallObject.getId());
|
||||
|
||||
if (objectComposition == null)
|
||||
{
|
||||
return false;
|
||||
@@ -240,7 +274,7 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
lines = Geometry.clipPath(lines, MapLocations.getRoughWilderness(i));
|
||||
}
|
||||
lines = Geometry.splitIntoSegments(lines, 1);
|
||||
if (config.collisionDetection())
|
||||
if (useCollisionLogic())
|
||||
{
|
||||
lines = Geometry.filterPath(lines, this::collisionFilter);
|
||||
}
|
||||
@@ -267,7 +301,7 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
{
|
||||
safeZonePath = Geometry.clipPath(safeZonePath, sceneRect);
|
||||
safeZonePath = Geometry.splitIntoSegments(safeZonePath, 1);
|
||||
if (config.collisionDetection())
|
||||
if (useCollisionLogic())
|
||||
{
|
||||
safeZonePath = Geometry.filterPath(safeZonePath, this::collisionFilter);
|
||||
}
|
||||
@@ -275,6 +309,35 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
}
|
||||
pvpPathToDisplay[i] = safeZonePath;
|
||||
}
|
||||
|
||||
// Generate wilderness level lines
|
||||
for (int i = 0; i < wildernessLevelLinesPathToDisplay.length; i++)
|
||||
{
|
||||
currentPlane = i;
|
||||
|
||||
GeneralPath wildernessLevelLinesPath = null;
|
||||
if (config.showWildernessLevelLines())
|
||||
{
|
||||
wildernessLevelLinesPath = new GeneralPath(MapLocations.getWildernessLevelLines(sceneRect, i));
|
||||
}
|
||||
if (wildernessLevelLinesPath != null)
|
||||
{
|
||||
wildernessLevelLinesPath = Geometry.clipPath(wildernessLevelLinesPath, sceneRect);
|
||||
wildernessLevelLinesPath = Geometry.splitIntoSegments(wildernessLevelLinesPath, 1);
|
||||
if (useCollisionLogic())
|
||||
{
|
||||
wildernessLevelLinesPath = Geometry.filterPath(wildernessLevelLinesPath, this::collisionFilter);
|
||||
}
|
||||
wildernessLevelLinesPath = Geometry.transformPath(wildernessLevelLinesPath, this::transformWorldToLocal);
|
||||
}
|
||||
wildernessLevelLinesPathToDisplay[i] = wildernessLevelLinesPath;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean useCollisionLogic()
|
||||
{
|
||||
// currently prevents overlay lines from showing up if this is ever enabled right now
|
||||
return false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -283,7 +346,8 @@ public class MultiIndicatorsPlugin extends Plugin
|
||||
if (event.getKey().equals("collisionDetection") ||
|
||||
event.getKey().equals("multicombatZoneVisibility") ||
|
||||
event.getKey().equals("deadmanSafeZones") ||
|
||||
event.getKey().equals("pvpSafeZones"))
|
||||
event.getKey().equals("pvpSafeZones") ||
|
||||
event.getKey().equals("wildernessLevelLines"))
|
||||
{
|
||||
findLinesInScene();
|
||||
}
|
||||
|
||||
@@ -40,4 +40,4 @@ public enum ZoneVisibility
|
||||
{
|
||||
return visibility;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,13 +286,13 @@ public class NpcIndicatorsPlugin extends Plugin
|
||||
public void onMenuOptionClicked(MenuOptionClicked click)
|
||||
{
|
||||
if (click.getMenuAction() != MenuAction.RUNELITE
|
||||
|| (!click.getMenuOption().equals(TAG)
|
||||
&& !click.getMenuOption().equals(UNTAG)))
|
||||
|| (!click.getOption().equals(TAG)
|
||||
&& !click.getOption().equals(UNTAG)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int id = click.getId();
|
||||
final int id = click.getIdentifier();
|
||||
final boolean removed = npcTags.remove(id);
|
||||
final NPC[] cachedNPCs = client.getCachedNPCs();
|
||||
final NPC npc = cachedNPCs[id];
|
||||
|
||||
@@ -272,20 +272,20 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuAction() != MenuAction.RUNELITE
|
||||
|| (!event.getMenuOption().equals(MARK)
|
||||
&& !event.getMenuOption().equals(UNMARK)))
|
||||
|| (!event.getOption().equals(MARK)
|
||||
&& !event.getOption().equals(UNMARK)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Scene scene = client.getScene();
|
||||
Tile[][][] tiles = scene.getTiles();
|
||||
final int x = event.getActionParam();
|
||||
final int y = event.getWidgetId();
|
||||
final int x = event.getActionParam0();
|
||||
final int y = event.getActionParam1();
|
||||
final int z = client.getPlane();
|
||||
final Tile tile = tiles[z][x][y];
|
||||
|
||||
TileObject object = findTileObject(tile, event.getId());
|
||||
TileObject object = findTileObject(tile, event.getIdentifier());
|
||||
if (object == null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -73,6 +73,8 @@ import net.runelite.client.util.Text;
|
||||
)
|
||||
public class PestControlPlugin extends Plugin
|
||||
{
|
||||
private static final int VOID_KNIGHTS_OUTPOST = 10537;
|
||||
|
||||
private final int NOVICE_GANGPLANK = 14315; // Combat 40+ (3 points)
|
||||
private final int INTERMEDIATE_GANGPLANK = 25631; // Combat 70+ (4 points)
|
||||
private final int VETERAN_GANGPLANK = 25632; // Combat 100+ (5 points)
|
||||
@@ -662,6 +664,10 @@ public class PestControlPlugin extends Plugin
|
||||
|
||||
boolean isOnPestControlMainIsland()
|
||||
{
|
||||
return client.getLocalPlayer().getWorldLocation().getRegionID() == 10537;
|
||||
if (client.getLocalPlayer() != null)
|
||||
{
|
||||
return client.getLocalPlayer().getWorldLocation().getRegionID() == VOID_KNIGHTS_OUTPOST;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ import net.runelite.client.config.Stub;
|
||||
public interface PileIndicatorsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "playerPilesStub",
|
||||
name = "Player Piles",
|
||||
description = "",
|
||||
position = 0
|
||||
keyName = "playerPilesStub",
|
||||
name = "Player Piles",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
default Stub playerPilesStub()
|
||||
{
|
||||
@@ -46,11 +46,11 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "enablePlayers",
|
||||
name = "Enable Player Piling",
|
||||
description = "Enable the option to highlight players when they pile.",
|
||||
parent = "playerPilesStub"
|
||||
position = 1,
|
||||
keyName = "enablePlayers",
|
||||
name = "Enable Player Piling",
|
||||
description = "Enable the option to highlight players when they pile.",
|
||||
parent = "playerPilesStub"
|
||||
)
|
||||
default boolean enablePlayers()
|
||||
{
|
||||
@@ -58,11 +58,11 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "wildyOnlyPlayer",
|
||||
name = "Wilderness Only",
|
||||
description = "Show player piling only when in the Wilderness.",
|
||||
parent = "playerPilesStub"
|
||||
position = 2,
|
||||
keyName = "wildyOnlyPlayer",
|
||||
name = "Wilderness Only",
|
||||
description = "Show player piling only when in the Wilderness.",
|
||||
parent = "playerPilesStub"
|
||||
)
|
||||
default boolean wildyOnlyPlayer()
|
||||
{
|
||||
@@ -70,22 +70,22 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "playerPileColor",
|
||||
name = "Player Pile Color",
|
||||
description = "Color used for player piles.",
|
||||
parent = "playerPilesStub"
|
||||
position = 3,
|
||||
keyName = "playerPileColor",
|
||||
name = "Player Pile Color",
|
||||
description = "Color used for player piles.",
|
||||
parent = "playerPilesStub"
|
||||
)
|
||||
default Color playerPileColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "npcPilesStub",
|
||||
name = "NPC Piles",
|
||||
description = "",
|
||||
position = 4
|
||||
keyName = "npcPilesStub",
|
||||
name = "NPC Piles",
|
||||
description = "",
|
||||
position = 4
|
||||
)
|
||||
default Stub npcPilesStub()
|
||||
{
|
||||
@@ -93,11 +93,11 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "enableNPCS",
|
||||
name = "Enable NPC Piling",
|
||||
description = "Enable the option to highlight NPCs when they pile.",
|
||||
parent = "npcPilesStub"
|
||||
position = 5,
|
||||
keyName = "enableNPCS",
|
||||
name = "Enable NPC Piling",
|
||||
description = "Enable the option to highlight NPCs when they pile.",
|
||||
parent = "npcPilesStub"
|
||||
)
|
||||
default boolean enableNPCS()
|
||||
{
|
||||
@@ -105,11 +105,11 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "npcPileColor",
|
||||
name = "NPC Pile Color",
|
||||
description = "Color used for NPC piles.",
|
||||
parent = "npcPilesStub"
|
||||
position = 6,
|
||||
keyName = "npcPileColor",
|
||||
name = "NPC Pile Color",
|
||||
description = "Color used for NPC piles.",
|
||||
parent = "npcPilesStub"
|
||||
)
|
||||
default Color npcPileColor()
|
||||
{
|
||||
@@ -117,10 +117,10 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "mixedPilesStub",
|
||||
name = "Mixed Piles",
|
||||
description = "",
|
||||
position = 7
|
||||
keyName = "mixedPilesStub",
|
||||
name = "Mixed Piles",
|
||||
description = "",
|
||||
position = 7
|
||||
)
|
||||
default Stub mixedPilesStub()
|
||||
{
|
||||
@@ -128,11 +128,11 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "mixedPileColor",
|
||||
name = "Mixed Pile Color",
|
||||
description = "Color used for mixed piles.",
|
||||
parent = "mixedPilesStub"
|
||||
position = 8,
|
||||
keyName = "mixedPileColor",
|
||||
name = "Mixed Pile Color",
|
||||
description = "Color used for mixed piles.",
|
||||
parent = "mixedPilesStub"
|
||||
)
|
||||
default Color mixedPileColor()
|
||||
{
|
||||
@@ -140,10 +140,10 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "pilesSizeStub",
|
||||
name = "Pile size",
|
||||
description = "",
|
||||
position = 9
|
||||
keyName = "pilesSizeStub",
|
||||
name = "Pile size",
|
||||
description = "",
|
||||
position = 9
|
||||
)
|
||||
default Stub pilesSizeStub()
|
||||
{
|
||||
@@ -151,14 +151,14 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 2
|
||||
min = 2
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "minimumPileSize",
|
||||
name = "Minimum Pile Size",
|
||||
description = "Any pile under this size will not show up. (Minimum: 2)",
|
||||
parent = "pilesSizeStub"
|
||||
position = 10,
|
||||
keyName = "minimumPileSize",
|
||||
name = "Minimum Pile Size",
|
||||
description = "Any pile under this size will not show up. (Minimum: 2)",
|
||||
parent = "pilesSizeStub"
|
||||
)
|
||||
default int minimumPileSize()
|
||||
{
|
||||
@@ -166,10 +166,10 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "miscellaneousStub",
|
||||
name = "Miscellaneous",
|
||||
description = "",
|
||||
position = 11
|
||||
keyName = "miscellaneousStub",
|
||||
name = "Miscellaneous",
|
||||
description = "",
|
||||
position = 11
|
||||
)
|
||||
default Stub miscellaneousStub()
|
||||
{
|
||||
@@ -177,14 +177,39 @@ public interface PileIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "numberOnly",
|
||||
name = "Display Number Only",
|
||||
description = "Shorten \"PILE SIZE: 1\" to \"1\"",
|
||||
parent = "miscellaneousStub"
|
||||
position = 12,
|
||||
keyName = "numberOnly",
|
||||
name = "Display Number Only",
|
||||
description = "Shorten \"PILE SIZE: 1\" to \"1\"",
|
||||
parent = "miscellaneousStub"
|
||||
)
|
||||
default boolean numberOnly()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "drawPileTile",
|
||||
name = "Draw Pile Tile",
|
||||
description = "Draws the tile of the pile for best visibility.",
|
||||
parent = "miscellaneousStub"
|
||||
)
|
||||
default boolean drawPileTile()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "drawPileHull",
|
||||
name = "Draw Pile Convex Hull",
|
||||
description = "Draws the hull of the pile for best visibility.",
|
||||
parent = "miscellaneousStub"
|
||||
)
|
||||
default boolean drawPileHull()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,11 +26,15 @@ package net.runelite.client.plugins.pileindicators;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class PileIndicatorsOverlay extends Overlay
|
||||
{
|
||||
@@ -65,22 +69,21 @@ public class PileIndicatorsOverlay extends Overlay
|
||||
PileType pileType = plugin.getPileType(actorArrayList);
|
||||
Color pileColor = plugin.getColorByPileType(pileType);
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
Actor actorToRender = actorArrayList.get(0); //guaranteed to have at least two players
|
||||
final String text;
|
||||
if (config.numberOnly())
|
||||
final String pileTypeStr = pileType == PileType.PLAYER_PILE ? "PLAYER" : pileType == PileType.NPC_PILE ? "NPC" : pileType == PileType.MIXED_PILE ? "MIXED" : "";
|
||||
final String text = config.numberOnly() ? "" + actorArrayList.size() : (pileTypeStr + " PILE SIZE: " + actorArrayList.size());
|
||||
if (config.drawPileTile())
|
||||
{
|
||||
text = "" + actorArrayList.size();
|
||||
OverlayUtil.renderPolygon(graphics, actorToRender.getCanvasTilePoly(), pileColor);
|
||||
}
|
||||
else
|
||||
if (config.drawPileHull())
|
||||
{
|
||||
text = "PILE SIZE: " + actorArrayList.size();
|
||||
OverlayUtil.renderPolygon(graphics, actorToRender.getConvexHull(), pileColor);
|
||||
}
|
||||
|
||||
OverlayUtil.renderPolygon(graphics, actorToRender.getCanvasTilePoly(), pileColor);
|
||||
OverlayUtil.renderTextLocation(graphics, actorToRender.getCanvasTextLocation(graphics, text, 40), text, pileColor);
|
||||
}
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
}
|
||||
@@ -89,4 +92,5 @@ public class PileIndicatorsOverlay extends Overlay
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,11 @@ package net.runelite.client.plugins.pileindicators;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
@@ -40,11 +44,11 @@ import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Pile Indicators",
|
||||
description = "Highlight and count how many npcs/players are stacked on each other.",
|
||||
tags = {"overlay", "pile", "stack", "pvp", "pvm", "pve"},
|
||||
type = PluginType.UTILITY,
|
||||
enabledByDefault = false
|
||||
name = "Pile Indicators",
|
||||
description = "Highlight and count how many npcs/players are stacked on each other.",
|
||||
tags = {"overlay", "pile", "stack", "pvp", "pvm", "pve"},
|
||||
type = PluginType.UTILITY,
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Singleton
|
||||
|
||||
@@ -29,7 +29,6 @@ import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
|
||||
@ConfigGroup("playerindicators")
|
||||
public interface PlayerIndicatorsConfig extends Config
|
||||
@@ -365,46 +364,6 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 27,
|
||||
keyName = "highlightPile",
|
||||
name = "Highlight Pile",
|
||||
description = "Highlights Pile Onscreen",
|
||||
group = "Callers"
|
||||
)
|
||||
default boolean highlightPile()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 29,
|
||||
keyName = "drawPileHull",
|
||||
name = "Draws the hull of the pile.",
|
||||
description = "Draws the hull of the pile for best visibility.",
|
||||
group = "Callers"
|
||||
)
|
||||
default boolean drawPileHull()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 1,
|
||||
max = 10
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 30,
|
||||
keyName = "pileColor",
|
||||
name = "Pile Color",
|
||||
description = "Color of Indicated Pile",
|
||||
group = "Callers"
|
||||
)
|
||||
default Color pileColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 27,
|
||||
keyName = "unchargedGlory",
|
||||
|
||||
@@ -172,10 +172,6 @@ public class PlayerIndicatorsOverlay extends Overlay
|
||||
{
|
||||
name = "[C] " + name;
|
||||
}
|
||||
if (config.highlightPile() && playerIndicatorsPlugin.isPile(actor))
|
||||
{
|
||||
name = "[P] " + name;
|
||||
}
|
||||
if (config.showCombatLevel())
|
||||
{
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.ClanMember;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
import static net.runelite.api.ClanMemberRank.UNRANKED;
|
||||
@@ -54,7 +52,6 @@ import net.runelite.api.Player;
|
||||
import net.runelite.api.events.ClanMemberJoined;
|
||||
import net.runelite.api.events.ClanMemberLeft;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
@@ -128,35 +125,6 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick gameTick)
|
||||
{
|
||||
if (config.highlightPile() && callers != null)
|
||||
{
|
||||
for (Player p : client.getPlayers())
|
||||
{
|
||||
for (String name : callers)
|
||||
{
|
||||
Actor pile;
|
||||
String finalName = name.toLowerCase().replace("_", " ");
|
||||
if (p.getName().toLowerCase().replace("_", " ").equals(finalName))
|
||||
{
|
||||
pile = p.getInteracting();
|
||||
if (pile != null)
|
||||
{
|
||||
pileList.set(callers.indexOf(name), pile.getName());
|
||||
//pileList.add(pile.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
pileList.set(callers.indexOf(name), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onClanMemberJoined(ClanMemberJoined event)
|
||||
{
|
||||
@@ -213,14 +181,6 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isPile(Player player)
|
||||
{
|
||||
if (Objects.nonNull(pileList) && pileList.size() > 0)
|
||||
{
|
||||
return pileList.contains(player.getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
|
||||
@@ -328,10 +288,6 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
{
|
||||
color = config.callerColor();
|
||||
}
|
||||
if (config.colorPlayerMenu() && config.highlightPile() && this.isPile(player))
|
||||
{
|
||||
color = config.pileColor();
|
||||
}
|
||||
if (image != -1 || color != null)
|
||||
{
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
@@ -50,8 +50,7 @@ public class PlayerIndicatorsService
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
|
||||
{
|
||||
if (!config.highlightOwnPlayer() && !config.drawClanMemberNames()
|
||||
&& !config.highlightFriends() && !config.highlightNonClanMembers() && !config.highlightTargets()
|
||||
&& !config.highlightPile() && !config.highlightCallers() && !config.highlightTeamMembers())
|
||||
&& !config.highlightFriends() && !config.highlightNonClanMembers() && !config.highlightTargets() && !config.highlightCallers() && !config.highlightTeamMembers())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -107,11 +106,6 @@ public class PlayerIndicatorsService
|
||||
{
|
||||
consumer.accept(player, config.callerColor());
|
||||
}
|
||||
if (config.highlightPile() && playerIndicatorsPlugin.isPile(player)
|
||||
&& !player.isClanMember())
|
||||
{
|
||||
consumer.accept(player, config.pileColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
|
||||
package net.runelite.client.plugins.playerindicators;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
@@ -58,18 +56,6 @@ public class PlayerIndicatorsTileOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.drawPileHull())
|
||||
{
|
||||
playerIndicatorsService.forEachPlayer((player, color) ->
|
||||
{
|
||||
if (playerIndicatorsPlugin.isPile(player))
|
||||
{
|
||||
Polygon objectClickbox = player.getConvexHull();
|
||||
|
||||
renderPoly(graphics, config.pileColor(), objectClickbox);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!config.drawTiles() /*&& !config.drawPlayerHull()*/)
|
||||
{
|
||||
return null;
|
||||
@@ -89,15 +75,4 @@ public class PlayerIndicatorsTileOverlay extends Overlay
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPoly(Graphics2D graphics, Color color, Polygon polygon)
|
||||
{
|
||||
if (polygon != null)
|
||||
{
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(polygon);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20));
|
||||
graphics.fill(polygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class PuzzleSolverPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked menuOptionClicked)
|
||||
{
|
||||
int widgetId = menuOptionClicked.getWidgetId();
|
||||
int widgetId = menuOptionClicked.getActionParam1();
|
||||
if (TO_GROUP(widgetId) != WidgetID.LIGHT_BOX_GROUP_ID)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -16,6 +16,9 @@ import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.Arrays;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -23,18 +26,23 @@ import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableElement;
|
||||
import net.runelite.client.ui.overlay.components.table.TableRow;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
public class PlayerCountOverlay extends Overlay
|
||||
{
|
||||
private static int[] CLAN_WARS_REGIONS = {9520, 13135, 13134, 13133, 13131, 13130, 13387, 13386};
|
||||
|
||||
private final PvpToolsPlugin pvpToolsPlugin;
|
||||
private final PvpToolsConfig config;
|
||||
private final Client client;
|
||||
|
||||
|
||||
@Inject
|
||||
public PlayerCountOverlay(PvpToolsPlugin pvpToolsPlugin, PvpToolsConfig pvpToolsConfig)
|
||||
public PlayerCountOverlay(PvpToolsPlugin pvpToolsPlugin, PvpToolsConfig pvpToolsConfig, Client client)
|
||||
{
|
||||
this.pvpToolsPlugin = pvpToolsPlugin;
|
||||
this.config = pvpToolsConfig;
|
||||
this.client = client;
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
@@ -46,17 +54,23 @@ public class PlayerCountOverlay extends Overlay
|
||||
{
|
||||
if (config.countPlayers())
|
||||
{
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
TableElement[] firstRowElements = {
|
||||
if ((client.getVar(Varbits.IN_WILDERNESS) == 1) || WorldType.isPvpWorld(client.getWorldType())
|
||||
|| ArrayUtils.contains(CLAN_WARS_REGIONS, client.getMapRegions()[0]) ||
|
||||
WorldType.isDeadmanWorld(client.getWorldType()))
|
||||
{
|
||||
// Make this stop showing up when its not relevant
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
TableElement[] firstRowElements = {
|
||||
TableElement.builder().content("Friendly").color(Color.GREEN).build(),
|
||||
TableElement.builder().content(String.valueOf(pvpToolsPlugin.getFriendlyPlayerCount())).build()};
|
||||
TableRow firstRow = TableRow.builder().elements(Arrays.asList(firstRowElements)).build();
|
||||
TableElement[] secondRowElements = {
|
||||
TableElement.builder().content("Enemy").color(Color.RED).build(),
|
||||
TableElement.builder().content(String.valueOf(pvpToolsPlugin.getEnemyPlayerCount())).build()};
|
||||
TableRow secondRow = TableRow.builder().elements(Arrays.asList(secondRowElements)).build();
|
||||
tableComponent.addRows(firstRow, secondRow);
|
||||
return tableComponent.render(graphics);
|
||||
TableElement.builder().content(String.valueOf(pvpToolsPlugin.getFriendlyPlayerCount())).build()};
|
||||
TableRow firstRow = TableRow.builder().elements(Arrays.asList(firstRowElements)).build();
|
||||
TableElement[] secondRowElements = {
|
||||
TableElement.builder().content("Enemy").color(Color.RED).build(),
|
||||
TableElement.builder().content(String.valueOf(pvpToolsPlugin.getEnemyPlayerCount())).build()};
|
||||
TableRow secondRow = TableRow.builder().elements(Arrays.asList(secondRowElements)).build();
|
||||
tableComponent.addRows(firstRow, secondRow);
|
||||
return tableComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -178,10 +178,10 @@ public class PvpToolsPlugin extends Plugin
|
||||
};
|
||||
|
||||
private final HotkeyListener renderselfHotkeyListener = new HotkeyListener(() -> config.renderSelf())
|
||||
{ //TODO FIX
|
||||
{
|
||||
public void hotkeyPressed()
|
||||
{
|
||||
//client.toggleRenderSelf();
|
||||
client.setRenderSelf(!client.getRenderSelf());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -59,6 +59,18 @@ public interface RaidsConfig extends Config
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
parent = "scouterConfig",
|
||||
keyName = "hideBackground",
|
||||
name = "Hide Scouter Background",
|
||||
description = "Removes the scouter background, and makes it transparent."
|
||||
)
|
||||
default boolean hideBackground()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
parent = "scouterConfig",
|
||||
|
||||
@@ -52,6 +52,7 @@ import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
@@ -154,6 +155,15 @@ public class RaidsOverlay extends Overlay
|
||||
scouterActive = false;
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (config.hideBackground())
|
||||
{
|
||||
panelComponent.setBackgroundColor(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
panelComponent.setBackgroundColor(ComponentConstants.STANDARD_BACKGROUND_COLOR);
|
||||
}
|
||||
|
||||
if (plugin.getRaid() == null || plugin.getRaid().getLayout() == null)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
@@ -279,14 +289,13 @@ public class RaidsOverlay extends Overlay
|
||||
scavsBeforeIceRooms.add(prev);
|
||||
}
|
||||
int lastScavs = scavRooms.get(scavRooms.size() - 1);
|
||||
if (!recordRaid())
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(displayLayout)
|
||||
.color(color)
|
||||
.build());
|
||||
}
|
||||
else
|
||||
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(displayLayout)
|
||||
.color(color)
|
||||
.build());
|
||||
|
||||
if (recordRaid())
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Record Raid")
|
||||
@@ -294,6 +303,17 @@ public class RaidsOverlay extends Overlay
|
||||
.build());
|
||||
panelComponent.setBackgroundColor(new Color(0, 255, 0, 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config.hideBackground())
|
||||
{
|
||||
panelComponent.setBackgroundColor(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
panelComponent.setBackgroundColor(ComponentConstants.STANDARD_BACKGROUND_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
@@ -304,7 +324,7 @@ public class RaidsOverlay extends Overlay
|
||||
String clanOwner = Text.removeTags(client.getWidget(WidgetInfo.CLAN_CHAT_OWNER).getText());
|
||||
if (clanOwner.equals("None"))
|
||||
{
|
||||
clanOwner = "Open CC tab...";
|
||||
clanOwner = "Open CC Tab";
|
||||
color = Color.RED;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ package net.runelite.client.plugins.raids;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
@@ -78,22 +77,9 @@ class RaidsPanel extends PluginPanel
|
||||
JPanel scoutFrame = new JPanel();
|
||||
reloadButton.addActionListener((ActionEvent e) ->
|
||||
{
|
||||
|
||||
|
||||
if ((client.getGameState() == GameState.LOGGED_IN))
|
||||
{
|
||||
try
|
||||
{
|
||||
//look for client.gameStateChanged(-1); in src files to find
|
||||
Method m = client.getClass().getClassLoader().loadClass("ba").getDeclaredMethod("ec", int.class, byte.class);
|
||||
m.setAccessible(true);
|
||||
m.invoke(null, 40, (byte) 3);
|
||||
|
||||
}
|
||||
catch (ReflectiveOperationException f)
|
||||
{
|
||||
throw new RuntimeException(f);
|
||||
}
|
||||
client.setGameState(40);
|
||||
}
|
||||
});
|
||||
reloadScouter.addActionListener((ActionEvent e) ->
|
||||
|
||||
@@ -28,16 +28,29 @@ import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Stub;
|
||||
|
||||
@ConfigGroup("runedoku")
|
||||
public interface RunedokuConfig extends Config
|
||||
{
|
||||
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "mindRuneColor",
|
||||
name = "Mind Rune Color",
|
||||
description = "Color used to highlight Mind runes."
|
||||
position = 0,
|
||||
keyName = "colorStub",
|
||||
name = "Colors",
|
||||
description = "" //stubs don't show descriptions when hovered over
|
||||
)
|
||||
default Stub colorStub()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "mindRuneColor",
|
||||
name = "Mind Rune Color",
|
||||
description = "Color used to highlight Mind runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color mindRuneColor()
|
||||
{
|
||||
@@ -45,10 +58,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "fireRuneColor",
|
||||
name = "Fire Rune Color",
|
||||
description = "Color used to highlight Fire runes."
|
||||
position = 2,
|
||||
keyName = "fireRuneColor",
|
||||
name = "Fire Rune Color",
|
||||
description = "Color used to highlight Fire runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color fireRuneColor()
|
||||
{
|
||||
@@ -56,10 +70,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "bodyRuneColor",
|
||||
name = "Body Rune Color",
|
||||
description = "Color used to highlight Body runes."
|
||||
position = 3,
|
||||
keyName = "bodyRuneColor",
|
||||
name = "Body Rune Color",
|
||||
description = "Color used to highlight Body runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color bodyRuneColor()
|
||||
{
|
||||
@@ -67,10 +82,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "airRuneColor",
|
||||
name = "Air Rune Color",
|
||||
description = "Color used to highlight Air runes."
|
||||
position = 4,
|
||||
keyName = "airRuneColor",
|
||||
name = "Air Rune Color",
|
||||
description = "Color used to highlight Air runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color airRuneColor()
|
||||
{
|
||||
@@ -78,10 +94,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "deathRuneColor",
|
||||
name = "Death Rune Color",
|
||||
description = "Color used to highlight Death runes."
|
||||
position = 5,
|
||||
keyName = "deathRuneColor",
|
||||
name = "Death Rune Color",
|
||||
description = "Color used to highlight Death runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color deathRuneColor()
|
||||
{
|
||||
@@ -89,10 +106,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "waterRuneColor",
|
||||
name = "Water Rune Color",
|
||||
description = "Color used to highlight Water runes."
|
||||
position = 6,
|
||||
keyName = "waterRuneColor",
|
||||
name = "Water Rune Color",
|
||||
description = "Color used to highlight Water runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color waterRuneColor()
|
||||
{
|
||||
@@ -100,10 +118,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "chaosRuneColor",
|
||||
name = "Chaos Rune Color",
|
||||
description = "Color used to highlight Chaos runes."
|
||||
position = 7,
|
||||
keyName = "chaosRuneColor",
|
||||
name = "Chaos Rune Color",
|
||||
description = "Color used to highlight Chaos runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color chaosRuneColor()
|
||||
{
|
||||
@@ -111,10 +130,11 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "earthRuneColor",
|
||||
name = "Earth Rune Color",
|
||||
description = "Color used to highlight Earth runes."
|
||||
position = 8,
|
||||
keyName = "earthRuneColor",
|
||||
name = "Earth Rune Color",
|
||||
description = "Color used to highlight Earth runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color earthRuneColor()
|
||||
{
|
||||
@@ -122,14 +142,37 @@ public interface RunedokuConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "lawRuneColor",
|
||||
name = "Law Rune Color",
|
||||
description = "Color used to highlight Law runes."
|
||||
position = 9,
|
||||
keyName = "lawRuneColor",
|
||||
name = "Law Rune Color",
|
||||
description = "Color used to highlight Law runes.",
|
||||
parent = "colorStub"
|
||||
)
|
||||
default Color lawRuneColor()
|
||||
{
|
||||
return Color.CYAN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "miscFeature",
|
||||
name = "Miscellaneous Features",
|
||||
description = ""
|
||||
)
|
||||
default Stub miscFeature()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "onlyHighlightSelectedPiece",
|
||||
name = "Only Highlight Selected Piece",
|
||||
description = "Instead of showing all, this option only show what rune you have selected."
|
||||
)
|
||||
default boolean onlyHighlightSelectedPiece()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,15 +47,17 @@ class RunedokuOverlay extends Overlay
|
||||
private final RunedokuPlugin plugin;
|
||||
private final Client client;
|
||||
private final RunedokuUtil util;
|
||||
private final RunedokuConfig config;
|
||||
|
||||
|
||||
@Inject
|
||||
private RunedokuOverlay(final RunedokuPlugin plugin, final Client client, final RunedokuUtil util)
|
||||
private RunedokuOverlay(final RunedokuPlugin plugin, final Client client, final RunedokuUtil util, final RunedokuConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
this.util = util;
|
||||
this.config = config;
|
||||
|
||||
setPosition(OverlayPosition.DETACHED);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
@@ -138,7 +140,10 @@ class RunedokuOverlay extends Overlay
|
||||
}
|
||||
else
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, RunedokuUtil.rectangleToPolygon(squareToHighlight.getBounds()), util.sudokuPieceToColor(simpleArr.get(iteration)));
|
||||
if (!config.onlyHighlightSelectedPiece() ^ (config.onlyHighlightSelectedPiece() && util.getSelectedPiece(client) == simpleArr.get(iteration)))
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, RunedokuUtil.rectangleToPolygon(squareToHighlight.getBounds()), util.sudokuPieceToColor(simpleArr.get(iteration)));
|
||||
}
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
|
||||
@@ -180,4 +180,41 @@ class RunedokuUtil
|
||||
return myArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client
|
||||
* @return
|
||||
*/
|
||||
int getSelectedPiece(Client client)
|
||||
{
|
||||
for (int i = 91; i < 100; i++)
|
||||
{
|
||||
Widget selectedPieceWidget = client.getWidget(288, i);
|
||||
if (!selectedPieceWidget.isHidden())
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 91:
|
||||
return 8;
|
||||
case 92:
|
||||
return 6;
|
||||
case 93:
|
||||
return 4;
|
||||
case 94:
|
||||
return 2;
|
||||
case 95:
|
||||
return 1;
|
||||
case 96:
|
||||
return 3;
|
||||
case 97:
|
||||
return 5;
|
||||
case 98:
|
||||
return 7;
|
||||
case 99:
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -784,7 +784,7 @@ public class SlayerPlugin extends Plugin
|
||||
private boolean doubleTroubleExtraKill()
|
||||
{
|
||||
return WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()).getRegionID() == GROTESQUE_GUARDIANS_REGION &&
|
||||
SlayerUnlock.GROTESQUE_GARDIAN_DOUBLE_COUNT.isEnabled(client);
|
||||
SlayerUnlock.GROTESQUE_GUARDIAN_DOUBLE_COUNT.isEnabled(client);
|
||||
}
|
||||
|
||||
// checks if any contiguous subsequence of seq0 exactly matches the String toMatch
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user