* 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:
James
2019-04-20 12:06:29 -07:00
committed by Tyler Bochard
parent bb76873678
commit c0bc66fb9c
35 changed files with 2208 additions and 545 deletions

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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),

View File

@@ -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),

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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)

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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)

View File

@@ -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()
{

View File

@@ -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; }
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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]);
}
/**

View File

@@ -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);
}
}

View File

@@ -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 = "-";
}
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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));

View File

@@ -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)),