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

This commit is contained in:
Owain van Brakel
2019-07-16 15:25:41 +02:00
14 changed files with 1185 additions and 306 deletions

View File

@@ -1679,15 +1679,25 @@ public interface Client extends GameShell
boolean isSpellSelected(); boolean isSpellSelected();
/** /**
* Set whether or not player attack options will be hidden for clanmembers/friends * Set whether or not player attack options will be hidden for friends
*/ */
void setHideFriendAttackOptions(boolean yes); void setHideFriendAttackOptions(boolean yes);
/** /**
* Set whether or not player cast options will be hidden for clanmembers/friends * Set whether or not player cast options will be hidden for friends
*/ */
void setHideFriendCastOptions(boolean yes); void setHideFriendCastOptions(boolean yes);
/**
* Set whether or not player attack options will be hidden for clanmates
*/
void setHideClanmateAttackOptions(boolean yes);
/**
* Set whether or not player cast options will be hidden for clanmates
*/
void setHideClanmateCastOptions(boolean yes);
/** /**
* Set spells excluded from above hiding * Set spells excluded from above hiding
*/ */

View File

@@ -24,7 +24,6 @@
*/ */
package net.runelite.client.plugins.demonicgorilla; package net.runelite.client.plugins.demonicgorilla;
import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@@ -43,6 +42,7 @@ import net.runelite.client.game.SkillIconManager;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
@Singleton @Singleton
public class DemonicGorillaOverlay extends Overlay public class DemonicGorillaOverlay extends Overlay
@@ -118,31 +118,11 @@ public class DemonicGorillaOverlay extends Overlay
int currentPosX = 0; int currentPosX = 0;
for (BufferedImage icon : icons) for (BufferedImage icon : icons)
{ {
graphics.setStroke(new BasicStroke(2)); OverlayUtil.setProgressIcon(graphics, point, icon, totalWidth, bgPadding, currentPosX,
graphics.setColor(COLOR_ICON_BACKGROUND); COLOR_ICON_BACKGROUND, OVERLAY_ICON_DISTANCE, COLOR_ICON_BORDER, COLOR_ICON_BORDER_FILL);
graphics.fillOval(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
icon.getWidth() + bgPadding * 2,
icon.getHeight() + bgPadding * 2);
graphics.setColor(COLOR_ICON_BORDER);
graphics.drawOval(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
icon.getWidth() + bgPadding * 2,
icon.getHeight() + bgPadding * 2);
graphics.drawImage(
icon,
point.getX() - totalWidth / 2 + currentPosX,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
null);
graphics.setColor(COLOR_ICON_BORDER_FILL);
Arc2D.Double arc = new Arc2D.Double( Arc2D.Double arc = new Arc2D.Double(
point.getX() - totalWidth / 2 + currentPosX - bgPadding, point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - icon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, point.getY() - (float) (icon.getHeight() / 2) - OVERLAY_ICON_DISTANCE - bgPadding,
icon.getWidth() + bgPadding * 2, icon.getWidth() + bgPadding * 2,
icon.getHeight() + bgPadding * 2, icon.getHeight() + bgPadding * 2,
90.0, 90.0,

View File

@@ -1,7 +1,8 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Kyle <https://github.com/kyleeld> * Copyright (c) 2019, alanbaumgartner <https://github.com/alanbaumgartner>
* Copyright (c) 2018, lucouswin <https://github.com/lucouswin> * Copyright (c) 2019, Kyle <https://github.com/kyleeld>
* Copyright (c) 2019, lucouswin <https://github.com/lucouswin>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -1668,28 +1669,56 @@ default CharterOption charterOption()
//------------------------------------------------------------// //------------------------------------------------------------//
@ConfigItem( @ConfigItem(
keyName = "removeFreezePlayerToB", keyName = "hideCastToB",
name = "Remove freeze in ToB", name = "Hide cast in ToB",
description = "Removes the freeze option for ice barrage, ice blitz, entangle etc. in ToB", description = "Hides the cast option for clanmates and friends in ToB",
position = 0, position = 0,
group = "PVM" group = "PVM"
) )
default boolean getRemoveFreezePlayerToB() default boolean hideCastToB()
{ {
return true; return true;
} }
@ConfigItem( @ConfigItem(
keyName = "removeFreezePlayerCoX", keyName = "hideCastIgnoredToB",
name = "Remove freeze in CoX", name = "Ignored spells",
description = "Removes the freeze option for ice barrage, ice blitz, entangle etc. in CoX", description = "Spells that should not be hidden from being cast, separated by a comma",
position = 1, position = 1,
group = "PVM",
hidden = true,
unhide = "hideCastToB"
)
default String hideCastIgnoredToB()
{
return "cure other, energy transfer, heal other, vengeance other";
}
@ConfigItem(
keyName = "hideCastCoX",
name = "Hide cast in CoX",
description = "Hides the cast option for clanmates and friends in CoX",
position = 2,
group = "PVM" group = "PVM"
) )
default boolean getRemoveFreezePlayerCoX() default boolean hideCastCoX()
{ {
return true; return true;
} }
@ConfigItem(
keyName = "hideCastIgnoredCoX",
name = "Ignored spells",
description = "Spells that should not be hidden from being cast, separated by a comma",
position = 3,
group = "PVM",
hidden = true,
unhide = "hideCastCoX"
)
default String hideCastIgnoredCoX()
{
return "cure other, energy transfer, heal other, vengeance other";
}
} }

View File

@@ -1,8 +1,9 @@
/* /*
* Copyright (c) 2018, Adam <Adam@sigterm.info> * Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Kamiel * Copyright (c) 2018, Kamiel
* Copyright (c) 2018, Kyle <https://github.com/kyleeld> * Copyright (c) 2019, alanbaumgartner <https://github.com/alanbaumgartner>
* Copyright (c) 2018, lucouswin <https://github.com/lucouswin> * Copyright (c) 2019, Kyle <https://github.com/kyleeld>
* Copyright (c) 2019, lucouswin <https://github.com/lucouswin>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -30,6 +31,7 @@ package net.runelite.client.plugins.menuentryswapper;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -57,6 +59,8 @@ import net.runelite.api.NPC;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import static net.runelite.api.Varbits.BUILDING_MODE; import static net.runelite.api.Varbits.BUILDING_MODE;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint; import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
@@ -78,7 +82,9 @@ import net.runelite.client.menus.ComparableEntry;
import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.MenuManager;
import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.menus.WidgetMenuOption;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginManager;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.menuentryswapper.util.BurningAmuletMode; import net.runelite.client.plugins.menuentryswapper.util.BurningAmuletMode;
import net.runelite.client.plugins.menuentryswapper.util.CombatBraceletMode; import net.runelite.client.plugins.menuentryswapper.util.CombatBraceletMode;
@@ -100,6 +106,9 @@ import net.runelite.client.plugins.menuentryswapper.util.SlayerRingMode;
import net.runelite.client.plugins.menuentryswapper.util.XericsTalismanMode; import net.runelite.client.plugins.menuentryswapper.util.XericsTalismanMode;
import net.runelite.client.plugins.menuentryswapper.util.teleEquippedMode; import net.runelite.client.plugins.menuentryswapper.util.teleEquippedMode;
import static net.runelite.client.util.MenuUtil.swap; import static net.runelite.client.util.MenuUtil.swap;
import net.runelite.client.plugins.pvptools.PvpToolsConfig;
import net.runelite.client.plugins.pvptools.PvpToolsPlugin;
import net.runelite.client.util.MiscUtils; import net.runelite.client.util.MiscUtils;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
@@ -112,6 +121,7 @@ import org.apache.commons.lang3.ArrayUtils;
enabledByDefault = false enabledByDefault = false
) )
@Singleton @Singleton
@PluginDependency(PvpToolsPlugin.class)
public class MenuEntrySwapperPlugin extends Plugin public class MenuEntrySwapperPlugin extends Plugin
{ {
private static final String CONFIGURE = "Configure"; private static final String CONFIGURE = "Configure";
@@ -127,6 +137,8 @@ public class MenuEntrySwapperPlugin extends Plugin
private MenuEntry[] entries; private MenuEntry[] entries;
private final Set<String> leftClickConstructionItems = new HashSet<>(); private final Set<String> leftClickConstructionItems = new HashSet<>();
private boolean buildingMode; private boolean buildingMode;
private boolean inTobRaid = false;
private boolean inCoxRaid = false;
private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE, private static final WidgetMenuOption FIXED_INVENTORY_TAB_CONFIGURE = new WidgetMenuOption(CONFIGURE,
MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB); MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB);
@@ -176,6 +188,9 @@ public class MenuEntrySwapperPlugin extends Plugin
@Inject @Inject
private ConfigManager configManager; private ConfigManager configManager;
@Inject
private PluginManager pluginManager;
@Inject @Inject
private KeyManager keyManager; private KeyManager keyManager;
@@ -188,6 +203,12 @@ public class MenuEntrySwapperPlugin extends Plugin
@Inject @Inject
private EventBus eventBus; private EventBus eventBus;
@Inject
private PvpToolsPlugin pvpTools;
@Inject
private PvpToolsConfig pvpToolsConfig;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private boolean configuringShiftClick = false; private boolean configuringShiftClick = false;
@@ -315,8 +336,10 @@ public class MenuEntrySwapperPlugin extends Plugin
private boolean hideDestroyBoltpouch; private boolean hideDestroyBoltpouch;
private boolean hideDestroyGembag; private boolean hideDestroyGembag;
private boolean hideDropRunecraftingPouch; private boolean hideDropRunecraftingPouch;
private boolean getRemoveFreezePlayerToB; private boolean hideCastToB;
private boolean getRemoveFreezePlayerCoX; private Set<String> hideCastIgnoredToB;
private boolean hideCastCoX;
private Set<String> hideCastIgnoredCoX;
@Provides @Provides
MenuEntrySwapperConfig provideConfig(ConfigManager configManager) MenuEntrySwapperConfig provideConfig(ConfigManager configManager)
@@ -332,8 +355,6 @@ public class MenuEntrySwapperPlugin extends Plugin
addSwaps(); addSwaps();
loadConstructionItems(config.getEasyConstructionItems()); loadConstructionItems(config.getEasyConstructionItems());
client.setHideFriendCastOptions(config.getRemoveFreezePlayerToB());
client.setHideFriendCastOptions(config.getRemoveFreezePlayerCoX());
if (config.shiftClickCustomization()) if (config.shiftClickCustomization())
{ {
@@ -341,6 +362,11 @@ public class MenuEntrySwapperPlugin extends Plugin
} }
loadCustomSwaps(config.customSwaps()); loadCustomSwaps(config.customSwaps());
if (client.getGameState() == GameState.LOGGED_IN)
{
setCastOptions(true);
}
} }
@Override @Override
@@ -348,11 +374,15 @@ public class MenuEntrySwapperPlugin extends Plugin
{ {
eventBus.unregister(this); eventBus.unregister(this);
client.setHideFriendCastOptions(false);
disableCustomization(); disableCustomization();
loadConstructionItems(""); loadConstructionItems("");
loadCustomSwaps(""); // Removes all custom swaps loadCustomSwaps(""); // Removes all custom swaps
removeSwaps(); removeSwaps();
if (client.getGameState() == GameState.LOGGED_IN)
{
resetCastOptions();
}
} }
private void addSubscriptions() private void addSubscriptions()
@@ -387,8 +417,6 @@ public class MenuEntrySwapperPlugin extends Plugin
{ {
loadCustomSwaps(this.configCustomSwaps); loadCustomSwaps(this.configCustomSwaps);
} }
return;
} }
if (event.getKey().equals("shiftClickCustomization")) if (event.getKey().equals("shiftClickCustomization"))
@@ -407,19 +435,27 @@ public class MenuEntrySwapperPlugin extends Plugin
clientThread.invoke(this::resetItemDefinitionCache); clientThread.invoke(this::resetItemDefinitionCache);
} }
if (event.getKey().equals("removeFreezePlayerToB")) else if ((event.getKey().equals("hideCastToB") || event.getKey().equals("hideCastIgnoredToB")))
{ {
if (this.getRemoveFreezePlayerToB && client.getVar(Varbits.THEATRE_OF_BLOOD) == 2) if (this.hideCastToB)
{ {
client.setHideFriendCastOptions(config.getRemoveFreezePlayerToB()); setCastOptions(true);
}
else
{
resetCastOptions();
} }
} }
if (event.getKey().equals("removeFreezePlayerCoX")) else if ((event.getKey().equals("hideCastCoX") || event.getKey().equals("hideCastIgnoredCoX")))
{ {
if (this.getRemoveFreezePlayerCoX && client.getVar(Varbits.IN_RAID) == 1) if (this.hideCastCoX)
{ {
client.setHideFriendCastOptions(config.getRemoveFreezePlayerCoX()); setCastOptions(true);
}
else
{
resetCastOptions();
} }
} }
} }
@@ -493,6 +529,8 @@ public class MenuEntrySwapperPlugin extends Plugin
private void onVarbitChanged(VarbitChanged event) private void onVarbitChanged(VarbitChanged event)
{ {
buildingMode = client.getVar(BUILDING_MODE) == 1; buildingMode = client.getVar(BUILDING_MODE) == 1;
setCastOptions(false);
} }
private void onMenuOpened(MenuOpened event) private void onMenuOpened(MenuOpened event)
@@ -1709,6 +1747,59 @@ public class MenuEntrySwapperPlugin extends Plugin
menuManager.removePriorityEntry("climb-down"); menuManager.removePriorityEntry("climb-down");
} }
private void setCastOptions(boolean force)
{
clientThread.invoke(() ->
{
boolean tmpInCoxRaid = client.getVar(Varbits.IN_RAID) == 1;
if (tmpInCoxRaid != inCoxRaid || force)
{
if (tmpInCoxRaid && this.hideCastCoX)
{
client.setHideFriendCastOptions(true);
client.setHideClanmateCastOptions(true);
client.setUnhiddenCasts(this.hideCastIgnoredCoX);
}
inCoxRaid = tmpInCoxRaid;
}
boolean tmpInTobRaid = client.getVar(Varbits.THEATRE_OF_BLOOD) == 2;
if (tmpInTobRaid != inTobRaid || force)
{
if (tmpInTobRaid && this.hideCastToB)
{
client.setHideFriendCastOptions(true);
client.setHideClanmateCastOptions(true);
client.setUnhiddenCasts(this.hideCastIgnoredToB);
}
inTobRaid = tmpInTobRaid;
}
if (!inCoxRaid && !inTobRaid)
{
resetCastOptions();
}
});
}
private void resetCastOptions()
{
clientThread.invoke(() ->
{
if (client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isAllPvpWorld(client.getWorldType()) && pluginManager.isPluginEnabled(pvpTools) && pvpToolsConfig.hideCast())
{
pvpTools.setCastOptions();
}
else
{
client.setHideFriendCastOptions(false);
client.setHideClanmateCastOptions(false);
}
});
}
private void updateConfig() private void updateConfig()
{ {
this.getWithdrawOne = config.getWithdrawOne(); this.getWithdrawOne = config.getWithdrawOne();
@@ -1832,7 +1923,9 @@ public class MenuEntrySwapperPlugin extends Plugin
this.hideDestroyBoltpouch = config.hideDestroyBoltpouch(); this.hideDestroyBoltpouch = config.hideDestroyBoltpouch();
this.hideDestroyGembag = config.hideDestroyGembag(); this.hideDestroyGembag = config.hideDestroyGembag();
this.hideDropRunecraftingPouch = config.hideDropRunecraftingPouch(); this.hideDropRunecraftingPouch = config.hideDropRunecraftingPouch();
this.getRemoveFreezePlayerToB = config.getRemoveFreezePlayerToB(); this.hideCastToB = config.hideCastToB();
this.getRemoveFreezePlayerCoX = config.getRemoveFreezePlayerCoX(); this.hideCastIgnoredToB = Sets.newHashSet(Text.fromCSV(config.hideCastIgnoredToB().toLowerCase()));
this.hideCastCoX = config.hideCastCoX();
this.hideCastIgnoredCoX = Sets.newHashSet(Text.fromCSV(config.hideCastIgnoredCoX().toLowerCase()));
} }
} }

View File

@@ -76,31 +76,68 @@ public interface PvpToolsConfig extends Config
keyName = "hideAttack", keyName = "hideAttack",
name = "Hide attack", name = "Hide attack",
description = "Hides the attack option for clanmates, friends, or both", description = "Hides the attack option for clanmates, friends, or both",
position = 5, position = 5
group = "Right-Click Attack Options"
) )
default boolean hideAttack() default boolean hideAttack()
{ {
return false; return false;
} }
@ConfigItem(
keyName = "hideAttackMode",
name = "Mode",
description = "",
position = 6,
hidden = true,
unhide = "hideAttack"
)
default AttackMode hideAttackMode()
{
return AttackMode.FRIENDS;
}
@ConfigItem( @ConfigItem(
keyName = "hideCast", keyName = "hideCast",
name = "Hide cast", name = "Hide cast",
description = "Hides the cast option for clanmates, friends, or both", description = "Hides the cast option for clanmates, friends, or both",
position = 7, position = 7
group = "Right-Click Attack Options"
) )
default boolean hideCast() default boolean hideCast()
{ {
return false; return false;
} }
@ConfigItem(
keyName = "hideCastMode",
name = "Mode",
description = "",
position = 8,
hidden = true,
unhide = "hideCast"
)
default AttackMode hideCastMode()
{
return AttackMode.FRIENDS;
}
@ConfigItem(
keyName = "hideCastIgnored",
name = "Ignored spells",
description = "Spells that should not be hidden from being cast, separated by a comma",
position = 9,
hidden = true,
unhide = "hideCast"
)
default String hideCastIgnored()
{
return "cure other, energy transfer, heal other, vengeance other";
}
@ConfigItem( @ConfigItem(
keyName = "riskCalculator", keyName = "riskCalculator",
name = "Risk Calculator", name = "Risk Calculator",
description = "Enables a panel in the PvP Tools Panel that shows the players current risk", description = "Enables a panel in the PvP Tools Panel that shows the players current risk",
position = 13 position = 10
) )
default boolean riskCalculatorEnabled() default boolean riskCalculatorEnabled()
{ {
@@ -111,7 +148,7 @@ public interface PvpToolsConfig extends Config
keyName = "missingPlayers", keyName = "missingPlayers",
name = "Missing CC Players", name = "Missing CC Players",
description = "Adds a button to the PvP Tools panel that opens a window showing which CC members are not at the current players location", description = "Adds a button to the PvP Tools panel that opens a window showing which CC members are not at the current players location",
position = 14 position = 11
) )
default boolean missingPlayersEnabled() default boolean missingPlayersEnabled()
{ {
@@ -122,7 +159,7 @@ public interface PvpToolsConfig extends Config
keyName = "currentPlayers", keyName = "currentPlayers",
name = "Current CC Players", name = "Current CC Players",
description = "Adds a button to the PvP Tools panel that opens a window showing which CC members currently at the players location", description = "Adds a button to the PvP Tools panel that opens a window showing which CC members currently at the players location",
position = 15 position = 12
) )
default boolean currentPlayersEnabled() default boolean currentPlayersEnabled()
{ {

View File

@@ -11,6 +11,7 @@
package net.runelite.client.plugins.pvptools; package net.runelite.client.plugins.pvptools;
import com.google.common.collect.Sets;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@@ -20,6 +21,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -36,11 +38,14 @@ import net.runelite.api.Item;
import net.runelite.api.ItemDefinition; import net.runelite.api.ItemDefinition;
import net.runelite.api.Player; import net.runelite.api.Player;
import net.runelite.api.SkullIcon; import net.runelite.api.SkullIcon;
import net.runelite.api.Varbits;
import net.runelite.api.WorldType;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.PlayerDespawned; import net.runelite.api.events.PlayerDespawned;
import net.runelite.api.events.PlayerSpawned; import net.runelite.api.events.PlayerSpawned;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.Keybind; import net.runelite.client.config.Keybind;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
@@ -87,6 +92,7 @@ public class PvpToolsPlugin extends Plugin
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private boolean hideAll; private boolean hideAll;
private boolean loaded;
@Inject @Inject
private OverlayManager overlayManager; private OverlayManager overlayManager;
@@ -94,6 +100,9 @@ public class PvpToolsPlugin extends Plugin
@Inject @Inject
private Client client; private Client client;
@Inject
private ClientThread clientThread;
@Inject @Inject
private ItemManager itemManager; private ItemManager itemManager;
@@ -152,7 +161,10 @@ public class PvpToolsPlugin extends Plugin
private boolean missingPlayersEnabled; private boolean missingPlayersEnabled;
private boolean currentPlayersEnabled; private boolean currentPlayersEnabled;
private boolean hideAttack; private boolean hideAttack;
private AttackMode hideAttackMode;
private boolean hideCast; private boolean hideCast;
private AttackMode hideCastMode;
private Set<String> unhiddenCasts;
@Inject @Inject
private ClientToolbar clientToolbar; private ClientToolbar clientToolbar;
@@ -242,8 +254,6 @@ public class PvpToolsPlugin extends Plugin
overlayManager.add(pvpToolsOverlay); overlayManager.add(pvpToolsOverlay);
overlayManager.add(playerCountOverlay); overlayManager.add(playerCountOverlay);
client.setHideFriendAttackOptions(this.hideAttack);
client.setHideFriendCastOptions(this.hideCast);
keyManager.registerKeyListener(fallinHotkeyListener); keyManager.registerKeyListener(fallinHotkeyListener);
keyManager.registerKeyListener(renderselfHotkeyListener); keyManager.registerKeyListener(renderselfHotkeyListener);
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "skull.png"); final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "skull.png");
@@ -262,7 +272,6 @@ public class PvpToolsPlugin extends Plugin
panel.currentPlayers.addActionListener(currentPlayersActionListener); panel.currentPlayers.addActionListener(currentPlayersActionListener);
clientToolbar.addNavigation(navButton); clientToolbar.addNavigation(navButton);
if (this.missingPlayersEnabled) if (this.missingPlayersEnabled)
{ {
panel.missingPlayers.setVisible(true); panel.missingPlayers.setVisible(true);
@@ -273,6 +282,10 @@ public class PvpToolsPlugin extends Plugin
panel.currentPlayers.setVisible(true); panel.currentPlayers.setVisible(true);
} }
if (client.getGameState() == GameState.LOGGED_IN)
{
setCastOptions();
}
} }
@Override @Override
@@ -285,8 +298,13 @@ public class PvpToolsPlugin extends Plugin
keyManager.unregisterKeyListener(fallinHotkeyListener); keyManager.unregisterKeyListener(fallinHotkeyListener);
keyManager.unregisterKeyListener(renderselfHotkeyListener); keyManager.unregisterKeyListener(renderselfHotkeyListener);
clientToolbar.removeNavigation(navButton); clientToolbar.removeNavigation(navButton);
client.setHideFriendAttackOptions(false);
client.setHideFriendCastOptions(false); if (client.getGameState() == GameState.LOGGED_IN)
{
resetCastOptions();
}
loaded = false;
} }
private void addSubscriptions() private void addSubscriptions()
@@ -304,60 +322,72 @@ public class PvpToolsPlugin extends Plugin
{ {
return; return;
} }
client.setHideFriendAttackOptions(this.hideAttack);
client.setHideFriendCastOptions(this.hideCast);
if (configChanged.getGroup().equals("pvptools")) updateConfig();
switch (configChanged.getKey())
{ {
updateConfig(); case "countPlayers":
if (this.countPlayers)
switch (configChanged.getKey()) {
{ updatePlayers();
case "countPlayers": }
if (this.countPlayers) if (!this.countPlayers)
{ {
updatePlayers(); panel.disablePlayerCount();
} }
if (!this.countPlayers) break;
{ case "countOverHeads":
panel.disablePlayerCount(); if (this.countOverHeads)
} {
break; countOverHeads();
case "countOverHeads": }
if (this.countOverHeads) if (!this.countOverHeads)
{ {
countOverHeads(); panel.disablePrayerCount();
} }
if (!this.countOverHeads) break;
{ case "riskCalculator":
panel.disablePrayerCount(); if (this.riskCalculatorEnabled)
} {
break; getCarriedWealth();
case "riskCalculator": }
if (this.riskCalculatorEnabled) if (!this.riskCalculatorEnabled)
{ {
getCarriedWealth(); panel.disableRiskCalculator();
} }
if (!this.riskCalculatorEnabled) break;
{ case "missingPlayers":
panel.disableRiskCalculator(); if (this.missingPlayersEnabled)
} {
break; panel.missingPlayers.setVisible(true);
case "missingPlayers": }
if (this.missingPlayersEnabled) break;
{ case "currentPlayers":
panel.missingPlayers.setVisible(true); if (this.currentPlayersEnabled)
} {
break; panel.currentPlayers.setVisible(true);
case "currentPlayers": }
if (this.currentPlayersEnabled) break;
{ case "hideAttack":
panel.currentPlayers.setVisible(true); case "hideAttackMode":
} if (this.hideAttack)
break; {
default: hideAttackOptions(this.hideAttackMode);
break; }
} else
{
client.setHideFriendAttackOptions(false);
client.setHideClanmateAttackOptions(false);
}
break;
case "hideCast":
case "hideCastMode":
case "hideCastIgnored":
setCastOptions();
break;
default:
break;
} }
} }
@@ -372,13 +402,20 @@ public class PvpToolsPlugin extends Plugin
private void onGameStateChanged(GameStateChanged event) private void onGameStateChanged(GameStateChanged event)
{ {
if (event.getGameState().equals(GameState.LOGGED_IN) && this.riskCalculatorEnabled) if (event.getGameState().equals(GameState.LOGGED_IN))
{ {
getCarriedWealth(); if (this.riskCalculatorEnabled)
} {
if (event.getGameState().equals(GameState.LOGGED_IN) && this.countPlayers) getCarriedWealth();
{ }
updatePlayers(); if (this.countPlayers)
{
updatePlayers();
}
if (!loaded)
{
setCastOptions();
}
} }
} }
@@ -587,6 +624,101 @@ public class PvpToolsPlugin extends Plugin
panel.biggestItemLabel.repaint(); panel.biggestItemLabel.repaint();
} }
/**
* Given an AttackMode, hides the appropriate attack options.
* @param mode The {@link AttackMode} specifying clanmates, friends, or both.
*/
public void hideAttackOptions(AttackMode mode)
{
switch (mode)
{
case CLAN:
client.setHideClanmateAttackOptions(true);
client.setHideFriendAttackOptions(false);
break;
case FRIENDS:
client.setHideFriendAttackOptions(true);
client.setHideClanmateAttackOptions(false);
break;
case BOTH:
client.setHideClanmateAttackOptions(true);
client.setHideFriendAttackOptions(true);
break;
}
}
/**
* Given an AttackMode, hides the appropriate cast options.
* @param mode The {@link AttackMode} specifying clanmates, friends, or both.
*/
public void hideCastOptions(AttackMode mode)
{
switch (mode)
{
case CLAN:
client.setHideClanmateCastOptions(true);
client.setHideFriendCastOptions(false);
break;
case FRIENDS:
client.setHideFriendCastOptions(true);
client.setHideClanmateCastOptions(false);
break;
case BOTH:
client.setHideClanmateCastOptions(true);
client.setHideFriendCastOptions(true);
break;
}
}
public void setCastOptions()
{
clientThread.invoke(() ->
{
if ((client.getVar(Varbits.IN_RAID) == 1 || client.getVar(Varbits.THEATRE_OF_BLOOD) == 2)
|| (client.getVar(Varbits.IN_WILDERNESS) != 1 && !WorldType.isAllPvpWorld(client.getWorldType())))
{
return;
}
if (this.hideAttack)
{
hideAttackOptions(this.hideAttackMode);
}
else
{
client.setHideFriendAttackOptions(false);
client.setHideClanmateAttackOptions(false);
}
if (this.hideCast)
{
hideCastOptions(this.hideCastMode);
}
else
{
client.setHideFriendCastOptions(false);
client.setHideClanmateCastOptions(false);
}
client.setUnhiddenCasts(this.unhiddenCasts);
loaded = true;
});
}
private void resetCastOptions()
{
clientThread.invoke(() ->
{
if (client.getVar(Varbits.IN_RAID) == 1 || client.getVar(Varbits.THEATRE_OF_BLOOD) == 2)
{
return;
}
client.setHideFriendAttackOptions(false);
client.setHideFriendCastOptions(false);
});
}
private void updateConfig() private void updateConfig()
{ {
@@ -599,6 +731,9 @@ public class PvpToolsPlugin extends Plugin
this.missingPlayersEnabled = config.missingPlayersEnabled(); this.missingPlayersEnabled = config.missingPlayersEnabled();
this.currentPlayersEnabled = config.currentPlayersEnabled(); this.currentPlayersEnabled = config.currentPlayersEnabled();
this.hideAttack = config.hideAttack(); this.hideAttack = config.hideAttack();
this.hideAttackMode = config.hideAttackMode();
this.hideCast = config.hideCast(); this.hideCast = config.hideCast();
this.hideCastMode = config.hideCastMode();
this.unhiddenCasts = Sets.newHashSet(Text.fromCSV(config.hideCastIgnored().toLowerCase()));
} }
} }

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2018, https://runelitepl.us
* Copyright (c) 2019, Infinitay <https://github.com/Infinitay>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.vorkath;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
public class AcidPathOverlay extends Overlay
{
private static final Color ACID_SPOTS_COLOR = Color.GREEN;
private static final Color ACID_FREE_PATH_COLOR = Color.PINK;
private static final Color WOOXWALK_ATTACK_SPOT_COLOR = Color.YELLOW;
private static final Color WOOXWALK_OUT_OF_REACH_SPOT_COLOR = Color.RED;
private static final int BAR_INDICATOR_SPACER = 5;
private final Client client;
private final VorkathPlugin plugin;
@Inject
public AcidPathOverlay(final Client client, final VorkathPlugin plugin)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE);
this.client = client;
this.plugin = plugin;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (plugin.getVorkath() == null || plugin.getVorkath().getVorkath().getLocalLocation() == null)
{
return null;
}
if (plugin.isIndicateAcidPools() && plugin.getAcidSpots() != null
&& !plugin.getAcidSpots().isEmpty())
{
for (WorldPoint acidWorldPoint : plugin.getAcidSpots())
{
LocalPoint acidLocalPoint = LocalPoint.fromWorld(client, acidWorldPoint);
if (acidLocalPoint == null)
{
continue;
}
OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client,
acidLocalPoint), ACID_SPOTS_COLOR);
}
}
if (plugin.isIndicateAcidFreePath() && plugin.getAcidFreePath() != null
&& !plugin.getAcidFreePath().isEmpty())
{
for (WorldPoint acidFreeWorldPoint : plugin.getAcidFreePath())
{
LocalPoint acidFreeLocalPoint = LocalPoint.fromWorld(client, acidFreeWorldPoint);
if (acidFreeLocalPoint == null)
{
continue;
}
OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client,
acidFreeLocalPoint), ACID_FREE_PATH_COLOR);
}
}
if (plugin.isIndicateWooxWalkPath() && plugin.getWooxWalkPath()[0] != null
&& plugin.getWooxWalkPath()[1] != null)
{
LocalPoint attackLocalPoint = LocalPoint.fromWorld(client, plugin.getWooxWalkPath()[0]);
LocalPoint outOfReachLocalPoint = LocalPoint.fromWorld(client, plugin.getWooxWalkPath()[1]);
if (attackLocalPoint != null && outOfReachLocalPoint != null)
{
OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client,
attackLocalPoint), Color.YELLOW);
OverlayUtil.renderPolygon(graphics, Perspective.getCanvasTilePoly(client,
outOfReachLocalPoint), Color.RED);
if (plugin.isIndicateWooxWalkTick() && plugin.getWooxWalkBar() != null
&& plugin.getWooxWalkTimer() != -1)
{
int[] xpointsAttack = {
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2.0 + 1),
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth()),
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth()),
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2 + 1)
};
int[] xpointsOutOfReach = {
(int) plugin.getWooxWalkBar().getX(),
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2.0),
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getWidth() / 2.0),
(int) plugin.getWooxWalkBar().getX()
};
int[] ypointsBoth = {
(int) plugin.getWooxWalkBar().getY(),
(int) plugin.getWooxWalkBar().getY(),
(int) (plugin.getWooxWalkBar().getY() + plugin.getWooxWalkBar().getHeight()),
(int) (plugin.getWooxWalkBar().getY() + plugin.getWooxWalkBar().getHeight())
};
Polygon wooxWalkAttack = new Polygon(xpointsAttack, ypointsBoth, 4);
Polygon wooxWalkOutOfReach = new Polygon(xpointsOutOfReach, ypointsBoth, 4);
OverlayUtil.renderPolygon(graphics, wooxWalkAttack, WOOXWALK_ATTACK_SPOT_COLOR);
OverlayUtil.renderPolygon(graphics, wooxWalkOutOfReach, WOOXWALK_OUT_OF_REACH_SPOT_COLOR);
long timeLeft = (System.currentTimeMillis() - plugin.getWooxWalkTimer()) % 1200;
double timeScale;
if (timeLeft <= 600)
{
timeScale = 1 - timeLeft / 600.0;
}
else
{
timeLeft -= 600;
timeScale = timeLeft / 600.0;
}
int progress = (int) Math.round(plugin.getWooxWalkBar().getWidth() * timeScale);
int[] xpointsIndicator = {
(int) (plugin.getWooxWalkBar().getX() - plugin.getWooxWalkBar().getHeight() / 2 + progress),
(int) (plugin.getWooxWalkBar().getX() + plugin.getWooxWalkBar().getHeight() / 2 + progress),
(int) plugin.getWooxWalkBar().getX() + progress
};
int[] ypointsIndicator = {
(int) (plugin.getWooxWalkBar().getY() - plugin.getWooxWalkBar().getHeight() - BAR_INDICATOR_SPACER),
(int) (plugin.getWooxWalkBar().getY() - plugin.getWooxWalkBar().getHeight() - BAR_INDICATOR_SPACER),
(int) (plugin.getWooxWalkBar().getY() - BAR_INDICATOR_SPACER)
};
Polygon indicator = new Polygon(xpointsIndicator, ypointsIndicator, 3);
OverlayUtil.renderPolygon(graphics, indicator, Color.WHITE);
}
}
}
return null;
}
}

