Changes (#15)
* Add config option to hide inventory viewer when player inventory is open * Fix style error * Adds world history to world hopper plugin.\n- Adds support for converting strings to Maps\n- Ability to clear history * Fixed code style issues * Fixed code style issues in another file * Adds ability to not show tabs if you don't want * Tabs are not shown by default * Fix indentation in InventoryViewerConfig * mixes checkstyle * mixes checkstyle * Adds ability to see your xp drops as damage, overlayed above your opponent * Adds building to jar capabilities and fixes 0s * added output * Add grouping option to Inventory Viewer * Add option to show free slots Works on both the Grouped and Full modes * skybox: calculate brightness increase in HSB format * mixins: renderWidgetLayer: skip hidden widgets * World Map: Identify Both Shield of Arrav Quest Start Points (#8442) Closes #8437 * Add Ammo plugin Shows the contents of the Ammo slot as an Infobox * Add support for weapon slot items, such as darts * Add stack formatting * Improve Ammo's Documentation * widgetitem: associate Widget with WidgetItem * widgetitem overlay: allow configuring which interfaces to overlay Update overlays to behave consistent with how they behaved before removal of query api, with the exception of adding the rune pouch overlay to the bank. * Displays teammate health bars for BA Healer overlay Parses teammate hp and outputs to System.out Removed useless class Displays offset inverted health bars Set accurate values for location and size of health bars Checkstyle Checkstyle * Nothing * Removes max draw distance of ground markers * Added vanguard hp tracker * Vanguard Disabled by default * Add player indicator config to show offline friends * Better player indicator plugin, removed pk vison. added InteractChanged api * Add a toggle to only show player indicators in the wilderness. * Dont limit level by default in playerindicators * Added type to plugins
This commit is contained in:
@@ -602,6 +602,22 @@ public class ConfigManager
|
||||
{
|
||||
return Duration.ofMillis(Long.parseLong(str));
|
||||
}
|
||||
if (type == Map.class)
|
||||
{
|
||||
Map<String, String> output = new HashMap<>();
|
||||
str = str.substring(1, str.length() - 1);
|
||||
String[] splitStr = str.split(", ");
|
||||
for (String s : splitStr)
|
||||
{
|
||||
String[] keyVal = s.split("=");
|
||||
if (keyVal.length > 1)
|
||||
{
|
||||
output.put(keyVal[0], keyVal[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.ammo;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||
import net.runelite.client.util.StackFormatter;
|
||||
|
||||
public class AmmoCounter extends Counter
|
||||
{
|
||||
@Getter
|
||||
private int itemID;
|
||||
|
||||
@Getter
|
||||
private String name;
|
||||
|
||||
public AmmoCounter(Plugin plugin, int itemID, int count, String name, BufferedImage image)
|
||||
{
|
||||
super(image, plugin, count);
|
||||
this.itemID = itemID;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
return StackFormatter.quantityToRSDecimalStack(getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.ammo;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
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.ui.overlay.infobox.InfoBoxManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Ammo",
|
||||
description = "Shows the current ammo the player has equipped",
|
||||
tags = {"bolts", "darts", "chinchompa"},
|
||||
type = "utility"
|
||||
)
|
||||
public class AmmoPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
private AmmoCounter counterBox;
|
||||
|
||||
@Override
|
||||
public void startUp() throws Exception
|
||||
{
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
ItemContainer container = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
if (container != null)
|
||||
{
|
||||
parseInventory(container.getItems());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws Exception
|
||||
{
|
||||
infoBoxManager.removeInfoBox(counterBox);
|
||||
counterBox = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemContainerChanged(ItemContainerChanged event)
|
||||
{
|
||||
if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parseInventory(event.getItemContainer().getItems());
|
||||
}
|
||||
|
||||
private void parseInventory(Item[] items)
|
||||
{
|
||||
// Check for weapon slot items. This overrides the ammo slot,
|
||||
// as the player will use the thrown weapon (eg. chinchompas, knives, darts)
|
||||
if (items.length >= EquipmentInventorySlot.WEAPON.getSlotIdx() - 1)
|
||||
{
|
||||
final Item weapon = items[EquipmentInventorySlot.WEAPON.getSlotIdx()];
|
||||
final ItemComposition weaponComp = itemManager.getItemComposition(weapon.getId());
|
||||
if (weaponComp.isStackable())
|
||||
{
|
||||
updateInfobox(weapon, weaponComp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (items.length <= EquipmentInventorySlot.AMMO.getSlotIdx())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Item ammo = items[EquipmentInventorySlot.AMMO.getSlotIdx()];
|
||||
final ItemComposition comp = itemManager.getItemComposition(ammo.getId());
|
||||
|
||||
if (!comp.isStackable())
|
||||
{
|
||||
infoBoxManager.removeInfoBox(counterBox);
|
||||
counterBox = null;
|
||||
return;
|
||||
}
|
||||
|
||||
updateInfobox(ammo, comp);
|
||||
}
|
||||
|
||||
private void updateInfobox(Item item, ItemComposition comp)
|
||||
{
|
||||
if (counterBox != null && counterBox.getItemID() == item.getId())
|
||||
{
|
||||
counterBox.setCount(item.getQuantity());
|
||||
return;
|
||||
}
|
||||
|
||||
infoBoxManager.removeInfoBox(counterBox);
|
||||
final BufferedImage image = itemManager.getImage(item.getId(), 5, false);
|
||||
counterBox = new AmmoCounter(this, item.getId(), item.getQuantity(), comp.getName(), image);
|
||||
infoBoxManager.addInfoBox(counterBox);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ package net.runelite.client.plugins.attackstyles;
|
||||
|
||||
import net.runelite.api.Skill;
|
||||
|
||||
enum AttackStyle
|
||||
public enum AttackStyle
|
||||
{
|
||||
ACCURATE("Accurate", Skill.ATTACK),
|
||||
AGGRESSIVE("Aggressive", Skill.STRENGTH),
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.*;
|
||||
|
||||
enum WeaponType
|
||||
public enum WeaponType
|
||||
{
|
||||
TYPE_0(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
|
||||
TYPE_1(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
|
||||
@@ -55,6 +55,11 @@ class BarbarianAssaultOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_EGG_DISTANCE = 2500;
|
||||
|
||||
|
||||
private final int HEALTH_BAR_HEIGHT = 20;
|
||||
private final Color HEALTH_BAR_COLOR = new Color(225, 35, 0, 125);
|
||||
private static final Color BACKGROUND = new Color(0, 0, 0, 150);
|
||||
|
||||
private final Client client;
|
||||
private final BarbarianAssaultPlugin plugin;
|
||||
private final BarbarianAssaultConfig config;
|
||||
@@ -156,7 +161,35 @@ class BarbarianAssaultOverlay extends Overlay
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
if (role == Role.HEALER)
|
||||
{
|
||||
for (HealerTeam teammate : HealerTeam.values())
|
||||
{
|
||||
Widget widget = client.getWidget(teammate.getTeammate());
|
||||
if (widget == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] teammateHealth = widget.getText().split(" / ");
|
||||
final int curHealth = Integer.parseInt(teammateHealth[0]);
|
||||
final int maxHealth = Integer.parseInt(teammateHealth[1]);
|
||||
|
||||
int width = teammate.getWidth();
|
||||
final int filledWidth = getBarWidth(maxHealth, curHealth, width);
|
||||
|
||||
int offsetX = teammate.getOffset().getX();
|
||||
int offsetY = teammate.getOffset().getY();
|
||||
int x = widget.getCanvasLocation().getX() - offsetX;
|
||||
int y = widget.getCanvasLocation().getY() - offsetY;
|
||||
|
||||
graphics.setColor(HEALTH_BAR_COLOR);
|
||||
graphics.fillRect(x, y, filledWidth, HEALTH_BAR_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderEggLocation(Graphics2D graphics, WorldPoint location, int quantity, Color color)
|
||||
@@ -186,4 +219,16 @@ class BarbarianAssaultOverlay extends Overlay
|
||||
Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, 0);
|
||||
OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE);
|
||||
}
|
||||
|
||||
private static int getBarWidth(int base, int current, int size)
|
||||
{
|
||||
final double ratio = (double) current / base;
|
||||
|
||||
if (ratio >= 1)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
return (int) Math.round(ratio * size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018, whartd <github.com/whartd>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
enum HealerTeam
|
||||
{
|
||||
TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115),
|
||||
TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115),
|
||||
TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115),
|
||||
TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115);
|
||||
|
||||
private WidgetInfo teammate;
|
||||
private Point offset;
|
||||
private int width;
|
||||
}
|
||||
@@ -87,4 +87,26 @@ public interface XpDropConfig extends Config
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showDamage",
|
||||
name = "Show Damage on XP Drop",
|
||||
description = "Show what you hit next to the XP drop",
|
||||
position = 5
|
||||
)
|
||||
default boolean showDamage()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "damageColor",
|
||||
name = "Damage Color",
|
||||
description = "The color you want the text to be for damage",
|
||||
position = 6
|
||||
)
|
||||
default Color getDamageColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.experiencedrop;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class XpDropOverlay extends Overlay
|
||||
{
|
||||
private final XpDropPlugin plugin;
|
||||
private final XpDropConfig config;
|
||||
|
||||
@Inject
|
||||
private XpDropOverlay(XpDropPlugin plugin, XpDropConfig config)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.showDamage())
|
||||
{
|
||||
final Actor opponent = plugin.getLastOpponent();
|
||||
if (opponent != null)
|
||||
{
|
||||
int offset = opponent.getLogicalHeight() + 50;
|
||||
String damageStr = String.valueOf(this.plugin.getDamage());
|
||||
Point textLocation = opponent.getCanvasTextLocation(graphics, damageStr, offset);
|
||||
|
||||
if (textLocation != null && this.plugin.getDamage() != 0)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, damageStr, config.getDamageColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -25,26 +25,38 @@
|
||||
package net.runelite.client.plugins.experiencedrop;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.*;
|
||||
|
||||
import static net.runelite.api.ScriptID.XPDROP_DISABLED;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.WidgetHiddenChanged;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.*;
|
||||
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.HiscoreManager;
|
||||
import net.runelite.client.game.NPCManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.attackstyles.AttackStyle;
|
||||
import net.runelite.client.plugins.attackstyles.WeaponType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
||||
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "XP Drop",
|
||||
@@ -54,6 +66,7 @@ import net.runelite.client.plugins.PluginDescriptor;
|
||||
public class XpDropPlugin extends Plugin
|
||||
{
|
||||
private static final int XPDROP_PADDING = 2; // space between xp drop icons
|
||||
private static final Duration WAIT = Duration.ofSeconds(5);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
@@ -63,11 +76,39 @@ public class XpDropPlugin extends Plugin
|
||||
|
||||
private int tickCounter = 0;
|
||||
private int previousExpGained;
|
||||
private boolean hasHit = false;
|
||||
private boolean hasDropped = false;
|
||||
private boolean correctPrayer;
|
||||
private Skill lastSkill = null;
|
||||
private Map<Skill, Integer> previousSkillExpTable = new EnumMap<>(Skill.class);
|
||||
private PrayerType currentTickPrayer;
|
||||
private AttackStyle attackStyle;
|
||||
private int attackStyleVarbit = -1;
|
||||
private int equippedWeaponTypeVarbit = -1;
|
||||
private int castingModeVarbit = -1;
|
||||
private int opponentHealth = -1;
|
||||
private int xpGains = 0;
|
||||
private AttackStyle[] offensiveStyles = {ACCURATE, AGGRESSIVE, DEFENSIVE, CONTROLLED, RANGING, LONGRANGE, CASTING, DEFENSIVE_CASTING};
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int damage = 0;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Actor lastOpponent;
|
||||
|
||||
private Instant lastTime;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private XpDropOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private NPCManager npcManager;
|
||||
|
||||
@Inject
|
||||
private HiscoreManager hiscoreManager;
|
||||
|
||||
@Provides
|
||||
XpDropConfig provideConfig(ConfigManager configManager)
|
||||
@@ -75,6 +116,23 @@ public class XpDropPlugin extends Plugin
|
||||
return configManager.getConfig(XpDropConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
lastOpponent = null;
|
||||
overlayManager.add(overlay);
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(
|
||||
equippedWeaponTypeVarbit,
|
||||
attackStyleVarbit,
|
||||
castingModeVarbit);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetHiddenChanged(WidgetHiddenChanged event)
|
||||
{
|
||||
@@ -203,6 +261,42 @@ public class XpDropPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
// Detect hitting a 0
|
||||
if (lastOpponent != null)
|
||||
{
|
||||
int health = calculateHealth(lastOpponent);
|
||||
if (health != -1 && opponentHealth != -1 && health == opponentHealth && hasHit)
|
||||
{
|
||||
damage = 0;
|
||||
hasHit = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle getting XP gains
|
||||
if (hasDropped)
|
||||
{
|
||||
if (xpGains != 0 && attackStyle.getSkills().length > 1 && attackStyle != LONGRANGE)
|
||||
{
|
||||
damage = (int) (xpGains / (attackStyle.getSkills().length * 1.3));
|
||||
}
|
||||
else if (xpGains != 0)
|
||||
{
|
||||
damage = xpGains / 4;
|
||||
}
|
||||
|
||||
xpGains = 0;
|
||||
hasDropped = false;
|
||||
}
|
||||
|
||||
// Clear opponent
|
||||
if (lastOpponent != null && lastTime != null && client.getLocalPlayer().getInteracting() == null)
|
||||
{
|
||||
if (Duration.between(lastTime, Instant.now()).compareTo(WAIT) > 0)
|
||||
{
|
||||
lastOpponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
currentTickPrayer = getActivePrayerType();
|
||||
correctPrayer = false;
|
||||
|
||||
@@ -240,9 +334,115 @@ public class XpDropPlugin extends Plugin
|
||||
Integer previous = previousSkillExpTable.put(skill, xp);
|
||||
if (previous != null)
|
||||
{
|
||||
opponentHealth = calculateHealth(lastOpponent);
|
||||
previousExpGained = xp - previous;
|
||||
if (skill != Skill.HITPOINTS && Arrays.stream(offensiveStyles).anyMatch(attackStyle::equals))
|
||||
{
|
||||
xpGains += previousExpGained;
|
||||
}
|
||||
|
||||
hasDropped = true;
|
||||
hasHit = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode)
|
||||
{
|
||||
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles();
|
||||
if (attackStyleIndex < attackStyles.length)
|
||||
{
|
||||
attackStyle = attackStyles[attackStyleIndex];
|
||||
if (attackStyle == null)
|
||||
{
|
||||
attackStyle = OTHER;
|
||||
}
|
||||
else if ((attackStyle == CASTING) && (castingMode == 1))
|
||||
{
|
||||
attackStyle = DEFENSIVE_CASTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractingChanged(InteractingChanged event)
|
||||
{
|
||||
if (event.getSource() != client.getLocalPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Actor opponent = event.getTarget();
|
||||
|
||||
if (opponent == null)
|
||||
{
|
||||
lastTime = Instant.now();
|
||||
return;
|
||||
}
|
||||
|
||||
damage = 0;
|
||||
lastOpponent = opponent;
|
||||
opponentHealth = calculateHealth(opponent);
|
||||
}
|
||||
|
||||
private int calculateHealth(Actor target)
|
||||
{
|
||||
if (target == null || target.getName() == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int healthScale = target.getHealth();
|
||||
final int healthRatio = target.getHealthRatio();
|
||||
final String targetName = Text.removeTags(target.getName());
|
||||
|
||||
Integer maxHealth = -1;
|
||||
if (target instanceof NPC)
|
||||
{
|
||||
maxHealth = npcManager.getHealth(targetName, target.getCombatLevel());
|
||||
}
|
||||
else if (target instanceof Player)
|
||||
{
|
||||
final HiscoreResult hiscoreResult = hiscoreManager.lookupAsync(targetName, HiscoreEndpoint.NORMAL);
|
||||
if (hiscoreResult != null)
|
||||
{
|
||||
final int hp = hiscoreResult.getHitpoints().getLevel();
|
||||
if (hp > 0)
|
||||
{
|
||||
maxHealth = hp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)((maxHealth * healthRatio / healthScale) + 0.5f);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
if (attackStyleVarbit == -1 || attackStyleVarbit != client.getVar(VarPlayer.ATTACK_STYLE))
|
||||
{
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit,
|
||||
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
|
||||
}
|
||||
|
||||
if (equippedWeaponTypeVarbit == -1 || equippedWeaponTypeVarbit != client.getVar(Varbits.EQUIPPED_WEAPON_TYPE))
|
||||
{
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
updateAttackStyle(equippedWeaponTypeVarbit, client.getVar(VarPlayer.ATTACK_STYLE),
|
||||
client.getVar(Varbits.DEFENSIVE_CASTING_MODE));
|
||||
}
|
||||
|
||||
if (castingModeVarbit == -1 || castingModeVarbit != client.getVar(Varbits.DEFENSIVE_CASTING_MODE))
|
||||
{
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE), client.getVar(VarPlayer.ATTACK_STYLE),
|
||||
castingModeVarbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class GroundMarkerOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DRAW_DISTANCE = 32;
|
||||
|
||||
private final Client client;
|
||||
private final GroundMarkerConfig config;
|
||||
@@ -87,12 +86,6 @@ public class GroundMarkerOverlay extends Overlay
|
||||
|
||||
private void drawTile(Graphics2D graphics, WorldPoint point, Color color)
|
||||
{
|
||||
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
|
||||
if (point.distanceTo(playerLocation) >= MAX_DRAW_DISTANCE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, point);
|
||||
if (lp == null)
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.inventoryviewer;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup(InventoryViewerPlugin.CONFIG_GROUP_KEY)
|
||||
public interface InventoryViewerConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "viewerMode",
|
||||
name = "Mode",
|
||||
description = "The mode to display the inventory viewer with"
|
||||
)
|
||||
default InventoryViewerMode viewerMode()
|
||||
{
|
||||
return InventoryViewerMode.FULL;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showFreeSlots",
|
||||
name = "Show Free Slots",
|
||||
description = "Whether to show a label with the free slots in the inventory"
|
||||
)
|
||||
default boolean showFreeSlots()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideWhenInvOpen",
|
||||
name = "Hide when inventory is open",
|
||||
description = "Hide the inventory viewer when the player's inventory is open"
|
||||
)
|
||||
default boolean hideWhenInvOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.inventoryviewer;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum InventoryViewerMode
|
||||
{
|
||||
FULL("Full"),
|
||||
GROUPED("Grouped");
|
||||
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 AWPH-I
|
||||
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -24,9 +25,12 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.inventoryviewer;
|
||||
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.Multiset;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
@@ -34,11 +38,14 @@ import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class InventoryViewerOverlay extends Overlay
|
||||
{
|
||||
@@ -49,23 +56,49 @@ class InventoryViewerOverlay extends Overlay
|
||||
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
private final InventoryViewerConfig config;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
private final PanelComponent wrapperComponent = new PanelComponent();
|
||||
private final PanelComponent inventoryComponent = new PanelComponent();
|
||||
private final TitleComponent freeSlotsComponent = TitleComponent.builder().build();
|
||||
|
||||
@Inject
|
||||
private InventoryViewerOverlay(Client client, ItemManager itemManager)
|
||||
private InventoryViewerOverlay(Client client, ItemManager itemManager, InventoryViewerConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
panelComponent.setWrapping(4);
|
||||
panelComponent.setGap(new Point(6, 4));
|
||||
panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL);
|
||||
|
||||
inventoryComponent.setWrapping(4);
|
||||
inventoryComponent.setGap(new Point(6, 4));
|
||||
inventoryComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL);
|
||||
inventoryComponent.setBackgroundColor(null);
|
||||
inventoryComponent.setBorder(new Rectangle(
|
||||
0,
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
0,
|
||||
ComponentConstants.STANDARD_BORDER));
|
||||
|
||||
wrapperComponent.setOrientation(PanelComponent.Orientation.VERTICAL);
|
||||
wrapperComponent.setWrapping(2);
|
||||
wrapperComponent.setBorder(new Rectangle(
|
||||
ComponentConstants.STANDARD_BORDER * 2,
|
||||
ComponentConstants.STANDARD_BORDER,
|
||||
ComponentConstants.STANDARD_BORDER * 2,
|
||||
ComponentConstants.STANDARD_BORDER));
|
||||
|
||||
this.itemManager = itemManager;
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.hideWhenInvOpen()
|
||||
&& client.getVar(VarClientInt.PLAYER_INVENTORY_OPENED) == 3)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY);
|
||||
|
||||
if (itemContainer == null)
|
||||
@@ -73,10 +106,50 @@ class InventoryViewerOverlay extends Overlay
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
inventoryComponent.getChildren().clear();
|
||||
wrapperComponent.getChildren().clear();
|
||||
|
||||
final Item[] items = itemContainer.getItems();
|
||||
|
||||
if (config.viewerMode() == InventoryViewerMode.GROUPED)
|
||||
{
|
||||
Multiset<Integer> totals = HashMultiset.create();
|
||||
for (Item item : items)
|
||||
{
|
||||
if (item.getId() != -1)
|
||||
{
|
||||
totals.add(item.getId(), item.getQuantity());
|
||||
}
|
||||
}
|
||||
|
||||
final long remaining = INVENTORY_SIZE - totals.size();
|
||||
if (remaining == INVENTORY_SIZE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Multiset.Entry<Integer> cursor : totals.entrySet())
|
||||
{
|
||||
final BufferedImage image = itemManager.getImage(cursor.getElement(), cursor.getCount(), true);
|
||||
if (image != null)
|
||||
{
|
||||
inventoryComponent.getChildren().add(new ImageComponent(image));
|
||||
}
|
||||
}
|
||||
wrapperComponent.getChildren().add(inventoryComponent);
|
||||
|
||||
if (config.showFreeSlots())
|
||||
{
|
||||
freeSlotsComponent.setText(remaining + " free");
|
||||
wrapperComponent.setPreferredSize(new Dimension(Math.min(totals.elementSet().size(), 4) * (PLACEHOLDER_WIDTH + 6) + ComponentConstants.STANDARD_BORDER * 2, 0));
|
||||
wrapperComponent.getChildren().add(freeSlotsComponent);
|
||||
}
|
||||
|
||||
return wrapperComponent.render(graphics);
|
||||
}
|
||||
|
||||
int remaining = 28;
|
||||
|
||||
for (int i = 0; i < INVENTORY_SIZE; i++)
|
||||
{
|
||||
if (i < items.length)
|
||||
@@ -84,20 +157,30 @@ class InventoryViewerOverlay extends Overlay
|
||||
final Item item = items[i];
|
||||
if (item.getQuantity() > 0)
|
||||
{
|
||||
remaining -= 1;
|
||||
final BufferedImage image = getImage(item);
|
||||
if (image != null)
|
||||
{
|
||||
panelComponent.getChildren().add(new ImageComponent(image));
|
||||
inventoryComponent.getChildren().add(new ImageComponent(image));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// put a placeholder image so each item is aligned properly and the panel is not resized
|
||||
panelComponent.getChildren().add(PLACEHOLDER_IMAGE);
|
||||
inventoryComponent.getChildren().add(PLACEHOLDER_IMAGE);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
wrapperComponent.getChildren().add(inventoryComponent);
|
||||
|
||||
if (config.showFreeSlots())
|
||||
{
|
||||
freeSlotsComponent.setText(remaining + " free");
|
||||
wrapperComponent.setPreferredSize(new Dimension(4 * (PLACEHOLDER_WIDTH + 6) + ComponentConstants.STANDARD_BORDER * 2, 0));
|
||||
wrapperComponent.getChildren().add(freeSlotsComponent);
|
||||
}
|
||||
|
||||
return wrapperComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getImage(Item item)
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.inventoryviewer;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
@@ -37,12 +39,20 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
||||
)
|
||||
public class InventoryViewerPlugin extends Plugin
|
||||
{
|
||||
static final String CONFIG_GROUP_KEY = "inventoryviewer";
|
||||
|
||||
@Inject
|
||||
private InventoryViewerOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Provides
|
||||
InventoryViewerConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(InventoryViewerConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
|
||||
@@ -137,13 +137,48 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
name = "Non-clan member color",
|
||||
description = "Color of non-clan member names"
|
||||
)
|
||||
default Color getNonClanMemberColor()
|
||||
default Color getNonClanMemberColor() { return Color.RED; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "drawAttackerNames",
|
||||
name = "Highlight attacker players",
|
||||
description = "Configures whether or not attacker players should be highlighted"
|
||||
)
|
||||
default boolean highlightAttackerPlayers()
|
||||
{
|
||||
return Color.RED;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
position = 11,
|
||||
keyName = "attackerColor",
|
||||
name = "Attacker player color",
|
||||
description = "Color of attacking player names"
|
||||
)
|
||||
default Color getAttackerPlayerColor() { return new Color(241, 0, 108); }
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "drawAttackableNames",
|
||||
name = "Highlight attackable players",
|
||||
description = "Configures whether or not attackable players should be highlighted"
|
||||
)
|
||||
default boolean highlightAttackablePlayers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "attackableColor",
|
||||
name = "Attackable player color",
|
||||
description = "Color of attackable player names"
|
||||
)
|
||||
default Color getAttackablePlayerColor() { return new Color(231, 122,- 0); }
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "drawPlayerTiles",
|
||||
name = "Draw tiles under players",
|
||||
description = "Configures whether or not tiles under highlighted players should be drawn"
|
||||
@@ -154,18 +189,29 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "playerNamePosition",
|
||||
name = "Name position",
|
||||
description = "Configures the position of drawn player names, or if they should be disabled"
|
||||
position = 15,
|
||||
keyName = "drawOverheadPlayerNames",
|
||||
name = "Draw names above players",
|
||||
description = "Configures whether or not player names should be drawn above players"
|
||||
)
|
||||
default PlayerNameLocation playerNamePosition()
|
||||
default boolean drawOverheadPlayerNames()
|
||||
{
|
||||
return PlayerNameLocation.ABOVE_HEAD;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
position = 16,
|
||||
keyName = "drawOverheadLevels",
|
||||
name = "Draw combat levels above players",
|
||||
description = "Configures whether or not combat levels should be drawn above players"
|
||||
)
|
||||
default boolean drawOverheadLevels()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 17,
|
||||
keyName = "drawMinimapNames",
|
||||
name = "Draw names on minimap",
|
||||
description = "Configures whether or not minimap names for players with rendered names should be drawn"
|
||||
@@ -176,7 +222,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
position = 18,
|
||||
keyName = "colorPlayerMenu",
|
||||
name = "Colorize player menu",
|
||||
description = "Color right click menu for players"
|
||||
@@ -187,7 +233,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
position = 19,
|
||||
keyName = "clanMenuIcons",
|
||||
name = "Show clan ranks",
|
||||
description = "Add clan rank to right click menu and next to player names"
|
||||
@@ -196,4 +242,109 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 20,
|
||||
keyName = "showOfflineFriends",
|
||||
name = "Show offline friends",
|
||||
description = "Draw friends names even if they're offline"
|
||||
)
|
||||
default boolean showOfflineFriends()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 21,
|
||||
keyName = "drawHighlightedNames",
|
||||
name = "Draw highlighted player names",
|
||||
description = "Configures whether or not highlighted player names should be drawn"
|
||||
)
|
||||
default boolean drawHighlightedNames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightedNames",
|
||||
name = "Highlighted names",
|
||||
description = "Clan caller names separated by a comma"
|
||||
)
|
||||
default String getHighlightedNames()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightedNamesColor",
|
||||
name = "Highlighted names color",
|
||||
description = "Color of highlighted names"
|
||||
)
|
||||
default Color getHighlightedNamesColor()
|
||||
{
|
||||
return Color.ORANGE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 22,
|
||||
keyName = "drawHighlightedTargetNames",
|
||||
name = "Draw highlighted target names",
|
||||
description = "Configures whether or not highlighted target names should be drawn"
|
||||
)
|
||||
default boolean drawHighlightedTargetNames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 23,
|
||||
keyName = "highlightedTargetColor",
|
||||
name = "Highlighted target color",
|
||||
description = "Color of highlighted target names"
|
||||
)
|
||||
default Color getHighlightedTargetColor()
|
||||
{
|
||||
return new Color(255, 100, 183);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 24,
|
||||
keyName = "limitLevel",
|
||||
name = "Limit Level",
|
||||
description = "Limit the players to show +-x your level. Useful for BH"
|
||||
)
|
||||
default boolean limitLevel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 25,
|
||||
keyName = "level",
|
||||
name = "Level",
|
||||
description = "The level to limit players shown +-x"
|
||||
)
|
||||
default int intLevel()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 26,
|
||||
keyName = "wildernessOnly",
|
||||
name = "Show only in wilderness",
|
||||
description = "Toggle whether or not to only show player indicators in the wilderness"
|
||||
)
|
||||
default boolean showInWildernessOnly()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 27,
|
||||
keyName="rightClickOverhead",
|
||||
name="Add Overheads to Right Click Menu",
|
||||
description="Feature shows a player's overhead prayer in the right click menu. Useful for DDs, or extremely crowded areas.")
|
||||
|
||||
default boolean rightClickOverhead() { return false; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2019, Jordan Atwood <nightfirecat@protonmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,6 +31,7 @@ import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
@@ -39,18 +39,17 @@ import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Singleton
|
||||
public class PlayerIndicatorsOverlay extends Overlay
|
||||
{
|
||||
private static final int ACTOR_OVERHEAD_TEXT_MARGIN = 40;
|
||||
private static final int ACTOR_HORIZONTAL_TEXT_MARGIN = 10;
|
||||
|
||||
private final PlayerIndicatorsService playerIndicatorsService;
|
||||
private final PlayerIndicatorsConfig config;
|
||||
private final ClanManager clanManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private PlayerIndicatorsOverlay(PlayerIndicatorsConfig config, PlayerIndicatorsService playerIndicatorsService,
|
||||
ClanManager clanManager)
|
||||
@@ -71,78 +70,68 @@ public class PlayerIndicatorsOverlay extends Overlay
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
final PlayerNameLocation drawPlayerNamesConfig = config.playerNamePosition();
|
||||
if (drawPlayerNamesConfig == PlayerNameLocation.DISABLED)
|
||||
if (!config.drawOverheadPlayerNames() && !config.drawOverheadLevels())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int zOffset;
|
||||
switch (drawPlayerNamesConfig)
|
||||
String namee = actor.getName().replace('\u00A0', ' ');
|
||||
String combatLevel = Integer.toString(actor.getCombatLevel());
|
||||
String playerInfo = "";
|
||||
|
||||
if (config.drawOverheadPlayerNames())
|
||||
{
|
||||
case MODEL_CENTER:
|
||||
case MODEL_RIGHT:
|
||||
zOffset = actor.getLogicalHeight() / 2;
|
||||
break;
|
||||
default:
|
||||
zOffset = actor.getLogicalHeight() + ACTOR_OVERHEAD_TEXT_MARGIN;
|
||||
playerInfo = namee;
|
||||
}
|
||||
|
||||
final String name = Text.sanitize(actor.getName());
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, name, zOffset);
|
||||
|
||||
if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT)
|
||||
if (config.drawOverheadLevels())
|
||||
{
|
||||
textLocation = actor.getCanvasTextLocation(graphics, "", zOffset);
|
||||
if (!playerInfo.isEmpty())
|
||||
{
|
||||
playerInfo = playerInfo.concat("(" + combatLevel + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
playerInfo = combatLevel;
|
||||
}
|
||||
}
|
||||
|
||||
if (textLocation == null)
|
||||
if (config.limitLevel())
|
||||
{
|
||||
if (!(client.getLocalPlayer().getCombatLevel() >= actor.getCombatLevel() - config.intLevel() && client.getLocalPlayer().getCombatLevel() <= actor.getCombatLevel() + config.intLevel()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
textLocation = new Point(textLocation.getX() + ACTOR_HORIZONTAL_TEXT_MARGIN, textLocation.getY());
|
||||
}
|
||||
|
||||
if (textLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
String name = actor.getName().replace('\u00A0', ' ') + (config.limitLevel() ? " Lvl: " + actor.getCombatLevel() : "");
|
||||
int offset = actor.getLogicalHeight() + 40;
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, playerInfo, offset);
|
||||
|
||||
if (config.showClanRanks() && actor.isClanMember())
|
||||
if (textLocation != null)
|
||||
{
|
||||
final ClanMemberRank rank = clanManager.getRank(name);
|
||||
|
||||
if (rank != ClanMemberRank.UNRANKED)
|
||||
if (config.showClanRanks() && actor.isClanMember())
|
||||
{
|
||||
final BufferedImage clanchatImage = clanManager.getClanImage(rank);
|
||||
ClanMemberRank rank = clanManager.getRank(name);
|
||||
|
||||
if (clanchatImage != null)
|
||||
if (rank != ClanMemberRank.UNRANKED)
|
||||
{
|
||||
final int clanImageWidth = clanchatImage.getWidth();
|
||||
final int clanImageTextMargin;
|
||||
final int clanImageNegativeMargin;
|
||||
BufferedImage clanchatImage = clanManager.getClanImage(rank);
|
||||
|
||||
if (drawPlayerNamesConfig == PlayerNameLocation.MODEL_RIGHT)
|
||||
if (clanchatImage != null)
|
||||
{
|
||||
clanImageTextMargin = clanImageWidth;
|
||||
clanImageNegativeMargin = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
clanImageTextMargin = clanImageWidth / 2;
|
||||
clanImageNegativeMargin = clanImageWidth / 2;
|
||||
}
|
||||
int width = clanchatImage.getWidth();
|
||||
int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent();
|
||||
Point imageLocation = new Point(textLocation.getX() - width / 2 - 1, textLocation.getY() - textHeight / 2 - clanchatImage.getHeight() / 2);
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage);
|
||||
|
||||
final int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent();
|
||||
final Point imageLocation = new Point(textLocation.getX() - clanImageNegativeMargin - 1, textLocation.getY() - textHeight / 2 - clanchatImage.getHeight() / 2);
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage);
|
||||
|
||||
// move text
|
||||
textLocation = new Point(textLocation.getX() + clanImageTextMargin, textLocation.getY());
|
||||
// move text
|
||||
textLocation = new Point(textLocation.getX() + width / 2, textLocation.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, playerInfo, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,16 @@ package net.runelite.client.plugins.playerindicators;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
|
||||
import net.runelite.api.*;
|
||||
|
||||
import static net.runelite.api.ClanMemberRank.UNRANKED;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.*;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Player;
|
||||
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
@@ -41,14 +44,25 @@ import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import com.google.common.base.Splitter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.InteractChanged;
|
||||
import net.runelite.client.util.WildcardMatcher;
|
||||
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Player Indicators",
|
||||
description = "Highlight players on-screen and/or on the minimap",
|
||||
tags = {"highlight", "minimap", "overlay", "players"}
|
||||
tags = {"highlight", "minimap", "overlay", "players"},
|
||||
type = "utility"
|
||||
)
|
||||
public class PlayerIndicatorsPlugin extends Plugin
|
||||
{
|
||||
private static final Splitter COMMA_SPLITTER = Splitter.on(Pattern.compile("\\s*,\\s*"));
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@@ -70,6 +84,8 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
@Inject
|
||||
private ClanManager clanManager;
|
||||
|
||||
private Map<String, Actor> highlightedPlayers = new HashMap<>();
|
||||
|
||||
@Provides
|
||||
PlayerIndicatorsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -82,6 +98,7 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
overlayManager.add(playerIndicatorsOverlay);
|
||||
overlayManager.add(playerIndicatorsTileOverlay);
|
||||
overlayManager.add(playerIndicatorsMinimapOverlay);
|
||||
updateHighlightList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,9 +109,60 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
overlayManager.remove(playerIndicatorsMinimapOverlay);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractChanged(InteractChanged event)
|
||||
{
|
||||
Actor actor = event.getActor();
|
||||
if (actor != null
|
||||
&& actor.getName() != null
|
||||
&& isHighlighted(actor))
|
||||
{
|
||||
highlightedPlayers.put(actor.getName().toLowerCase(), actor.getInteracting());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("playerindicators") && event.getKey().equals("highlightedNames"))
|
||||
{
|
||||
updateHighlightList();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHighlightList()
|
||||
{
|
||||
highlightedPlayers.clear();
|
||||
for (String player : COMMA_SPLITTER.splitToList(config.getHighlightedNames().toLowerCase().trim()))
|
||||
{
|
||||
highlightedPlayers.put(player, null);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isHighlighted(Actor player)
|
||||
{
|
||||
for (Map.Entry<String, Actor> map : highlightedPlayers.entrySet())
|
||||
{
|
||||
if (WildcardMatcher.matches(map.getKey(), player.getName()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isHighlightedTarget(Player player)
|
||||
{
|
||||
return highlightedPlayers.containsValue(player);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
|
||||
{
|
||||
if (config.showInWildernessOnly() && client.getVar(Varbits.IN_THE_WILDERNESS) != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int type = menuEntryAdded.getType();
|
||||
|
||||
if (type >= 2000)
|
||||
@@ -154,6 +222,37 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
{
|
||||
color = config.getNonClanMemberColor();
|
||||
}
|
||||
else if (config.drawHighlightedNames() && isHighlighted(player))
|
||||
{
|
||||
color = config.getHighlightedNamesColor();
|
||||
}
|
||||
else if (config.drawHighlightedTargetNames() && isHighlightedTarget(player))
|
||||
{
|
||||
color = config.getHighlightedTargetColor();
|
||||
}
|
||||
else if (config.highlightAttackerPlayers() && player.getInteracting() == localPlayer)
|
||||
{
|
||||
color = config.getAttackerPlayerColor();
|
||||
}
|
||||
else if (config.highlightAttackablePlayers() && isWithinLevelRange(player.getCombatLevel()))
|
||||
{
|
||||
color = config.getAttackablePlayerColor();
|
||||
}
|
||||
if (this.config.rightClickOverhead() && !player.isClanMember() && player.getOverheadIcon() != null) { // NEEDS TESTING
|
||||
if (player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) {
|
||||
image = 29;
|
||||
} else if (player.getOverheadIcon().equals((Object)HeadIcon.RANGED)) {
|
||||
image = 30;
|
||||
} else if (player.getOverheadIcon().equals((Object)HeadIcon.MELEE)) {
|
||||
image = 31;
|
||||
} else if (player.getOverheadIcon().equals((Object)HeadIcon.REDEMPTION)) {
|
||||
image = 32;
|
||||
} else if (player.getOverheadIcon().equals((Object)HeadIcon.RETRIBUTION)) {
|
||||
image = 33;
|
||||
} else if (player.getOverheadIcon().equals((Object)HeadIcon.SMITE)) {
|
||||
image = 34;
|
||||
}
|
||||
}
|
||||
|
||||
if (image != -1 || color != null)
|
||||
{
|
||||
@@ -182,4 +281,57 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWithinLevelRange(int playerCombatLevel)
|
||||
{
|
||||
Widget levelRangeWidget = client.getWidget(WidgetInfo.PVP_ATTACK_RANGE);
|
||||
Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
|
||||
int localPlayerLevel = client.getLocalPlayer().getCombatLevel();
|
||||
int lowerLevelBound = localPlayerLevel - 15;
|
||||
int upperLevelBound = localPlayerLevel + 15;
|
||||
|
||||
if (levelRangeWidget == null && wildernessLevelWidget == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden())
|
||||
{
|
||||
int wildernessLevel = calculateWildernessLevel(client.getLocalPlayer().getWorldLocation());
|
||||
lowerLevelBound = localPlayerLevel - wildernessLevel - 15;
|
||||
upperLevelBound = localPlayerLevel + wildernessLevel + 15;
|
||||
return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound);
|
||||
}
|
||||
else if (levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden())
|
||||
{
|
||||
int wildernessLevel = calculateWildernessLevel(client.getLocalPlayer().getWorldLocation());
|
||||
lowerLevelBound = localPlayerLevel - wildernessLevel;
|
||||
upperLevelBound = localPlayerLevel + wildernessLevel;
|
||||
return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound);
|
||||
}
|
||||
}
|
||||
|
||||
public static int calculateWildernessLevel(WorldPoint userLocation)
|
||||
{
|
||||
int wildernessLevel = 0;
|
||||
if (WorldPoint.isInZone(new WorldPoint(2944, 3520, 0), new WorldPoint(3391, 4351, 3), userLocation))
|
||||
{
|
||||
wildernessLevel = ((userLocation.getY() - (55 * 64)) / 8) + 1;
|
||||
}
|
||||
else if (WorldPoint.isInZone(new WorldPoint(3008, 10112, 0), new WorldPoint(3071, 10175, 3), userLocation))
|
||||
{
|
||||
wildernessLevel = ((userLocation.getY() - (155 * 64)) / 8) - 1;
|
||||
}
|
||||
else if (WorldPoint.isInZone(new WorldPoint(2944, 9920, 0), new WorldPoint(3391, 10879, 3), userLocation))
|
||||
{
|
||||
wildernessLevel = ((userLocation.getY() - (155 * 64)) / 8) + 1;
|
||||
}
|
||||
return wildernessLevel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,62 +30,96 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.Varbits;
|
||||
|
||||
|
||||
import static net.runelite.client.plugins.playerindicators.PlayerIndicatorsPlugin.calculateWildernessLevel;
|
||||
|
||||
@Singleton
|
||||
public class PlayerIndicatorsService
|
||||
{
|
||||
public class PlayerIndicatorsService {
|
||||
private final Client client;
|
||||
private final PlayerIndicatorsConfig config;
|
||||
|
||||
@Inject
|
||||
private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config)
|
||||
{
|
||||
private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config) {
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
|
||||
{
|
||||
if (!config.highlightOwnPlayer() && !config.drawClanMemberNames()
|
||||
&& !config.highlightFriends() && !config.highlightNonClanMembers())
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer) {
|
||||
|
||||
if (config.showInWildernessOnly() && client.getVar(Varbits.IN_THE_WILDERNESS) != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.highlightOwnPlayer() && !config.drawClanMemberNames()
|
||||
&& !config.highlightFriends() && !config.highlightNonClanMembers()
|
||||
&& !config.highlightAttackablePlayers() && !config.highlightAttackerPlayers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
if (player == null || player.getName() == null)
|
||||
{
|
||||
for (Player player : client.getPlayers()) {
|
||||
if (player == null || player.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isClanMember = player.isClanMember();
|
||||
|
||||
if (player == localPlayer)
|
||||
{
|
||||
if (config.highlightOwnPlayer())
|
||||
{
|
||||
if (player == localPlayer) {
|
||||
if (config.highlightOwnPlayer()) {
|
||||
consumer.accept(player, config.getOwnPlayerColor());
|
||||
}
|
||||
}
|
||||
else if (config.highlightFriends() && player.isFriend())
|
||||
{
|
||||
} else if (config.highlightFriends() && player.isFriend()) {
|
||||
consumer.accept(player, config.getFriendColor());
|
||||
}
|
||||
else if (config.drawClanMemberNames() && isClanMember)
|
||||
{
|
||||
} else if (config.drawClanMemberNames() && isClanMember) {
|
||||
consumer.accept(player, config.getClanMemberColor());
|
||||
}
|
||||
else if (config.highlightTeamMembers() && localPlayer.getTeam() > 0 && localPlayer.getTeam() == player.getTeam())
|
||||
{
|
||||
} else if (config.highlightTeamMembers() && localPlayer.getTeam() > 0 && localPlayer.getTeam() == player.getTeam()) {
|
||||
consumer.accept(player, config.getTeamMemberColor());
|
||||
}
|
||||
else if (config.highlightNonClanMembers() && !isClanMember)
|
||||
{
|
||||
} else if (config.highlightNonClanMembers() && !isClanMember) {
|
||||
consumer.accept(player, config.getNonClanMemberColor());
|
||||
}
|
||||
} else if (config.highlightAttackerPlayers() && player.getInteracting() == localPlayer) {
|
||||
consumer.accept(player, config.getAttackerPlayerColor());
|
||||
} else if (config.highlightAttackablePlayers() && isWithinLevelRange(player.getCombatLevel())) {
|
||||
consumer.accept(player, config.getAttackablePlayerColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWithinLevelRange(int playerCombatLevel)
|
||||
{
|
||||
Widget levelRangeWidget = client.getWidget(WidgetInfo.PVP_ATTACK_RANGE);
|
||||
Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||
|
||||
int localPlayerLevel = client.getLocalPlayer().getCombatLevel();
|
||||
int lowerLevelBound = localPlayerLevel - 15;
|
||||
int upperLevelBound = localPlayerLevel + 15;
|
||||
|
||||
if (levelRangeWidget == null && wildernessLevelWidget == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden())
|
||||
{
|
||||
lowerLevelBound = Integer.parseInt(levelRangeWidget.getText().split("-")[0]);
|
||||
upperLevelBound = Integer.parseInt(levelRangeWidget.getText().split("-")[1]);
|
||||
return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound);
|
||||
}
|
||||
else if (levelRangeWidget.isHidden() && !wildernessLevelWidget.isHidden())
|
||||
{
|
||||
int wildernessLevel = calculateWildernessLevel(client.getLocalPlayer().getWorldLocation());
|
||||
lowerLevelBound = localPlayerLevel - wildernessLevel;
|
||||
upperLevelBound = localPlayerLevel + wildernessLevel;
|
||||
return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (playerCombatLevel >= lowerLevelBound && playerCombatLevel <= upperLevelBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.skybox;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@@ -447,7 +448,7 @@ class Skybox
|
||||
}
|
||||
|
||||
// Convert back to int range values, and bounds check while we are at it
|
||||
byte ay = (byte) Math.min(Math.max(Math.round(Math.pow(ty / t, brightness) * 255.d), 0), 255);
|
||||
byte ay = (byte) Math.min(Math.max(Math.round(ty / t * 255.d), 0), 255);
|
||||
byte aco = (byte) Math.min(Math.max(Math.round(tco * 128.d / t), -128), 127);
|
||||
byte acg = (byte) Math.min(Math.max(Math.round(tcg * 128.d / t), -128), 127);
|
||||
|
||||
@@ -457,7 +458,11 @@ class Skybox
|
||||
int r = (tmp - (aco >> 1)) & 0xFF;
|
||||
int b = (r + aco) & 0xFF;
|
||||
|
||||
return r << 16 | g << 8 | b;
|
||||
// increase brightness with HSB
|
||||
float[] hsb = Color.RGBtoHSB(r, g, b, null);
|
||||
hsb[2] = (float) Math.pow(hsb[2], brightness);
|
||||
|
||||
return 0xFFFFFF & Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
package net.runelite.client.plugins.vanguards;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.game.NPCManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
import net.runelite.client.plugins.opponentinfo.OpponentInfoPlugin;
|
||||
//import net.runelite.client.plugins.opponentinfo.OpponentInfoOverlay;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class VanguardOverlay extends Overlay {
|
||||
|
||||
private VanguardPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
private static final int MAGE_VANGUARD_ID = 7529;
|
||||
private static final int RANGE_VANGUARD_ID = 7528;
|
||||
private static final int MELEE_VANGUARD_ID = 7527;
|
||||
//private final NPCManager npcManager;
|
||||
|
||||
private int mageHp = -1;
|
||||
private float magePercent = 0;
|
||||
|
||||
private int rangeHp = -1;
|
||||
private float rangePercent = 0;
|
||||
|
||||
private int meleeHp = -1;
|
||||
private float meleePercent = 0;
|
||||
|
||||
public String right_mage_str, right_range_str, right_melee_str = "";
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
|
||||
@Inject
|
||||
public VanguardOverlay(VanguardPlugin plugin) {
|
||||
super(plugin);//?
|
||||
this.plugin = plugin;
|
||||
|
||||
setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT);
|
||||
//this.opponentInfoPlugin = opponentInfoPlugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Player p = client.getLocalPlayer(); //local player aka me
|
||||
Actor opponent = p.getInteracting(); //get entity i am interacting with
|
||||
//how to find its Id since it's an Actor not NPC specifically
|
||||
//if(opponent.getName().equals("Vanguard") && opponent.getHealth() > 0)//might wana double check the name
|
||||
//{
|
||||
if(opponent instanceof NPC)
|
||||
{
|
||||
int id = ((NPC) opponent).getId();
|
||||
String name = opponent.getName();
|
||||
|
||||
if(id == MAGE_VANGUARD_ID) //maybe check name.equals("Vanguard")
|
||||
{
|
||||
magePercent = (float)opponent.getHealthRatio() / opponent.getHealth() * 100;
|
||||
mageHp = (int)magePercent;
|
||||
right_mage_str = Integer.toString(mageHp);
|
||||
System.out.println("mager");
|
||||
}
|
||||
else if (id == RANGE_VANGUARD_ID)
|
||||
{
|
||||
rangePercent = (float)opponent.getHealthRatio() / opponent.getHealth() * 100;
|
||||
rangeHp = (int)rangePercent;
|
||||
right_range_str = Integer.toString(rangeHp);
|
||||
|
||||
System.out.println("ranger");
|
||||
}
|
||||
else if (id == MELEE_VANGUARD_ID)
|
||||
{
|
||||
meleePercent = (float)opponent.getHealthRatio()/opponent.getHealth() * 100;
|
||||
meleeHp = (int)meleePercent;
|
||||
right_melee_str = Integer.toString(meleeHp);
|
||||
|
||||
|
||||
System.out.println("meleer");
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
//if (opponent == null) {
|
||||
//}
|
||||
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
String overlayTitle = "Vanguard HP";
|
||||
//title
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text(overlayTitle).color(Color.RED).build());
|
||||
|
||||
//size (width)
|
||||
panelComponent.setPreferredSize(new Dimension(graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0));
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Mage:").right(right_mage_str).build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Range:").right(right_range_str).build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder().left("Melee:").right(right_melee_str).build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
package net.runelite.client.plugins.vanguards;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name= "Vanguard HP Overlay",
|
||||
description= "tracks HP of all three vanguards",
|
||||
tags= {"overlay", "vangs", "cox"},
|
||||
enabledByDefault = false,
|
||||
type = "PVM"
|
||||
)
|
||||
public class VanguardPlugin extends Plugin {
|
||||
private static final int MAGE_VANGUARD_ID = 7526; //i think
|
||||
private static final int RANGE_VANGUARD_ID = 7527;
|
||||
private static final int MELEE_VANGUARD_ID = 7528;
|
||||
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private VanguardOverlay overlay;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
overlay.right_mage_str = "-";
|
||||
overlay.right_range_str = "-";
|
||||
overlay.right_melee_str = "-";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -112,4 +112,15 @@ public interface WorldHopperConfig extends Config
|
||||
{
|
||||
return SubscriptionFilterMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHistory",
|
||||
name = "Show history tab",
|
||||
description = "Shows the history tab",
|
||||
position = 5
|
||||
)
|
||||
default boolean showHistory()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +258,49 @@ public class WorldHopperPlugin extends Plugin
|
||||
panel.setFilterMode(config.subscriptionFilter());
|
||||
updateList();
|
||||
break;
|
||||
case "showHistory":
|
||||
panel.updateLayout();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean showHistory()
|
||||
{
|
||||
return config.showHistory();
|
||||
}
|
||||
|
||||
Map<String, String> getHistory()
|
||||
{
|
||||
Map<String, String> history = configManager.getConfiguration(WorldHopperConfig.GROUP, "history", Map.class);
|
||||
if (history == null)
|
||||
{
|
||||
history = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
void clearHistory()
|
||||
{
|
||||
Map<String, String> history = getHistory();
|
||||
history.clear();
|
||||
configManager.setConfiguration(WorldHopperConfig.GROUP, "history", history);
|
||||
}
|
||||
|
||||
void addToHistory()
|
||||
{
|
||||
addToHistory(client.getWorld());
|
||||
}
|
||||
|
||||
void addToHistory(int world)
|
||||
{
|
||||
long unixTime = System.currentTimeMillis() / 1000L;
|
||||
Map<String, String> history = getHistory();
|
||||
history.put(String.valueOf(world), String.valueOf(unixTime));
|
||||
configManager.setConfiguration(WorldHopperConfig.GROUP, "history", history);
|
||||
}
|
||||
|
||||
private void setFavoriteConfig(int world)
|
||||
{
|
||||
configManager.setConfiguration(WorldHopperConfig.GROUP, "favorite_" + world, true);
|
||||
@@ -408,6 +447,12 @@ public class WorldHopperPlugin extends Plugin
|
||||
lastWorld = newWorld;
|
||||
}
|
||||
}
|
||||
|
||||
if (gameStateChanged.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
addToHistory(client.getWorld());
|
||||
panel.updateList();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -644,6 +689,8 @@ public class WorldHopperPlugin extends Plugin
|
||||
|
||||
quickHopTargetWorld = rsWorld;
|
||||
displaySwitcherAttempts = 0;
|
||||
|
||||
addToHistory(worldId);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,12 +31,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
@@ -121,7 +116,7 @@ class WorldTableHeader extends JPanel
|
||||
|
||||
add(textLabel, BorderLayout.WEST);
|
||||
add(arrowLabel, BorderLayout.EAST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The labels inherit the parent's mouse listeners.
|
||||
|
||||
@@ -96,6 +96,7 @@ class WorldTableRow extends JPanel
|
||||
this.world = world;
|
||||
this.onFavorite = onFavorite;
|
||||
this.updatedPlayerCount = world.getPlayers();
|
||||
this.
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(2, 0, 2, 0));
|
||||
|
||||
@@ -46,10 +46,8 @@ enum QuestStartLocation
|
||||
THE_RESTLESS_GHOST("The Restless Ghost", new WorldPoint(3240, 3210, 0)),
|
||||
RUNE_MYSTERIES("Rune Mysteries", new WorldPoint(3210, 3220, 0)),
|
||||
SHEEP_SHEARER("Sheep Shearer", new WorldPoint(3190, 3272, 0)),
|
||||
|
||||
SHIELD_OF_ARRAV_PHOENIX_GANG("Shield of Arrav (Phoenix Gang)", new WorldPoint(3208, 3495, 0)),
|
||||
SHIELD_OF_ARRAV_BLACK_ARM_GANG("Shield of Arrav (Black Arm Gang)", new WorldPoint(3208, 3392, 0)),
|
||||
|
||||
VAMPIRE_SLAYER("Vampire Slayer", new WorldPoint(3096, 3266, 0)),
|
||||
WITCHS_POTION("Witch's Potion", new WorldPoint(2967, 3203, 0)),
|
||||
X_MARKS_THE_SPOT("X Marks the Spot", new WorldPoint(3227, 3242, 0)),
|
||||
|
||||
Reference in New Issue
Block a user