Merge pull request #1154 from deathbeam/team-member-names
Enhance player indicators plugin
@@ -300,6 +300,11 @@ public class Instructions
|
||||
add(ITEM_PRICE, "item_price", 1, 0);
|
||||
add(SEND_BUG_REPORT, "send_bug_report", 1, 0, 2, 0);
|
||||
add(SET_SHIFT_DROP_ENABLED, "set_shift_drop_enabled", 1, 0);
|
||||
add(SET_DRAW_FRIEND_NAME, "set_draw_friend_name", 1, 0);
|
||||
add(SET_DRAW_CLAN_NAME, "set_draw_clan_name", 1, 0);
|
||||
add(SET_DRAW_ALL_EXCEPT_OWN_NAME, "set_draw_all_except_own_name", 1, 0);
|
||||
add(SET_DRAW_OWN_NAME, "set_draw_own_name", 1, 0);
|
||||
add(SET_DRAW_NO_NAMES, "set_draw_no_names", 1, 0);
|
||||
// 3200-3300
|
||||
add(PLAY_SOUND_EFFECT, "play_sound_effect", 3, 0);
|
||||
add(3201, 1, 0);
|
||||
|
||||
@@ -238,6 +238,11 @@ public class Opcodes
|
||||
public static final int ITEM_PRICE = 3115;
|
||||
public static final int SEND_BUG_REPORT = 3116;
|
||||
public static final int SET_SHIFT_DROP_ENABLED = 3117;
|
||||
public static final int SET_DRAW_FRIEND_NAME = 3120;
|
||||
public static final int SET_DRAW_CLAN_NAME = 3121;
|
||||
public static final int SET_DRAW_ALL_EXCEPT_OWN_NAME = 3122;
|
||||
public static final int SET_DRAW_OWN_NAME = 3123;
|
||||
public static final int SET_DRAW_NO_NAMES = 3124;
|
||||
public static final int PLAY_SOUND_EFFECT = 3200;
|
||||
public static final int GET_GAMECYCLE = 3300;
|
||||
public static final int GET_ITEMCONTAINER_ITEMID = 3301;
|
||||
|
||||
@@ -350,4 +350,8 @@ public interface Client extends GameEngine
|
||||
World createWorld();
|
||||
|
||||
SpritePixels drawInstanceMap(int z);
|
||||
|
||||
void setPlayerNameMask(int mask);
|
||||
|
||||
int getPlayerNameMask();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ public interface Player extends Actor
|
||||
@Override
|
||||
int getCombatLevel();
|
||||
|
||||
String getCleanName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
PlayerComposition getPlayerComposition();
|
||||
|
||||
Polygon[] getPolygons();
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.api;
|
||||
|
||||
public class PlayerNameMask
|
||||
{
|
||||
public static final int DRAW_FRIEND_NAME = 1;
|
||||
public static final int DRAW_CLAN_NAME = 2;
|
||||
public static final int DRAW_ALL_EXCEPT_OWN_NAME = 4;
|
||||
public static final int DRAW_OWN_NAME = 8;
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.util;
|
||||
package net.runelite.api;
|
||||
|
||||
/**
|
||||
* A set of utilities to use when dealing with text.
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.api.events;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class ClanChanged
|
||||
{
|
||||
private boolean joined;
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.clanchat;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.ClanMember;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.SetMessage;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.task.Schedule;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Clan Chat"
|
||||
)
|
||||
@Slf4j
|
||||
public class ClanChatPlugin extends Plugin
|
||||
{
|
||||
private static final String[] CLANCHAT_IMAGES =
|
||||
{
|
||||
"Friend_clan_rank.png", "Recruit_clan_rank.png",
|
||||
"Corporal_clan_rank.png", "Sergeant_clan_rank.png",
|
||||
"Lieutenant_clan_rank.png", "Captain_clan_rank.png",
|
||||
"General_clan_rank.png", "Owner_clan_rank.png"
|
||||
};
|
||||
|
||||
|
||||
private final LoadingCache<String, ClanMemberRank> clanRanksCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(100)
|
||||
.expireAfterAccess(1, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<String, ClanMemberRank>()
|
||||
{
|
||||
@Override
|
||||
public ClanMemberRank load(String key) throws Exception
|
||||
{
|
||||
final ClanMember[] clanMembersArr = client.getClanMembers();
|
||||
|
||||
if (clanMembersArr == null || clanMembersArr.length == 0)
|
||||
{
|
||||
return ClanMemberRank.UNRANKED;
|
||||
}
|
||||
|
||||
return Arrays.stream(clanMembersArr)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(clanMember -> sanitize(clanMember.getUsername()).equals(sanitize(key)))
|
||||
.map(ClanMember::getRank)
|
||||
.findAny()
|
||||
.orElse(ClanMemberRank.UNRANKED);
|
||||
}
|
||||
});
|
||||
|
||||
private int modIconsLength;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
if (modIconsLength == 0 && client.getGameState().compareTo(GameState.LOGIN_SCREEN) >= 0)
|
||||
{
|
||||
loadClanChatIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
clanRanksCache.invalidateAll();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN
|
||||
&& modIconsLength == 0)
|
||||
{
|
||||
// this is after "Loading sprites" so we can modify modicons now
|
||||
loadClanChatIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@Schedule(
|
||||
period = 600,
|
||||
unit = ChronoUnit.MILLIS
|
||||
)
|
||||
public void updateClanChatTitle()
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget clanChatTitleWidget = client.getWidget(WidgetInfo.CLAN_CHAT_TITLE);
|
||||
if (clanChatTitleWidget != null)
|
||||
{
|
||||
clanChatTitleWidget.setText("Clan Chat (" + client.getClanChatCount() + "/100)");
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSetMessage(SetMessage setMessage)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (setMessage.getType() == ChatMessageType.CLANCHAT && client.getClanChatCount() > 0)
|
||||
{
|
||||
insertClanRankIcon(setMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadClanChatIcons()
|
||||
{
|
||||
try
|
||||
{
|
||||
final IndexedSprite[] modIcons = client.getModIcons();
|
||||
final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + CLANCHAT_IMAGES.length);
|
||||
int curPosition = newModIcons.length - CLANCHAT_IMAGES.length;
|
||||
|
||||
for (String resource : CLANCHAT_IMAGES)
|
||||
{
|
||||
IndexedSprite sprite = createIndexedSprite(resource);
|
||||
newModIcons[curPosition++] = sprite;
|
||||
}
|
||||
|
||||
client.setModIcons(newModIcons);
|
||||
modIconsLength = newModIcons.length;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Failed loading of clan chat icons", e);
|
||||
}
|
||||
}
|
||||
|
||||
private IndexedSprite createIndexedSprite(final String imagePath) throws IOException
|
||||
{
|
||||
final BufferedImage bufferedImage = rgbaToIndexedBufferedImage(ImageIO
|
||||
.read(this.getClass().getResource(imagePath)));
|
||||
|
||||
final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel();
|
||||
|
||||
final int width = bufferedImage.getWidth();
|
||||
final int height = bufferedImage.getHeight();
|
||||
final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
|
||||
final int[] palette = new int[indexedCM.getMapSize()];
|
||||
indexedCM.getRGBs(palette);
|
||||
|
||||
final IndexedSprite newIndexedSprite = client.createIndexedSprite();
|
||||
newIndexedSprite.setPixels(pixels);
|
||||
newIndexedSprite.setPalette(palette);
|
||||
newIndexedSprite.setWidth(width);
|
||||
newIndexedSprite.setHeight(height);
|
||||
newIndexedSprite.setOriginalWidth(width);
|
||||
newIndexedSprite.setOriginalHeight(height);
|
||||
newIndexedSprite.setOffsetX(0);
|
||||
newIndexedSprite.setOffsetY(0);
|
||||
return newIndexedSprite;
|
||||
}
|
||||
|
||||
private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage)
|
||||
{
|
||||
final BufferedImage indexedImage = new BufferedImage(
|
||||
sourceBufferedImage.getWidth(),
|
||||
sourceBufferedImage.getHeight(),
|
||||
BufferedImage.TYPE_BYTE_INDEXED);
|
||||
|
||||
final ColorModel cm = indexedImage.getColorModel();
|
||||
final IndexColorModel icm = (IndexColorModel) cm;
|
||||
|
||||
final int size = icm.getMapSize();
|
||||
final byte[] reds = new byte[size];
|
||||
final byte[] greens = new byte[size];
|
||||
final byte[] blues = new byte[size];
|
||||
icm.getReds(reds);
|
||||
icm.getGreens(greens);
|
||||
icm.getBlues(blues);
|
||||
|
||||
final WritableRaster raster = indexedImage.getRaster();
|
||||
final int pixel = raster.getSample(0, 0, 0);
|
||||
final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel);
|
||||
final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
|
||||
resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
|
||||
return resultIndexedImage;
|
||||
}
|
||||
|
||||
private void insertClanRankIcon(final SetMessage message)
|
||||
{
|
||||
final String playerName = sanitize(message.getName());
|
||||
final ClanMemberRank rank = clanRanksCache.getUnchecked(playerName);
|
||||
|
||||
if (rank != null && rank != ClanMemberRank.UNRANKED)
|
||||
{
|
||||
int iconNumber = getIconNumber(rank);
|
||||
message.getMessageNode()
|
||||
.setSender(message.getMessageNode().getSender() + " <img=" + iconNumber + ">");
|
||||
client.refreshChat();
|
||||
}
|
||||
}
|
||||
|
||||
private int getIconNumber(final ClanMemberRank clanMemberRank)
|
||||
{
|
||||
return modIconsLength - CLANCHAT_IMAGES.length + clanMemberRank.getValue();
|
||||
}
|
||||
|
||||
private static String sanitize(String lookup)
|
||||
{
|
||||
final String cleaned = lookup.contains("<img") ? lookup.substring(lookup.lastIndexOf('>') + 1) : lookup;
|
||||
return cleaned.replace('\u00A0', ' ');
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.SwingUtilities;
|
||||
import net.runelite.api.Text;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.PlayerMenuOptionClicked;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
@@ -138,7 +139,7 @@ public class HiscorePlugin extends Plugin
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
hiscorePanel.lookup(event.getMenuTarget());
|
||||
hiscorePanel.lookup(Text.removeTags(event.getMenuTarget()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Text;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.PostItemComposition;
|
||||
@@ -52,7 +53,6 @@ import net.runelite.client.menus.WidgetMenuOption;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Menu Entry Swapper",
|
||||
|
||||
@@ -39,7 +39,7 @@ import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Nightmare Zone"
|
||||
|
||||
@@ -45,7 +45,7 @@ import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.BackgroundComponent;
|
||||
import net.runelite.client.ui.overlay.components.TextComponent;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.Text;
|
||||
|
||||
class OpponentInfoOverlay extends Overlay
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
)
|
||||
default Color getOwnNameColor()
|
||||
{
|
||||
return new Color(0, 184, 212);
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
@@ -104,28 +104,50 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "drawNonClanMemberNames",
|
||||
name = "Draw non-clan member names",
|
||||
description = "Configures whether or not names of non-clan members should be drawn"
|
||||
keyName = "drawTeamMemberNames",
|
||||
name = "Draw team member names",
|
||||
description = "Configures whether or not names of player's team members should be drawn"
|
||||
)
|
||||
default boolean drawNonClanMemberNames()
|
||||
default boolean drawTeamMemberNames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "nonClanMemberColor",
|
||||
name = "Non-clan member color",
|
||||
description = "Color of non-clan member names"
|
||||
keyName = "teamMemberColor",
|
||||
name = "Team member color",
|
||||
description = "Color of team member names"
|
||||
)
|
||||
default Color getNonClanMemberColor()
|
||||
default Color getTeamMemberColor()
|
||||
{
|
||||
return Color.RED;
|
||||
return new Color(19, 110, 247);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "drawOthers",
|
||||
name = "Draw names of others",
|
||||
description = "Configures whether or not names of everyone except you should be drawn"
|
||||
)
|
||||
default boolean drawNonOwnNames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "nonClanMemberColor",
|
||||
name = "Non-clan member color",
|
||||
description = "Color of non-clan member names"
|
||||
)
|
||||
default Color getNonOwnColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "drawPlayerTiles",
|
||||
name = "Draw tiles",
|
||||
description = "Configures whether or not tiles under players with rendered names should be drawn"
|
||||
@@ -136,7 +158,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
position = 11,
|
||||
keyName = "drawMinimapNames",
|
||||
name = "Draw names on minimap",
|
||||
description = "Configures whether or not minimap names for players with rendered names should be drawn"
|
||||
@@ -145,4 +167,15 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "showClanRankIcons",
|
||||
name = "Show clan member rank icons next to names",
|
||||
description = "Configures whether or not icons representing rank are shown next to player names"
|
||||
)
|
||||
default boolean showClanRankIcons()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,22 +55,22 @@ public class PlayerIndicatorsMinimapOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
playerIndicatorsService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
if (config.drawMinimapNames())
|
||||
{
|
||||
playerIndicatorsService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
final String name = actor.getName().replace('\u00A0', ' ');
|
||||
final String name = actor.getName();
|
||||
final net.runelite.api.Point minimapLocation = actor.getMinimapLocation();
|
||||
|
||||
if (config.drawMinimapNames())
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
final net.runelite.api.Point minimapLocation = actor.getMinimapLocation();
|
||||
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
@@ -47,35 +48,29 @@ public class PlayerIndicatorsOverlay extends Overlay
|
||||
{
|
||||
this.config = config;
|
||||
this.playerIndicatorsService = playerIndicatorsService;
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
playerIndicatorsService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
if (config.drawTiles())
|
||||
{
|
||||
playerIndicatorsService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
if (config.drawTiles())
|
||||
{
|
||||
Polygon poly = actor.getCanvasTilePoly();
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
}
|
||||
Polygon poly = actor.getCanvasTilePoly();
|
||||
|
||||
final String name = actor.getName().replace('\u00A0', ' ');
|
||||
net.runelite.api.Point textLocation = actor
|
||||
.getCanvasTextLocation(graphics, name, actor.getLogicalHeight() + 40);
|
||||
|
||||
if (textLocation != null)
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,24 @@
|
||||
package net.runelite.client.plugins.playerindicators;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collection;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.ClanChanged;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.SetMessage;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
|
||||
@PluginDescriptor(
|
||||
@@ -38,12 +50,18 @@ import net.runelite.client.ui.overlay.Overlay;
|
||||
)
|
||||
public class PlayerIndicatorsPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private PlayerIndicatorsOverlay playerIndicatorsOverlay;
|
||||
|
||||
@Inject
|
||||
private PlayerIndicatorsMinimapOverlay playerIndicatorsMinimapOverlay;
|
||||
|
||||
@Inject
|
||||
private PlayerIndicatorsService playerIndicatorsService;
|
||||
|
||||
@Provides
|
||||
PlayerIndicatorsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -55,4 +73,78 @@ public class PlayerIndicatorsPlugin extends Plugin
|
||||
{
|
||||
return Sets.newHashSet(playerIndicatorsOverlay, playerIndicatorsMinimapOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
playerIndicatorsService.invalidatePlayerNames();
|
||||
playerIndicatorsService.updateConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
playerIndicatorsService.invalidatePlayerNames();
|
||||
playerIndicatorsService.invalidateClanRanksCache();
|
||||
client.setPlayerNameMask(0);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("playerindicators"))
|
||||
{
|
||||
playerIndicatorsService.invalidatePlayerNames();
|
||||
playerIndicatorsService.updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
playerIndicatorsService.updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onClanChanged(ClanChanged event)
|
||||
{
|
||||
playerIndicatorsService.invalidateClanRanksCache();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSetMessage(SetMessage setMessage)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOADING && client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (setMessage.getType() == ChatMessageType.CLANCHAT && client.getClanChatCount() > 0)
|
||||
{
|
||||
playerIndicatorsService.insertClanRankIcon(setMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Schedule(
|
||||
period = 1,
|
||||
unit = ChronoUnit.SECONDS
|
||||
)
|
||||
public void updatePlayerNames()
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Widget clanChatTitleWidget = client.getWidget(WidgetInfo.CLAN_CHAT_TITLE);
|
||||
if (clanChatTitleWidget != null)
|
||||
{
|
||||
clanChatTitleWidget.setText("Clan Chat (" + client.getClanChatCount() + "/100)");
|
||||
}
|
||||
|
||||
playerIndicatorsService.updatePlayers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,18 +24,74 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.playerindicators;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ClanMember;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.PlayerNameMask;
|
||||
import net.runelite.api.events.SetMessage;
|
||||
import net.runelite.api.Text;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class PlayerIndicatorsService
|
||||
{
|
||||
private static final String[] CLANCHAT_IMAGES =
|
||||
{
|
||||
"Friend_clan_rank.png", "Recruit_clan_rank.png",
|
||||
"Corporal_clan_rank.png", "Sergeant_clan_rank.png",
|
||||
"Lieutenant_clan_rank.png", "Captain_clan_rank.png",
|
||||
"General_clan_rank.png", "Owner_clan_rank.png"
|
||||
};
|
||||
|
||||
private final LoadingCache<String, ClanMemberRank> clanRanksCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(100)
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
.build(new CacheLoader<String, ClanMemberRank>()
|
||||
{
|
||||
@Override
|
||||
public ClanMemberRank load(@Nonnull String key)
|
||||
{
|
||||
final ClanMember[] clanMembersArr = client.getClanMembers();
|
||||
|
||||
if (clanMembersArr == null || clanMembersArr.length == 0)
|
||||
{
|
||||
return ClanMemberRank.UNRANKED;
|
||||
}
|
||||
|
||||
return Arrays.stream(clanMembersArr)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(clanMember -> clanMember.getUsername().equals(key))
|
||||
.map(ClanMember::getRank)
|
||||
.findAny()
|
||||
.orElse(ClanMemberRank.UNRANKED);
|
||||
}
|
||||
});
|
||||
|
||||
private final Client client;
|
||||
private final PlayerIndicatorsConfig config;
|
||||
private int modIconsLength;
|
||||
|
||||
@Inject
|
||||
private PlayerIndicatorsService(Client client, PlayerIndicatorsConfig config)
|
||||
@@ -44,13 +100,70 @@ public class PlayerIndicatorsService
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void invalidatePlayerNames()
|
||||
{
|
||||
// Reset player names
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
if (player != null && player.getName() != null)
|
||||
{
|
||||
player.setName(player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh chat box
|
||||
client.refreshChat();
|
||||
}
|
||||
|
||||
public void invalidateClanRanksCache()
|
||||
{
|
||||
// Invalidate clan cache
|
||||
clanRanksCache.invalidateAll();
|
||||
}
|
||||
|
||||
public void updateConfig()
|
||||
{
|
||||
// Update mod icons
|
||||
if (modIconsLength == 0 && client.getGameState().compareTo(GameState.LOGGED_IN) >= 0)
|
||||
{
|
||||
loadClanChatIcons();
|
||||
}
|
||||
|
||||
// Update mask
|
||||
int baseMask = 0;
|
||||
|
||||
if (config.drawFriendNames())
|
||||
{
|
||||
baseMask |= PlayerNameMask.DRAW_FRIEND_NAME;
|
||||
}
|
||||
|
||||
if (config.drawClanMemberNames())
|
||||
{
|
||||
baseMask |= PlayerNameMask.DRAW_CLAN_NAME;
|
||||
}
|
||||
|
||||
if (config.drawOwnName())
|
||||
{
|
||||
baseMask |= PlayerNameMask.DRAW_OWN_NAME;
|
||||
}
|
||||
|
||||
if (config.drawNonOwnNames())
|
||||
{
|
||||
baseMask |= PlayerNameMask.DRAW_ALL_EXCEPT_OWN_NAME;
|
||||
}
|
||||
|
||||
client.setPlayerNameMask(baseMask);
|
||||
}
|
||||
|
||||
public void updatePlayers()
|
||||
{
|
||||
// Update player names
|
||||
forEachPlayer(this::injectData);
|
||||
}
|
||||
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
|
||||
{
|
||||
if (!config.drawOwnName() && !config.drawClanMemberNames()
|
||||
&& !config.drawFriendNames() && !config.drawNonClanMemberNames())
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
@@ -61,7 +174,7 @@ public class PlayerIndicatorsService
|
||||
|
||||
boolean isClanMember = player.isClanMember();
|
||||
|
||||
if (player == client.getLocalPlayer())
|
||||
if (player == localPlayer)
|
||||
{
|
||||
if (config.drawOwnName())
|
||||
{
|
||||
@@ -76,10 +189,139 @@ public class PlayerIndicatorsService
|
||||
{
|
||||
consumer.accept(player, config.getClanMemberColor());
|
||||
}
|
||||
else if (config.drawNonClanMemberNames() && !isClanMember)
|
||||
else if (config.drawTeamMemberNames() && localPlayer.getTeam() > 0 && localPlayer.getTeam() == player.getTeam())
|
||||
{
|
||||
consumer.accept(player, config.getNonClanMemberColor());
|
||||
consumer.accept(player, config.getTeamMemberColor());
|
||||
}
|
||||
else if (config.drawNonOwnNames())
|
||||
{
|
||||
consumer.accept(player, config.getNonOwnColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void insertClanRankIcon(final SetMessage message)
|
||||
{
|
||||
if (!config.showClanRankIcons())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String playerName = Text.removeTags(message.getName());
|
||||
final ClanMemberRank rank = clanRanksCache.getUnchecked(playerName);
|
||||
|
||||
if (rank != null && rank != ClanMemberRank.UNRANKED)
|
||||
{
|
||||
int iconNumber = getIconNumber(rank);
|
||||
message.getMessageNode()
|
||||
.setSender(message.getMessageNode().getSender() + " <img=" + iconNumber + ">");
|
||||
client.refreshChat();
|
||||
}
|
||||
}
|
||||
|
||||
private void injectData(final Player player, final Color color)
|
||||
{
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
final String playerName = player.getName();
|
||||
|
||||
if (config.showClanRankIcons() && player.isClanMember())
|
||||
{
|
||||
final ClanMemberRank clanMemberRank = clanRanksCache.getUnchecked(playerName);
|
||||
|
||||
if (clanMemberRank != ClanMemberRank.UNRANKED)
|
||||
{
|
||||
stringBuilder
|
||||
.append("<img=")
|
||||
.append(getIconNumber(clanMemberRank))
|
||||
.append(">");
|
||||
}
|
||||
}
|
||||
|
||||
stringBuilder.append("<col=").append(parseColor(color)).append(">");
|
||||
player.setName(stringBuilder.toString() + playerName);
|
||||
}
|
||||
|
||||
private static String parseColor(final Color color)
|
||||
{
|
||||
return String.format("%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue());
|
||||
}
|
||||
|
||||
private void loadClanChatIcons()
|
||||
{
|
||||
try
|
||||
{
|
||||
final IndexedSprite[] modIcons = client.getModIcons();
|
||||
final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + CLANCHAT_IMAGES.length);
|
||||
int curPosition = newModIcons.length - CLANCHAT_IMAGES.length;
|
||||
|
||||
for (String resource : CLANCHAT_IMAGES)
|
||||
{
|
||||
IndexedSprite sprite = createIndexedSprite(resource);
|
||||
newModIcons[curPosition++] = sprite;
|
||||
}
|
||||
|
||||
client.setModIcons(newModIcons);
|
||||
modIconsLength = newModIcons.length;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn("Failed loading of clan chat icons", e);
|
||||
}
|
||||
}
|
||||
|
||||
private IndexedSprite createIndexedSprite(final String imagePath) throws IOException
|
||||
{
|
||||
final BufferedImage bufferedImage = rgbaToIndexedBufferedImage(ImageIO
|
||||
.read(this.getClass().getResource(imagePath)));
|
||||
|
||||
final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel();
|
||||
|
||||
final int width = bufferedImage.getWidth();
|
||||
final int height = bufferedImage.getHeight();
|
||||
final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
|
||||
final int[] palette = new int[indexedCM.getMapSize()];
|
||||
indexedCM.getRGBs(palette);
|
||||
|
||||
final IndexedSprite newIndexedSprite = client.createIndexedSprite();
|
||||
newIndexedSprite.setPixels(pixels);
|
||||
newIndexedSprite.setPalette(palette);
|
||||
newIndexedSprite.setWidth(width);
|
||||
newIndexedSprite.setHeight(height);
|
||||
newIndexedSprite.setOriginalWidth(width);
|
||||
newIndexedSprite.setOriginalHeight(height);
|
||||
newIndexedSprite.setOffsetX(0);
|
||||
newIndexedSprite.setOffsetY(0);
|
||||
return newIndexedSprite;
|
||||
}
|
||||
|
||||
private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage)
|
||||
{
|
||||
final BufferedImage indexedImage = new BufferedImage(
|
||||
sourceBufferedImage.getWidth(),
|
||||
sourceBufferedImage.getHeight(),
|
||||
BufferedImage.TYPE_BYTE_INDEXED);
|
||||
|
||||
final ColorModel cm = indexedImage.getColorModel();
|
||||
final IndexColorModel icm = (IndexColorModel) cm;
|
||||
|
||||
final int size = icm.getMapSize();
|
||||
final byte[] reds = new byte[size];
|
||||
final byte[] greens = new byte[size];
|
||||
final byte[] blues = new byte[size];
|
||||
icm.getReds(reds);
|
||||
icm.getGreens(greens);
|
||||
icm.getBlues(blues);
|
||||
|
||||
final WritableRaster raster = indexedImage.getRaster();
|
||||
final int pixel = raster.getSample(0, 0, 0);
|
||||
final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel);
|
||||
final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
|
||||
resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
|
||||
return resultIndexedImage;
|
||||
}
|
||||
|
||||
private int getIconNumber(final ClanMemberRank clanMemberRank)
|
||||
{
|
||||
return modIconsLength - CLANCHAT_IMAGES.length + clanMemberRank.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ import net.runelite.client.plugins.raids.solver.LayoutSolver;
|
||||
import net.runelite.client.plugins.raids.solver.RotationSolver;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Chambers Of Xeric"
|
||||
|
||||
@@ -78,7 +78,7 @@ import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.ui.TitleToolbar;
|
||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.Text;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
|
||||
@@ -57,7 +57,7 @@ import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Slayer"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package net.runelite.client.util;
|
||||
|
||||
import net.runelite.api.Text;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ import net.runelite.api.Varbits;
|
||||
import net.runelite.api.WidgetNode;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.events.BoostedLevelChanged;
|
||||
import net.runelite.api.events.ClanChanged;
|
||||
import net.runelite.api.events.DraggingWidgetChanged;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
@@ -653,4 +654,11 @@ public abstract class RSClientMixin implements RSClient
|
||||
resizeableChanged.setResized(client.isResized());
|
||||
eventBus.post(resizeableChanged);
|
||||
}
|
||||
|
||||
@FieldHook("clanMemberManager")
|
||||
@Inject
|
||||
public static void clanMemberManagerChanged(int idx)
|
||||
{
|
||||
eventBus.post(new ClanChanged(client.getClanMemberManager() != null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.List;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Text;
|
||||
import net.runelite.api.model.Triangle;
|
||||
import net.runelite.api.model.Vertex;
|
||||
import net.runelite.api.mixins.Inject;
|
||||
@@ -63,7 +64,35 @@ public abstract class RSPlayerMixin implements RSPlayer
|
||||
return null;
|
||||
}
|
||||
|
||||
return name.replace('\u00A0', ' ');
|
||||
return Text.removeTags(name.replace('\u00A0', ' '));
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public String getCleanName()
|
||||
{
|
||||
final RSName rsName = getRsName();
|
||||
|
||||
if (rsName == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return rsName.getCleanName();
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setName(String name)
|
||||
{
|
||||
final RSName rsName = getRsName();
|
||||
|
||||
if (rsName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rsName.setName(name);
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
||||
@@ -549,4 +549,12 @@ public interface RSClient extends RSGameEngine, Client
|
||||
|
||||
@Import("drawObject")
|
||||
void drawObject(int z, int x, int y, int randomColor1, int randomColor2);
|
||||
|
||||
@Import("playerNameMask")
|
||||
@Override
|
||||
void setPlayerNameMask(int mask);
|
||||
|
||||
@Import("playerNameMask")
|
||||
@Override
|
||||
int getPlayerNameMask();
|
||||
}
|
||||
|
||||
@@ -30,4 +30,10 @@ public interface RSName
|
||||
{
|
||||
@Import("name")
|
||||
String getName();
|
||||
|
||||
@Import("cleanName")
|
||||
String getCleanName();
|
||||
|
||||
@Import("name")
|
||||
void setName(String name);
|
||||
}
|
||||
|
||||