View File

@@ -38,23 +38,12 @@ public class Vorkath
static final int FIRE_BALL_ATTACKS = 25; static final int FIRE_BALL_ATTACKS = 25;
private NPC vorkath; private NPC vorkath;
private VorkathAttack lastAttack; private VorkathAttack lastAttack;
private Phase currentPhase; private Phase currentPhase;
private Phase nextPhase; private Phase nextPhase;
private Phase lastPhase; private Phase lastPhase;
private int attacksLeft; private int attacksLeft;
enum Phase
{
UNKNOWN,
ACID,
FIRE_BALL,
SPAWN
}
public Vorkath(NPC vorkath) public Vorkath(NPC vorkath)
{ {
this.vorkath = vorkath; this.vorkath = vorkath;
@@ -107,4 +96,12 @@ public class Vorkath
log.debug("[Vorkath] Update! Last Phase: {}->{}, Current Phase: {}->{}, Next Phase: {}->{}, Attacks: {}->{}", log.debug("[Vorkath] Update! Last Phase: {}->{}, Current Phase: {}->{}, Next Phase: {}->{}, Attacks: {}->{}",
oldLastPhase, this.lastPhase, oldCurrentPhase, this.currentPhase, oldNextPhase, this.nextPhase, oldAttacksLeft, this.attacksLeft); oldLastPhase, this.lastPhase, oldCurrentPhase, this.currentPhase, oldNextPhase, this.nextPhase, oldAttacksLeft, this.attacksLeft);
} }
enum Phase
{
UNKNOWN,
ACID,
FIRE_BALL,
SPAWN
}
} }

View File

@@ -82,9 +82,6 @@ public enum VorkathAttack
*/ */
ZOMBIFIED_SPAWN(AnimationID.VORKATH_FIRE_BOMB_OR_SPAWN_ATTACK, ProjectileID.VORKATH_SPAWN_AOE); ZOMBIFIED_SPAWN(AnimationID.VORKATH_FIRE_BOMB_OR_SPAWN_ATTACK, ProjectileID.VORKATH_SPAWN_AOE);
private final int vorkathAnimationID;
private final int projectileID;
private static final Map<Integer, VorkathAttack> VORKATH_ATTACKS; private static final Map<Integer, VorkathAttack> VORKATH_ATTACKS;
private static final Map<Integer, VorkathAttack> VORKATH_BASIC_ATTACKS; private static final Map<Integer, VorkathAttack> VORKATH_BASIC_ATTACKS;
@@ -113,6 +110,9 @@ public enum VorkathAttack
VORKATH_BASIC_ATTACKS = builder.build(); VORKATH_BASIC_ATTACKS = builder.build();
} }
private final int vorkathAnimationID;
private final int projectileID;
/** /**
* @param projectileID id of projectile * @param projectileID id of projectile
* @return {@link VorkathAttack} associated with the specified projectile * @return {@link VorkathAttack} associated with the specified projectile
@@ -123,7 +123,7 @@ public enum VorkathAttack
} }
/** /**
* @param projectileID * @param projectileID id of projectile
* @return true if the projectile id matches a {@link VorkathAttack#getProjectileID()} within {@link VorkathAttack#VORKATH_BASIC_ATTACKS}, * @return true if the projectile id matches a {@link VorkathAttack#getProjectileID()} within {@link VorkathAttack#VORKATH_BASIC_ATTACKS},
* false otherwise * false otherwise
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, https://runelitepl.us * Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -24,37 +24,67 @@
*/ */
package net.runelite.client.plugins.vorkath; package net.runelite.client.plugins.vorkath;
import java.awt.Color; import net.runelite.client.config.Config;
import java.awt.Dimension; import net.runelite.client.config.ConfigGroup;
import java.awt.Graphics2D; import net.runelite.client.config.ConfigItem;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
@Singleton @ConfigGroup("vorkath")
public class ZombifiedSpawnOverlay extends Overlay public interface VorkathConfig extends Config
{ {
private final VorkathPlugin plugin; @ConfigItem(
keyName = "indicateAcidPools",
@Inject name = "Acid Pools",
public ZombifiedSpawnOverlay(final VorkathPlugin plugin) description = "Indicate the acid pools",
position = 0
)
default boolean indicateAcidPools()
{ {
setPosition(OverlayPosition.DYNAMIC); return false;
setLayer(OverlayLayer.ABOVE_SCENE);
this.plugin = plugin;
} }
@Override @ConfigItem(
public Dimension render(Graphics2D graphics) keyName = "indicateAcidFreePath",
name = "Acid Free Path",
description = "Indicate the most efficient acid free path",
position = 1
)
default boolean indicateAcidFreePath()
{ {
if (plugin.getZombifiedSpawn() != null) return true;
{ }
OverlayUtil.renderActorOverlayImage(graphics, plugin.getZombifiedSpawn(), VorkathPlugin.SPAWN, Color.green, 10);
}
return null; @ConfigItem(
keyName = "acidFreePathMinLength",
name = "Minimum Length Acid Free Path",
description = "The minimum length of an acid free path",
position = 2,
hidden = true,
unhide = "indicateAcidFreePath"
)
default int acidFreePathLength()
{
return 5;
}
@ConfigItem(
keyName = "indicateWooxWalkPath",
name = "WooxWalk Path",
description = "Indicate the closest WooxWalk path",
position = 3
)
default boolean indicateWooxWalkPath()
{
return true;
}
@ConfigItem(
keyName = "indicateWooxWalkTick",
name = "WooxWalk Tick",
description = "Indicate on which tile to click during each game tick",
position = 4
)
default boolean indicateWooxWalkTick()
{
return true;
} }
} }

View File

@@ -26,7 +26,6 @@
*/ */
package net.runelite.client.plugins.vorkath; package net.runelite.client.plugins.vorkath;
import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@@ -41,6 +40,8 @@ import net.runelite.api.coords.LocalPoint;
import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.util.ImageUtil;
@Singleton @Singleton
public class VorkathOverlay extends Overlay public class VorkathOverlay extends Overlay
@@ -50,6 +51,18 @@ public class VorkathOverlay extends Overlay
private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255); private static final Color COLOR_ICON_BORDER_FILL = new Color(219, 175, 0, 255);
private static final int OVERLAY_ICON_DISTANCE = 30; private static final int OVERLAY_ICON_DISTANCE = 30;
private static final int OVERLAY_ICON_MARGIN = 1; private static final int OVERLAY_ICON_MARGIN = 1;
private static final BufferedImage UNKNOWN;
private static final BufferedImage ACID;
private static final BufferedImage FIRE_BALL;
private static final BufferedImage SPAWN;
static
{
UNKNOWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
FIRE_BALL = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "fire_strike.png");
SPAWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
}
private final Client client; private final Client client;
private final VorkathPlugin plugin; private final VorkathPlugin plugin;
@@ -68,9 +81,9 @@ public class VorkathOverlay extends Overlay
{ {
if (plugin.getVorkath() != null) if (plugin.getVorkath() != null)
{ {
Vorkath vorkath = plugin.getVorkath(); final Vorkath vorkath = plugin.getVorkath();
LocalPoint localLocation = vorkath.getVorkath().getLocalLocation(); final LocalPoint localLocation = vorkath.getVorkath().getLocalLocation();
if (localLocation != null) if (localLocation != null)
{ {
Point point = Perspective.localToCanvas(client, localLocation, client.getPlane(), vorkath.getVorkath().getLogicalHeight() + 16); Point point = Perspective.localToCanvas(client, localLocation, client.getPlane(), vorkath.getVorkath().getLogicalHeight() + 16);
@@ -78,7 +91,7 @@ public class VorkathOverlay extends Overlay
{ {
point = new Point(point.getX(), point.getY()); point = new Point(point.getX(), point.getY());
BufferedImage currentPhaseIcon = getIcon(vorkath); final BufferedImage currentPhaseIcon = getIcon(vorkath);
int totalWidth = 0; int totalWidth = 0;
if (currentPhaseIcon != null) if (currentPhaseIcon != null)
@@ -88,41 +101,33 @@ public class VorkathOverlay extends Overlay
int bgPadding = 8; int bgPadding = 8;
int currentPosX = 0; int currentPosX = 0;
graphics.setStroke(new BasicStroke(2)); if (currentPhaseIcon == null)
graphics.setColor(COLOR_ICON_BACKGROUND); {
graphics.fillOval( return null;
point.getX() - totalWidth / 2 + currentPosX - bgPadding, }
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2);
graphics.setColor(COLOR_ICON_BORDER); OverlayUtil.setProgressIcon(graphics, point, currentPhaseIcon, totalWidth, bgPadding, currentPosX,
graphics.drawOval( COLOR_ICON_BACKGROUND, OVERLAY_ICON_DISTANCE, COLOR_ICON_BORDER, COLOR_ICON_BORDER_FILL);
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2);
graphics.drawImage( final Arc2D.Double arc = new Arc2D.Double(
currentPhaseIcon,
point.getX() - totalWidth / 2 + currentPosX,
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE,
null);
graphics.setColor(COLOR_ICON_BORDER_FILL);
Arc2D.Double arc = new Arc2D.Double(
point.getX() - totalWidth / 2 + currentPosX - bgPadding, point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - currentPhaseIcon.getHeight() / 2 - OVERLAY_ICON_DISTANCE - bgPadding, point.getY() - (float) (currentPhaseIcon.getHeight() / 2) - OVERLAY_ICON_DISTANCE - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2, currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2, currentPhaseIcon.getHeight() + bgPadding * 2,
90.0, 90.0,
-360.0 * getAttacksLeftProgress(), -360.0 * getAttacksLeftProgress(),
Arc2D.OPEN); Arc2D.OPEN
);
graphics.draw(arc); graphics.draw(arc);
} }
} }
} }
if (plugin.getZombifiedSpawn() != null)
{
OverlayUtil.renderActorOverlayImage(graphics, plugin.getZombifiedSpawn(), SPAWN, Color.green, 10);
}
return null; return null;
} }
@@ -135,13 +140,13 @@ public class VorkathOverlay extends Overlay
switch (vorkath.getCurrentPhase()) switch (vorkath.getCurrentPhase())
{ {
case UNKNOWN: case UNKNOWN:
return VorkathPlugin.UNKNOWN; return UNKNOWN;
case ACID: case ACID:
return VorkathPlugin.ACID; return ACID;
case FIRE_BALL: case FIRE_BALL:
return VorkathPlugin.FIRE_BALL; return FIRE_BALL;
case SPAWN: case SPAWN:
return VorkathPlugin.SPAWN; return SPAWN;
} }
return null; return null;
} }

View File

@@ -27,28 +27,47 @@
package net.runelite.client.plugins.vorkath; package net.runelite.client.plugins.vorkath;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.awt.image.BufferedImage; import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.NPC; import net.runelite.api.NPC;
import net.runelite.api.NpcID; import net.runelite.api.ObjectID;
import net.runelite.api.Projectile;
import net.runelite.api.ProjectileID;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.AnimationChanged; import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameObjectDespawned;
import net.runelite.api.events.GameObjectSpawned;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.ProjectileMoved; import net.runelite.api.events.ProjectileMoved;
import net.runelite.api.events.ProjectileSpawned;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.ImageUtil;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor( @PluginDescriptor(
name = "Vorkath Helper", name = "Vorkath Helper",
description = "Count vorkath attacks, and which phase is coming next", description = "Count vorkath attacks, indicate next phase, wooxwalk timer, indicate path through acid",
tags = {"combat", "overlay", "pve", "pvm"}, tags = {"combat", "overlay", "pve", "pvm"},
type = PluginType.PVM, type = PluginType.PVM,
enabledByDefault = false enabledByDefault = false
@@ -61,113 +80,146 @@ public class VorkathPlugin extends Plugin
@Inject @Inject
private Client client; private Client client;
@Inject @Inject
private OverlayManager overlayManager; private OverlayManager overlayManager;
@Inject @Inject
private VorkathOverlay overlay; private VorkathOverlay overlay;
@Inject @Inject
private ZombifiedSpawnOverlay SpawnOverlay; private AcidPathOverlay acidPathOverlay;
@Inject
private VorkathConfig config;
@Inject @Inject
private EventBus eventBus; private EventBus eventBus;
@Getter(AccessLevel.PACKAGE)
@Getter
private Vorkath vorkath; private Vorkath vorkath;
@Getter(AccessLevel.PACKAGE)
@Getter
private NPC zombifiedSpawn; private NPC zombifiedSpawn;
@Getter(AccessLevel.PACKAGE)
private List<WorldPoint> acidSpots = new ArrayList<>();
@Getter(AccessLevel.PACKAGE)
private List<WorldPoint> acidFreePath = new ArrayList<>();
@Getter(AccessLevel.PACKAGE)
private WorldPoint[] wooxWalkPath = new WorldPoint[2];
@Getter(AccessLevel.PACKAGE)
private long wooxWalkTimer = -1;
@Getter(AccessLevel.PACKAGE)
private Rectangle wooxWalkBar;
private int lastAcidSpotsSize = 0;
// Config values
@Getter(AccessLevel.PACKAGE)
private boolean indicateAcidPools;
@Getter(AccessLevel.PACKAGE)
private boolean indicateAcidFreePath;
@Getter(AccessLevel.PACKAGE)
private boolean indicateWooxWalkPath;
@Getter(AccessLevel.PACKAGE)
private boolean indicateWooxWalkTick;
private int acidFreePathLength;
/** @Provides
* The last projectile's starting movement cycle VorkathConfig provideConfig(ConfigManager configManager)
*/
private int lastProjectileCycle;
static final BufferedImage UNKNOWN;
static final BufferedImage ACID;
static final BufferedImage FIRE_BALL;
static final BufferedImage SPAWN;
static
{ {
UNKNOWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png"); return configManager.getConfig(VorkathConfig.class);
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
FIRE_BALL = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "fire_strike.png");
SPAWN = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
} }
@Override @Override
protected void startUp() throws Exception protected void startUp()
{ {
addSubscriptions(); addSubscriptions();
updateConfig();
} }
@Override @Override
protected void shutDown() throws Exception protected void shutDown()
{ {
eventBus.unregister(this); reset();
} }
private void addSubscriptions() private void addSubscriptions()
{ {
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned); eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned); eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved); eventBus.subscribe(ProjectileMoved.class, this, this::onProjectileMoved);
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged); eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged);
eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned);
eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned);
eventBus.subscribe(ClientTick.class, this, this::onClientTick);
eventBus.subscribe(GameTick.class, this, this::onGameTick);
}
private void onConfigChanged(ConfigChanged event)
{
if (!event.getGroup().equals("vorkath"))
{
return;
}
updateConfig();
} }
private void onNpcSpawned(NpcSpawned event) private void onNpcSpawned(NpcSpawned event)
{ {
if (isAtVorkath()) if (!isAtVorkath())
{ {
if (isVorkath(event.getNpc().getId())) return;
{ }
vorkath = new Vorkath(event.getNpc());
lastProjectileCycle = -1; final NPC npc = event.getNpc();
overlayManager.add(overlay);
} if (npc.getName() == null)
else if (isZombifiedSpawn(event.getNpc().getId())) {
{ return;
zombifiedSpawn = event.getNpc(); }
overlayManager.add(SpawnOverlay);
} if (npc.getName().equals("Vorkath"))
{
vorkath = new Vorkath(npc);
overlayManager.add(overlay);
}
else if (npc.getName().equals("Zombified Spawn"))
{
zombifiedSpawn = npc;
} }
} }
private void onNpcDespawned(NpcDespawned event) private void onNpcDespawned(NpcDespawned event)
{ {
if (isAtVorkath()) if (!isAtVorkath())
{
if (isVorkath(event.getNpc().getId()))
{
vorkath = null;
lastProjectileCycle = -1;
overlayManager.remove(overlay);
}
else if (isZombifiedSpawn(event.getNpc().getId()))
{
zombifiedSpawn = null;
overlayManager.remove(SpawnOverlay);
}
}
}
private void onProjectileMoved(ProjectileMoved event)
{
// Only capture initial projectile
if (!isAtVorkath() || event.getProjectile().getStartMovementCycle() == lastProjectileCycle)
{ {
return; return;
} }
VorkathAttack vorkathAttack = VorkathAttack.getVorkathAttack(event.getProjectile().getId()); final NPC npc = event.getNpc();
if (npc.getName() == null)
{
return;
}
if (npc.getName().equals("Vorkath"))
{
reset();
}
else if (npc.getName().equals("Zombified Spawn"))
{
zombifiedSpawn = null;
}
}
private void onProjectileSpawned(ProjectileSpawned event)
{
if (!isAtVorkath())
{
return;
}
final Projectile proj = event.getProjectile();
final VorkathAttack vorkathAttack = VorkathAttack.getVorkathAttack(proj.getId());
if (vorkathAttack != null) if (vorkathAttack != null)
{ {
/*log.debug("[Projectile ({})] Game Tick: {}, Game Cycle: {}, Starting Cyle: {} Last Cycle: {}, Initial Projectile?: {}",
vorkathAttack, client.getTickCount(), client.getGameCycle(), event.getProjectile().getStartMovementCycle(),
lastProjectileCycle, event.getProjectile().getStartMovementCycle() == client.getGameCycle());*/
if (VorkathAttack.isBasicAttack(vorkathAttack.getProjectileID()) && vorkath.getAttacksLeft() > 0) if (VorkathAttack.isBasicAttack(vorkathAttack.getProjectileID()) && vorkath.getAttacksLeft() > 0)
{ {
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
@@ -175,46 +227,90 @@ public class VorkathPlugin extends Plugin
else if (vorkathAttack == VorkathAttack.ACID) else if (vorkathAttack == VorkathAttack.ACID)
{ {
vorkath.updatePhase(Vorkath.Phase.ACID); vorkath.updatePhase(Vorkath.Phase.ACID);
// Sets the phase's progress indicator to done
vorkath.setAttacksLeft(0); vorkath.setAttacksLeft(0);
} }
else if (vorkathAttack == VorkathAttack.FIRE_BALL) else if (vorkathAttack == VorkathAttack.FIRE_BALL)
{ {
vorkath.updatePhase(Vorkath.Phase.FIRE_BALL); vorkath.updatePhase(Vorkath.Phase.FIRE_BALL);
// Decrement to account for this fire ball
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
} }
else if (vorkathAttack == VorkathAttack.FREEZE_BREATH && vorkath.getLastAttack() != VorkathAttack.ZOMBIFIED_SPAWN) else if (vorkathAttack == VorkathAttack.FREEZE_BREATH && vorkath.getLastAttack() != VorkathAttack.ZOMBIFIED_SPAWN)
{ {
// Filters out second invisible freeze attack that is immediately after the Zombified Spawn
vorkath.updatePhase(Vorkath.Phase.SPAWN); vorkath.updatePhase(Vorkath.Phase.SPAWN);
// Sets progress of the phase to half
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - (vorkath.getAttacksLeft() / 2)); vorkath.setAttacksLeft(vorkath.getAttacksLeft() - (vorkath.getAttacksLeft() / 2));
} }
else if (vorkathAttack == VorkathAttack.ZOMBIFIED_SPAWN || (vorkath.getLastAttack() == VorkathAttack.ZOMBIFIED_SPAWN)) else if (vorkathAttack == VorkathAttack.ZOMBIFIED_SPAWN || (vorkath.getLastAttack() == VorkathAttack.ZOMBIFIED_SPAWN))
{ {
// Also consumes the second invisible freeze attack that is immediately after the Zombified Spawn
// Sets progress of the phase to done as there are no more attacks within this phase
vorkath.setAttacksLeft(0); vorkath.setAttacksLeft(0);
} }
else else
{ {
// Vorkath fired a basic attack AND there are no more attacks left, typically after phases are over
vorkath.updatePhase(vorkath.getNextPhase()); vorkath.updatePhase(vorkath.getNextPhase());
// Decrement to account for this basic attack
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
} }
log.debug("[Vorkath ({})] {}", vorkathAttack, vorkath); log.debug("[Vorkath ({})] {}", vorkathAttack, vorkath);
vorkath.setLastAttack(vorkathAttack); vorkath.setLastAttack(vorkathAttack);
lastProjectileCycle = event.getProjectile().getStartMovementCycle(); }
}
private void onProjectileMoved(ProjectileMoved event)
{
if (!isAtVorkath())
{
return;
}
final Projectile proj = event.getProjectile();
final LocalPoint loc = event.getPosition();
if (proj.getId() == ProjectileID.VORKATH_POISON_POOL_AOE)
{
addAcidSpot(WorldPoint.fromLocal(client, loc));
}
}
private void onGameObjectSpawned(GameObjectSpawned event)
{
if (!isAtVorkath())
{
return;
}
final GameObject obj = event.getGameObject();
if (obj.getId() == ObjectID.ACID_POOL || obj.getId() == ObjectID.ACID_POOL_32000)
{
addAcidSpot(obj.getWorldLocation());
}
}
private void onGameObjectDespawned(GameObjectDespawned event)
{
if (!isAtVorkath())
{
return;
}
final GameObject obj = event.getGameObject();
if (obj.getId() == ObjectID.ACID_POOL || obj.getId() == ObjectID.ACID_POOL_32000)
{
acidSpots.remove(obj.getWorldLocation());
} }
} }
private void onAnimationChanged(AnimationChanged event) private void onAnimationChanged(AnimationChanged event)
{ {
if (isAtVorkath() && vorkath != null && event.getActor().equals(vorkath.getVorkath()) if (!isAtVorkath())
&& event.getActor().getAnimation() == VorkathAttack.SLASH_ATTACK.getVorkathAnimationID()) {
return;
}
final Actor actor = event.getActor();
if (isAtVorkath() && vorkath != null && actor.equals(vorkath.getVorkath())
&& actor.getAnimation() == VorkathAttack.SLASH_ATTACK.getVorkathAnimationID())
{ {
if (vorkath.getAttacksLeft() > 0) if (vorkath.getAttacksLeft() > 0)
{ {
@@ -222,15 +318,83 @@ public class VorkathPlugin extends Plugin
} }
else else
{ {
// No more attacks left, typically after phases are over
vorkath.updatePhase(vorkath.getNextPhase()); vorkath.updatePhase(vorkath.getNextPhase());
// Decrement to account for this basic attack
vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1); vorkath.setAttacksLeft(vorkath.getAttacksLeft() - 1);
} }
log.debug("[Vorkath (SLASH_ATTACK)] {}", vorkath); log.debug("[Vorkath (SLASH_ATTACK)] {}", vorkath);
} }
} }
private void onGameTick(GameTick event)
{
if (!isAtVorkath())
{
return;
}
// Update the acid free path every tick to account for player movement
if (this.indicateAcidFreePath && !acidSpots.isEmpty())
{
calculateAcidFreePath();
}
// Start the timer when the player walks into the WooxWalk zone
if (this.indicateWooxWalkPath && this.indicateWooxWalkTick && wooxWalkPath[0] != null && wooxWalkPath[1] != null)
{
final WorldPoint playerLoc = client.getLocalPlayer().getWorldLocation();
if (playerLoc.getX() == wooxWalkPath[0].getX() && playerLoc.getY() == wooxWalkPath[0].getY()
&& playerLoc.getPlane() == wooxWalkPath[0].getPlane())
{
if (wooxWalkTimer == -1)
{
wooxWalkTimer = System.currentTimeMillis() - 400;
}
}
else if (playerLoc.getX() == wooxWalkPath[1].getX() && playerLoc.getY() == wooxWalkPath[1].getY()
&& playerLoc.getPlane() == wooxWalkPath[1].getPlane())
{
if (wooxWalkTimer == -1)
{
wooxWalkTimer = System.currentTimeMillis() - 1000;
}
}
else if (wooxWalkTimer != -1)
{
wooxWalkTimer = -1;
}
}
}
private void onClientTick(ClientTick event)
{
if (acidSpots.size() != lastAcidSpotsSize)
{
if (acidSpots.size() == 0)
{
overlayManager.remove(acidPathOverlay);
acidFreePath.clear();
Arrays.fill(wooxWalkPath, null);
wooxWalkTimer = -1;
}
else
{
if (this.indicateAcidFreePath)
{
calculateAcidFreePath();
}
if (this.indicateWooxWalkPath)
{
calculateWooxWalkPath();
}
overlayManager.add(acidPathOverlay);
}
lastAcidSpotsSize = acidSpots.size();
}
}
/** /**
* @return true if the player is in the Vorkath region, false otherwise * @return true if the player is in the Vorkath region, false otherwise
*/ */
@@ -239,28 +403,209 @@ public class VorkathPlugin extends Plugin
return ArrayUtils.contains(client.getMapRegions(), VORKATH_REGION); return ArrayUtils.contains(client.getMapRegions(), VORKATH_REGION);
} }
/** private void addAcidSpot(WorldPoint acidSpotLocation)
* @param npcID
* @return true if the npc is Vorkath, false otherwise
*/
private boolean isVorkath(int npcID)
{ {
// Could be done with a a simple name check instead... if (!acidSpots.contains(acidSpotLocation))
return npcID == NpcID.VORKATH || {
npcID == NpcID.VORKATH_8058 || acidSpots.add(acidSpotLocation);
npcID == NpcID.VORKATH_8059 || }
npcID == NpcID.VORKATH_8060 ||
npcID == NpcID.VORKATH_8061;
} }
/** private void calculateAcidFreePath()
* @param npcID
* @return true if the npc is a Zombified Spawn, otherwise false
*/
private boolean isZombifiedSpawn(int npcID)
{ {
// Could be done with a a simple name check instead... acidFreePath.clear();
return npcID == NpcID.ZOMBIFIED_SPAWN ||
npcID == NpcID.ZOMBIFIED_SPAWN_8063; final int[][][] directions = {
{
{0, 1}, {0, -1} // Positive and negative Y
},
{
{1, 0}, {-1, 0} // Positive and negative X
}
};
List<WorldPoint> bestPath = new ArrayList<>();
double bestClicksRequired = 99;
final WorldPoint playerLoc = client.getLocalPlayer().getWorldLocation();
final WorldPoint vorkLoc = vorkath.getVorkath().getWorldLocation();
final int maxX = vorkLoc.getX() + 14;
final int minX = vorkLoc.getX() - 8;
final int maxY = vorkLoc.getY() - 1;
final int minY = vorkLoc.getY() - 8;
// Attempt to search an acid free path, beginning at a location
// adjacent to the player's location (including diagonals)
for (int x = -1; x < 2; x++)
{
for (int y = -1; y < 2; y++)
{
final WorldPoint baseLocation = new WorldPoint(playerLoc.getX() + x,
playerLoc.getY() + y, playerLoc.getPlane());
if (acidSpots.contains(baseLocation) || baseLocation.getY() < minY || baseLocation.getY() > maxY)
{
continue;
}
// Search in X and Y direction
for (int d = 0; d < directions.length; d++)
{
// Calculate the clicks required to start walking on the path
double currentClicksRequired = Math.abs(x) + Math.abs(y);
if (currentClicksRequired < 2)
{
currentClicksRequired += Math.abs(y * directions[d][0][0]) + Math.abs(x * directions[d][0][1]);
}
if (d == 0)
{
// Prioritize a path in the X direction (sideways)
currentClicksRequired += 0.5;
}
List<WorldPoint> currentPath = new ArrayList<>();
currentPath.add(baseLocation);
// Positive X (first iteration) or positive Y (second iteration)
for (int i = 1; i < 25; i++)
{
final WorldPoint testingLocation = new WorldPoint(baseLocation.getX() + i * directions[d][0][0],
baseLocation.getY() + i * directions[d][0][1], baseLocation.getPlane());
if (acidSpots.contains(testingLocation) || testingLocation.getY() < minY || testingLocation.getY() > maxY
|| testingLocation.getX() < minX || testingLocation.getX() > maxX)
{
break;
}
currentPath.add(testingLocation);
}
// Negative X (first iteration) or positive Y (second iteration)
for (int i = 1; i < 25; i++)
{
final WorldPoint testingLocation = new WorldPoint(baseLocation.getX() + i * directions[d][1][0],
baseLocation.getY() + i * directions[d][1][1], baseLocation.getPlane());
if (acidSpots.contains(testingLocation) || testingLocation.getY() < minY || testingLocation.getY() > maxY
|| testingLocation.getX() < minX || testingLocation.getX() > maxX)
{
break;
}
currentPath.add(testingLocation);
}
if (currentPath.size() >= this.acidFreePathLength && currentClicksRequired < bestClicksRequired
|| (currentClicksRequired == bestClicksRequired && currentPath.size() > bestPath.size()))
{
bestPath = currentPath;
bestClicksRequired = currentClicksRequired;
}
}
}
}
if (bestClicksRequired != 99)
{
acidFreePath = bestPath;
}
}
private void calculateWooxWalkPath()
{
wooxWalkTimer = -1;
updateWooxWalkBar();
final WorldPoint playerLoc = client.getLocalPlayer().getWorldLocation();
final WorldPoint vorkLoc = vorkath.getVorkath().getWorldLocation();
final int maxX = vorkLoc.getX() + 14;
final int minX = vorkLoc.getX() - 8;
final int baseX = playerLoc.getX();
final int baseY = vorkLoc.getY() - 5;
final int middleX = vorkLoc.getX() + 3;
// Loop through the arena tiles in the x-direction and
// alternate between positive and negative x direction
for (int i = 0; i < 50; i++)
{
// Make sure we always choose the spot closest to
// the middle of the arena
int directionRemainder = 0;
if (playerLoc.getX() < middleX)
{
directionRemainder = 1;
}
int deviation = (int) Math.floor(i / 2.0);
if (i % 2 == directionRemainder)
{
deviation = -deviation;
}
final WorldPoint attackLocation = new WorldPoint(baseX + deviation, baseY, playerLoc.getPlane());
final WorldPoint outOfRangeLocation = new WorldPoint(baseX + deviation, baseY - 1, playerLoc.getPlane());
if (acidSpots.contains(attackLocation) || acidSpots.contains(outOfRangeLocation)
|| attackLocation.getX() < minX || attackLocation.getX() > maxX)
{
continue;
}
wooxWalkPath[0] = attackLocation;
wooxWalkPath[1] = outOfRangeLocation;
break;
}
}
private void updateWooxWalkBar()
{
// Update the WooxWalk tick indicator's dimensions
// based on the canvas dimensions
final Widget exp = client.getWidget(WidgetInfo.EXPERIENCE_TRACKER);
if (exp == null)
{
return;
}
final Rectangle screen = exp.getBounds();
int width = (int) Math.floor(screen.getWidth() / 2.0);
if (width % 2 == 1)
{
width++;
}
int height = (int) Math.floor(width / 20.0);
if (height % 2 == 1)
{
height++;
}
final int x = (int) Math.floor(screen.getX() + width / 2.0);
final int y = (int) Math.floor(screen.getY() + screen.getHeight() - 2 * height);
wooxWalkBar = new Rectangle(x, y, width, height);
}
private void updateConfig()
{
this.indicateAcidPools = config.indicateAcidPools();
this.indicateAcidFreePath = config.indicateAcidFreePath();
this.indicateWooxWalkPath = config.indicateWooxWalkPath();
this.indicateWooxWalkTick = config.indicateWooxWalkTick();
this.acidFreePathLength = config.acidFreePathLength();
}
private void reset()
{
overlayManager.remove(overlay);
overlayManager.remove(acidPathOverlay);
vorkath = null;
acidSpots.clear();
acidFreePath.clear();
Arrays.fill(wooxWalkPath, null);
wooxWalkTimer = -1;
zombifiedSpawn = null;
} }
} }

View File

@@ -393,4 +393,30 @@ public class OverlayUtil
OverlayUtil.drawStrokeAndFillPoly(graphics, color, outlineWidth, outlineAlpha, fillAlpha, tilePoly); OverlayUtil.drawStrokeAndFillPoly(graphics, color, outlineWidth, outlineAlpha, fillAlpha, tilePoly);
} }
} }
public static void setProgressIcon(Graphics2D graphics, Point point, BufferedImage currentPhaseIcon, int totalWidth, int bgPadding, int currentPosX, Color colorIconBackground, int overlayIconDistance, Color colorIconBorder, Color colorIconBorderFill)
{
graphics.setStroke(new BasicStroke(2));
graphics.setColor(colorIconBackground);
graphics.fillOval(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2);
graphics.setColor(colorIconBorder);
graphics.drawOval(
point.getX() - totalWidth / 2 + currentPosX - bgPadding,
point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance - bgPadding,
currentPhaseIcon.getWidth() + bgPadding * 2,
currentPhaseIcon.getHeight() + bgPadding * 2);
graphics.drawImage(
currentPhaseIcon,
point.getX() - totalWidth / 2 + currentPosX,
point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance,
null);
graphics.setColor(colorIconBorderFill);
}
} }

View File

@@ -208,9 +208,15 @@ public abstract class RSClientMixin implements RSClient
@Inject @Inject
private static boolean hideFriendAttackOptions = false; private static boolean hideFriendAttackOptions = false;
@Inject
private static boolean hideClanmateAttackOptions = false;
@Inject @Inject
private static boolean hideFriendCastOptions = false; private static boolean hideFriendCastOptions = false;
@Inject
private static boolean hideClanmateCastOptions = false;
@Inject @Inject
private static Set<String> unhiddenCasts = new HashSet<String>(); private static Set<String> unhiddenCasts = new HashSet<String>();
@@ -228,6 +234,20 @@ public abstract class RSClientMixin implements RSClient
hideFriendCastOptions = yes; hideFriendCastOptions = yes;
} }
@Inject
@Override
public void setHideClanmateAttackOptions(boolean yes)
{
hideClanmateAttackOptions = yes;
}
@Inject
@Override
public void setHideClanmateCastOptions(boolean yes)
{
hideClanmateCastOptions = yes;
}
@Inject @Inject
@Override @Override
public void setUnhiddenCasts(Set<String> casts) public void setUnhiddenCasts(Set<String> casts)
@@ -1644,12 +1664,11 @@ public abstract class RSClientMixin implements RSClient
{ {
if (client.isSpellSelected()) if (client.isSpellSelected())
{ {
return hideFriendCastOptions return ((hideFriendCastOptions && p.isFriended()) || (hideClanmateCastOptions && p.isClanMember()))
&& (p.isFriended() || p.isClanMember()) && !unhiddenCasts.contains(client.getSelectedSpellName().replaceAll("<[^>]*>", "").toLowerCase());
&& !unhiddenCasts.contains(client.getSelectedSpellName());
} }
return hideFriendAttackOptions && (p.isFriended() || p.isClanMember()); return ((hideFriendAttackOptions && p.isFriended()) || (hideClanmateAttackOptions && p.isClanMember()));
} }
@Inject @Inject