From d1c692e72e5ed15c4c8c380559f9e3c2df162d1d Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Sat, 11 May 2019 14:46:45 -0700 Subject: [PATCH 01/14] western diary: Fix elf pickpocket quest requirement The requirement for pickpocketing an elf is to have started Mourning's End Part I for access to Lletya, not to have completed Mourning's End Part II. Fixes runelite/runelite#8806 --- .../achievementdiary/diaries/WesternDiaryRequirement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java index ee67f45132..b136f889fe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/WesternDiaryRequirement.java @@ -140,6 +140,6 @@ public class WesternDiaryRequirement extends GenericDiaryRequirement new QuestRequirement(Quest.BIG_CHOMPY_BIRD_HUNTING)); add("Pickpocket an Elf.", new SkillRequirement(Skill.THIEVING, 85), - new QuestRequirement(Quest.MOURNINGS_ENDS_PART_II)); + new QuestRequirement(Quest.MOURNINGS_ENDS_PART_I, true)); } } From bbb8cff0d5d1fc8c1d4c5fb34aa5e8858a3033a0 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Sat, 11 May 2019 23:58:35 -0700 Subject: [PATCH 02/14] game timers: Don't remove antipoison effects on death --- .../java/net/runelite/client/plugins/timers/GameTimer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 03473991f5..529103d204 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -48,7 +48,7 @@ enum GameTimer HALFTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Half Teleblock", 150, ChronoUnit.SECONDS, true), DMM_FULLTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Deadman Mode Full Teleblock", 150, ChronoUnit.SECONDS, true), DMM_HALFTB(SpriteID.SPELL_TELE_BLOCK, GameTimerImageType.SPRITE, "Deadman Mode Half Teleblock", 75, ChronoUnit.SECONDS, true), - ANTIVENOMPLUS(ItemID.ANTIVENOM4_12913, GameTimerImageType.ITEM, "Anti-venom+", 3, ChronoUnit.MINUTES, true), + ANTIVENOMPLUS(ItemID.ANTIVENOM4_12913, GameTimerImageType.ITEM, "Anti-venom+", 3, ChronoUnit.MINUTES), ANTIVENOMPLUS_ANTIPOSION(ItemID.SUPERANTIPOISON4, GameTimerImageType.ITEM, "Anti-venom+ Antipoison", 15, ChronoUnit.MINUTES, 3), SUPERANTIFIRE(ItemID.SUPER_ANTIFIRE_POTION4, GameTimerImageType.ITEM, "Super antifire", 3, ChronoUnit.MINUTES), ANTIDOTEPLUSPLUS(ItemID.ANTIDOTE4_5952, GameTimerImageType.ITEM, "Antidote++", 12, ChronoUnit.MINUTES), @@ -65,10 +65,10 @@ enum GameTimer IMBUEDHEART(ItemID.IMBUED_HEART, GameTimerImageType.ITEM, "Imbued heart", GraphicID.IMBUED_HEART, 420, ChronoUnit.SECONDS), VENGEANCE(SpriteID.SPELL_VENGEANCE, GameTimerImageType.SPRITE, "Vengeance", 30, ChronoUnit.SECONDS), ANTIDOTEPLUS(ItemID.ANTIDOTE4, GameTimerImageType.ITEM, "Antidote+", 518, ChronoUnit.SECONDS), - ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom", 1, ChronoUnit.MINUTES, true), + ANTIVENOM(ItemID.ANTIVENOM4, GameTimerImageType.ITEM, "Anti-venom", 1, ChronoUnit.MINUTES), ANTIVENOM_ANTIPOISON(ItemID.ANTIPOISON4, GameTimerImageType.ITEM, "Anti-venom Antipoison", 12, ChronoUnit.MINUTES, 1), EXSUPERANTIFIRE(ItemID.EXTENDED_SUPER_ANTIFIRE4, GameTimerImageType.ITEM, "Extended Super AntiFire", 6, ChronoUnit.MINUTES), - SANFEW(ItemID.SANFEW_SERUM4, GameTimerImageType.ITEM, "Sanfew serum", 6, ChronoUnit.MINUTES, true), + SANFEW(ItemID.SANFEW_SERUM4, GameTimerImageType.ITEM, "Sanfew serum", 6, ChronoUnit.MINUTES), OVERLOAD_RAID(ItemID.OVERLOAD_4_20996, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true), PRAYER_ENHANCE(ItemID.PRAYER_ENHANCE_4, GameTimerImageType.ITEM, "Prayer enhance", 290, ChronoUnit.SECONDS, true), GOD_WARS_ALTAR(SpriteID.SKILL_PRAYER, GameTimerImageType.SPRITE, "God wars altar", 10, ChronoUnit.MINUTES), From 471a0ba73f926c33b3e04b25b7e27c4d59f64671 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Fri, 10 May 2019 17:42:16 +0200 Subject: [PATCH 03/14] Add loop timer infobox Add loop timer infobox that will keep looping through specified interval. Signed-off-by: Tomas Slusny --- .../client/ui/overlay/infobox/LoopTimer.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/LoopTimer.java diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/LoopTimer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/LoopTimer.java new file mode 100644 index 0000000000..1e11f1900e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/LoopTimer.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019, Tomas Slusny + * 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.ui.overlay.infobox; + +import com.google.common.base.Preconditions; +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import lombok.Getter; +import lombok.ToString; +import net.runelite.client.plugins.Plugin; + +@Getter +@ToString +public class LoopTimer extends InfoBox +{ + private final Instant startTime; + private final Duration duration; + private final boolean reverse; + + public LoopTimer(long period, ChronoUnit unit, BufferedImage image, Plugin plugin, boolean reverse) + { + super(image, plugin); + + Preconditions.checkArgument(period > 0, "negative period!"); + + startTime = Instant.now(); + duration = Duration.of(period, unit); + this.reverse = reverse; + } + + public LoopTimer(long period, ChronoUnit unit, BufferedImage image, Plugin plugin) + { + this(period, unit, image, plugin, false); + } + + @Override + public String getText() + { + final Duration progress = getProgress(); + final int seconds = (int) (progress.toMillis() / 1000L); + final int minutes = (seconds % 3600) / 60; + final int secs = seconds % 60; + return String.format("%d:%02d", minutes, secs); + } + + @Override + public Color getTextColor() + { + final Duration progress = getProgress(); + + // check if timer has 10% of time left + if (progress.getSeconds() < (duration.getSeconds() * .10)) + { + return Color.RED.brighter(); + } + + return Color.WHITE; + } + + private Duration getProgress() + { + final Duration passed = Duration.between(startTime, Instant.now()); + final long passedMillis = passed.toMillis(); + final long durationMillis = duration.toMillis(); + final long progress = passedMillis % durationMillis; + + return Duration.ofMillis(reverse + ? durationMillis - progress + : progress); + } +} \ No newline at end of file From f82aa6be93e7f5387ac1697e9216bf8b79ddc506 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Tue, 14 May 2019 00:00:36 +0200 Subject: [PATCH 04/14] Use LoopTimer in Barrows plugin Signed-off-by: Tomas Slusny --- .../client/plugins/barrows/BarrowsPlugin.java | 22 +++++- .../barrows/BarrowsPrayerDrainTimer.java | 77 ------------------- 2 files changed, 20 insertions(+), 79 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java index 72bf08fe7e..30ecefb885 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.barrows; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; import java.util.HashSet; import java.util.Set; import javax.inject.Inject; @@ -41,6 +42,7 @@ import net.runelite.api.Item; import net.runelite.api.ItemContainer; import net.runelite.api.NullObjectID; import net.runelite.api.ObjectID; +import net.runelite.api.SpriteID; import net.runelite.api.WallObject; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameObjectChanged; @@ -66,6 +68,8 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; +import net.runelite.client.ui.overlay.infobox.LoopTimer; import net.runelite.client.util.StackFormatter; @PluginDescriptor( @@ -92,6 +96,7 @@ public class BarrowsPlugin extends Plugin WidgetInfo.BARROWS_PUZZLE_ANSWER3 ); + private static final long PRAYER_DRAIN_INTERVAL_MS = 18200; private static final int CRYPT_REGION_ID = 14231; @Getter(AccessLevel.PACKAGE) @@ -100,6 +105,7 @@ public class BarrowsPlugin extends Plugin @Getter(AccessLevel.PACKAGE) private final Set ladders = new HashSet<>(); + private LoopTimer barrowsPrayerDrainTimer; private boolean wasInCrypt = false; @Getter @@ -313,13 +319,25 @@ public class BarrowsPlugin extends Plugin { if (config.showPrayerDrainTimer()) { - infoBoxManager.addInfoBox(new BarrowsPrayerDrainTimer(this, spriteManager)); + final LoopTimer loopTimer = new LoopTimer( + PRAYER_DRAIN_INTERVAL_MS, + ChronoUnit.MILLIS, + spriteManager.getSprite(SpriteID.TAB_PRAYER, 0), + this, + true); + + loopTimer.setPriority(InfoBoxPriority.MED); + loopTimer.setTooltip("Prayer Drain"); + + infoBoxManager.addInfoBox(loopTimer); + barrowsPrayerDrainTimer = loopTimer; } } private void stopPrayerDrainTimer() { - infoBoxManager.removeIf(BarrowsPrayerDrainTimer.class::isInstance); + infoBoxManager.removeInfoBox(barrowsPrayerDrainTimer); + barrowsPrayerDrainTimer = null; } private boolean isInCrypt() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java deleted file mode 100644 index 4428a54f07..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2019, Ryan - * 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.barrows; - -import java.awt.Color; -import java.time.Duration; -import java.time.Instant; -import net.runelite.api.SpriteID; -import net.runelite.client.game.SpriteManager; -import net.runelite.client.ui.overlay.infobox.InfoBox; -import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; - -class BarrowsPrayerDrainTimer extends InfoBox -{ - private static final long PRAYER_DRAIN_INTERVAL_MS = 18200; - - private final Instant startTime; - - BarrowsPrayerDrainTimer(BarrowsPlugin plugin, SpriteManager spriteManager) - { - super(spriteManager.getSprite(SpriteID.TAB_PRAYER, 0), plugin); - setPriority(InfoBoxPriority.MED); - setTooltip("Prayer Drain"); - startTime = Instant.now(); - } - - @Override - public String getText() - { - Duration timeLeft = Duration.between(Instant.now(), getNextPrayerDrainTime()); - int seconds = (int) (timeLeft.toMillis() / 1000L); - return String.format("0:%02d", seconds); - } - - @Override - public Color getTextColor() - { - Duration timeLeft = Duration.between(Instant.now(), getNextPrayerDrainTime()); - - //check if timer has 10% of time left - if (timeLeft.getSeconds() < (PRAYER_DRAIN_INTERVAL_MS / 1000 * .10)) - { - return Color.RED.brighter(); - } - - return Color.WHITE; - } - - private Instant getNextPrayerDrainTime() - { - Duration timePassed = Duration.between(startTime, Instant.now()); - // Get how many intervals have passed so far and add one more to find the next prayer drain time - return startTime.plusMillis((timePassed.toMillis() / PRAYER_DRAIN_INTERVAL_MS + 1) * PRAYER_DRAIN_INTERVAL_MS); - } -} From 4e8e1822143727ef62a6ac12f50f425a6e3fa240 Mon Sep 17 00:00:00 2001 From: Ville Kopio <13101000+vkopio@users.noreply.github.com> Date: Tue, 14 May 2019 04:25:47 +0300 Subject: [PATCH 05/14] combatlevel plugin: fix prayer levels until combat level calculation Add more prayer level tests to expose a bug in which needed prayer levels for next combat level was 0 instead of 2 in some corner cases and implemented fixes. For example: Let prayer level p be an odd number. The current combat level is exactly same for p and p - 1. Therefore given n is the needed prayer levels for a combat level with p - 1 prayer then n - 1 is the needed prayer levels for a combal level with p prayer. Further more the usage of Math.floor was incorrect in every cases so it is changed to Math.ceil. --- .../combatlevel/CombatLevelOverlay.java | 8 +++- .../combatlevel/CombatLevelPluginTest.java | 43 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java index bc107e31b2..6e81a7a983 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java @@ -168,12 +168,18 @@ class CombatLevelOverlay extends Overlay @VisibleForTesting static int calcLevelsPray(double start, int end, int prayerLevel) { - final int neededLevels = (int) Math.floor(calcMultipliedLevels(start, end, PRAY_MULT)); + int neededLevels = (int) Math.ceil(calcMultipliedLevels(start, end, PRAY_MULT)); + + if (prayerLevel % 2 != 0) + { + neededLevels--; + } if ((prayerLevel + neededLevels) % 2 != 0) { return neededLevels + 1; } + return neededLevels; } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java index 3c1ff06f0c..361fa04aea 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java @@ -270,10 +270,47 @@ public class CombatLevelPluginTest when(client.getRealSkillLevel(Skill.MAGIC)).thenReturn(99); when(client.getRealSkillLevel(Skill.HITPOINTS)).thenReturn(99); + assertEquals(1, neededPrayerLevels()); + } + + @Test + public void testEvenPrayerLevelsNeededWhenNearNextCombatLevel() + { + when(player.getCombatLevel()).thenReturn(90); + when(client.getRealSkillLevel(Skill.ATTACK)).thenReturn(74); + when(client.getRealSkillLevel(Skill.STRENGTH)).thenReturn(75); + when(client.getRealSkillLevel(Skill.DEFENCE)).thenReturn(72); + when(client.getRealSkillLevel(Skill.PRAYER)).thenReturn(52); + when(client.getRealSkillLevel(Skill.RANGED)).thenReturn(44); + when(client.getRealSkillLevel(Skill.MAGIC)).thenReturn(60); + when(client.getRealSkillLevel(Skill.HITPOINTS)).thenReturn(72); + + assertEquals(2, neededPrayerLevels()); + } + + @Test + public void testOddPrayerLevelsNeededWhenNearNextCombatLevel() + { + when(player.getCombatLevel()).thenReturn(90); + when(client.getRealSkillLevel(Skill.ATTACK)).thenReturn(74); + when(client.getRealSkillLevel(Skill.STRENGTH)).thenReturn(75); + when(client.getRealSkillLevel(Skill.DEFENCE)).thenReturn(72); + when(client.getRealSkillLevel(Skill.PRAYER)).thenReturn(53); + when(client.getRealSkillLevel(Skill.RANGED)).thenReturn(44); + when(client.getRealSkillLevel(Skill.MAGIC)).thenReturn(60); + when(client.getRealSkillLevel(Skill.HITPOINTS)).thenReturn(72); + + assertEquals(1, neededPrayerLevels()); + } + + private int neededPrayerLevels() + { HashMap baseValues = getBaseValues(); - // test prayer - assertEquals(1, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); + return calcLevelsPray( + baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, + client.getRealSkillLevel(Skill.PRAYER) + ); } } From 6ddb82c532f6204dd2e5b39aac9f2e109cb94472 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 14 May 2019 15:52:54 +1000 Subject: [PATCH 06/14] clue scroll plugin: fix typo in Arnold Lydspor clue (#8832) Fixes #8828 --- .../runelite/client/plugins/cluescrolls/clues/CipherClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java index 4dcf3849e0..404ce70eae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java @@ -57,7 +57,7 @@ public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScr new CipherClue("GBJSZ RVFFO", "Fairy Queen", new WorldPoint(2347, 4435, 0), "Fairy Resistance Hideout", "Puzzle"), new CipherClue("QSPGFTTPS HSBDLMFCPOF", "Professor Gracklebone", new WorldPoint(1625, 3802, 0), "Ground floor of Arceuus Library", "9"), new CipherClue("IWPPLQTP", "Gunnjorn", new WorldPoint(2541, 3548, 0), "Barbarian Outpost Agility course", "Puzzle"), - new CipherClue("BSOPME MZETQPS", "Arnold Lydspor", new WorldPoint(2329, 3689, 0), "Piscatorus Fishing Colony general store/bank", "Puzzle") + new CipherClue("BSOPME MZETQPS", "Arnold Lydspor", new WorldPoint(2329, 3689, 0), "Piscatoris Fishing Colony general store/bank", "Puzzle") ); private String text; From bd309135cecd4442b445838f09076f330fd17448 Mon Sep 17 00:00:00 2001 From: JZomerlei Date: Tue, 14 May 2019 02:43:42 -0400 Subject: [PATCH 07/14] itemstats: Add missing CoX fish, fix Leckish fish healing value (#8831) Closes #8829 --- .../client/plugins/itemstats/ItemStatChanges.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java index 099b5a16a7..bcce08ffe5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java @@ -59,22 +59,22 @@ public class ItemStatChanges add(food(3), SHRIMPS, COOKED_MEAT, COOKED_CHICKEN, ROE, CHOCOLATE_BAR); add(food(4), SARDINE, CAKE, _23_CAKE, SLICE_OF_CAKE, CHOCOLATEY_MILK, BAKED_POTATO, EDIBLE_SEAWEED, MOONLIGHT_MEAD); add(food(5), BREAD, HERRING, CHOCOLATE_CAKE, _23_CHOCOLATE_CAKE, CHOCOLATE_SLICE, COOKED_RABBIT, CHILLI_CON_CARNE, - FRIED_MUSHROOMS, FRIED_ONIONS, REDBERRY_PIE, HALF_A_REDBERRY_PIE, CAVIAR); + FRIED_MUSHROOMS, FRIED_ONIONS, REDBERRY_PIE, HALF_A_REDBERRY_PIE, CAVIAR, PYSK_FISH_0); add(food(6), CHOCICE, MACKEREL, MEAT_PIE, HALF_A_MEAT_PIE, GUANIC_BAT_0, ROAST_BIRD_MEAT, SQUARE_SANDWICH, ROLL, BAGUETTE, TRIANGLE_SANDWICH, GIANT_CARP); add(food(7), TROUT, COD, PLAIN_PIZZA, _12_PLAIN_PIZZA, APPLE_PIE, HALF_AN_APPLE_PIE, ROAST_RABBIT, PREMADE_CH_CRUNCH, CHOCCHIP_CRUNCHIES, PREMADE_SY_CRUNCH, SPICY_CRUNCHIES); add(food(8), PIKE, ROAST_BEAST_MEAT, MEAT_PIZZA, _12_MEAT_PIZZA, PREMADE_WM_CRUN, WORM_CRUNCHIES, PREMADE_TD_CRUNCH, - TOAD_CRUNCHIES, EGG_AND_TOMATO, LECKISH_FISH_2, PRAEL_BAT_1, PEACH); + TOAD_CRUNCHIES, EGG_AND_TOMATO, PRAEL_BAT_1, PEACH, SUPHI_FISH_1); add(food(9), PREMADE_P_PUNCH, PINEAPPLE_PUNCH, PREMADE_FR_BLAST, FRUIT_BLAST, SALMON, ANCHOVY_PIZZA, _12_ANCHOVY_PIZZA); add(food(10), TUNA, COOKED_CRAB_MEAT, CHOPPED_TUNA, COOKED_CHOMPY, FIELD_RATION); add(food(11), RAINBOW_FISH, STEW, PINEAPPLE_PIZZA, _12_PINEAPPLE_PIZZA, COOKED_FISHCAKE, PREMADE_VEG_BATTA, VEGETABLE_BATTA, PREMADE_WM_BATTA, WORM_BATTA, PREMADE_TD_BATTA, TOAD_BATTA, PREMADE_CT_BATTA, - CHEESETOM_BATTA, PREMADE_FRT_BATTA, FRUIT_BATTA, MUSHROOM__ONION, GIRAL_BAT_2, LAVA_EEL); + CHEESETOM_BATTA, PREMADE_FRT_BATTA, FRUIT_BATTA, MUSHROOM__ONION, GIRAL_BAT_2, LAVA_EEL, LECKISH_FISH_2); add(food(12), LOBSTER, PREMADE_WORM_HOLE, WORM_HOLE, PREMADE_VEG_BALL, VEG_BALL); add(food(13), BASS, TUNA_AND_CORN); - add(food(14), POTATO_WITH_BUTTER, CHILLI_POTATO, SWORDFISH, PHLUXIA_BAT_3, PUMPKIN, EASTER_EGG); + add(food(14), POTATO_WITH_BUTTER, CHILLI_POTATO, SWORDFISH, PHLUXIA_BAT_3, PUMPKIN, EASTER_EGG, BRAWK_FISH_3); add(food(15), PREMADE_TTL, TANGLED_TOADS_LEGS, PREMADE_CHOC_BOMB, CHOCOLATE_BOMB, COOKED_JUBBLY); add(food(16), MONKFISH, POTATO_WITH_CHEESE, EGG_POTATO); add(food(17), MYCIL_FISH_4, KRYKET_BAT_4); From 869fa9d93dfd8fbc46f97c6f17f8c9a33961f3ab Mon Sep 17 00:00:00 2001 From: Vincent Sevilla Date: Tue, 14 May 2019 05:24:45 -0700 Subject: [PATCH 08/14] notifier: Log notifications to console in debug mode (#8805) --- runelite-client/src/main/java/net/runelite/client/Notifier.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/Notifier.java b/runelite-client/src/main/java/net/runelite/client/Notifier.java index e29d66c87c..d1423f168e 100644 --- a/runelite-client/src/main/java/net/runelite/client/Notifier.java +++ b/runelite-client/src/main/java/net/runelite/client/Notifier.java @@ -150,6 +150,8 @@ public class Notifier { flashStart = Instant.now(); } + + log.debug(message); } public void processFlash(final Graphics2D graphics) From 69e57c9a612700aba711f59019f5a7548c850c55 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sun, 12 May 2019 16:08:14 +0200 Subject: [PATCH 09/14] client: format enum config options as "Config Opt" instead of CONFIG_OPT --- .../client/plugins/config/ConfigPanel.java | 4 +-- .../ui/components/ComboBoxListRenderer.java | 12 ++++++++- .../java/net/runelite/client/util/Text.java | 25 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index b71d5e8b0e..cfd5fca7c6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -492,7 +492,7 @@ public class ConfigPanel extends PluginPanel { Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName())); box.setSelectedItem(selectedItem); - box.setToolTipText(selectedItem.toString()); + box.setToolTipText(Text.titleCase(selectedItem)); } catch (IllegalArgumentException ex) { @@ -503,7 +503,7 @@ public class ConfigPanel extends PluginPanel if (e.getStateChange() == ItemEvent.SELECTED) { changeConfiguration(listItem, config, box, cd, cid); - box.setToolTipText(box.getSelectedItem().toString()); + box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem())); } }); item.add(box, BorderLayout.EAST); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java index a397cc3050..5aeb710115 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java @@ -31,6 +31,7 @@ import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.border.EmptyBorder; import net.runelite.client.ui.ColorScheme; +import net.runelite.client.util.Text; /** * A custom list renderer to avoid substance's weird coloring. @@ -57,7 +58,16 @@ public final class ComboBoxListRenderer extends JLabel implements ListCellRender setBorder(new EmptyBorder(5, 5, 5, 0)); - String text = o.toString(); + String text; + if (o instanceof Enum) + { + text = Text.titleCase((Enum) o); + } + else + { + text = o.toString(); + } + setText(text); return this; diff --git a/runelite-client/src/main/java/net/runelite/client/util/Text.java b/runelite-client/src/main/java/net/runelite/client/util/Text.java index 890b24fd32..6158b9a32f 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/Text.java +++ b/runelite-client/src/main/java/net/runelite/client/util/Text.java @@ -31,6 +31,7 @@ import com.google.common.base.Splitter; import java.util.Collection; import java.util.List; import java.util.regex.Pattern; +import org.apache.commons.text.WordUtils; /** * A set of utilities to use when dealing with text. @@ -159,4 +160,28 @@ public class Text String cleaned = name.contains("') + 1) : name; return cleaned.replace('\u00A0', ' '); } + + /** + * If passed in enum doesn't implement its own toString, + * converts enum name format from THIS_FORMAT to This Format. + * + * @param o an enum + * @return the enum's name in title case, + * or if it overrides toString, + * the value returned by toString + */ + public static String titleCase(Enum o) + { + String toString = o.toString(); + + // .toString() returns the value of .name() if not overridden + if (o.name().equals(toString)) + { + return WordUtils + .capitalize(toString.toLowerCase(), '_') + .replace("_", " "); + } + + return toString; + } } From 69d788d20cfb1be60b242db482b0268a2b358e6a Mon Sep 17 00:00:00 2001 From: Lotto Date: Sun, 12 May 2019 16:13:47 +0200 Subject: [PATCH 10/14] client: remove overrides in config enums with same converted name --- .../plugins/chatfilter/ChatFilterType.java | 17 +++------------ .../client/plugins/fps/FpsLimitMode.java | 19 +++-------------- .../ItemIdentificationMode.java | 17 ++------------- .../plugins/npchighlight/RenderStyle.java | 21 ++++--------------- .../plugins/prayer/PrayerFlickLocation.java | 21 ++++--------------- .../config/RunePouchOverlayMode.java | 19 +++-------------- .../worldhopper/SubscriptionFilterMode.java | 19 +++-------------- .../plugins/xptracker/XpTrackerConfig.java | 16 ++++---------- 8 files changed, 26 insertions(+), 123 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java index cf52fa969f..f0aef43471 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterType.java @@ -24,20 +24,9 @@ */ package net.runelite.client.plugins.chatfilter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor public enum ChatFilterType { - CENSOR_WORDS("Censor words"), - CENSOR_MESSAGE("Censor message"), - REMOVE_MESSAGE("Remove message"); - - private final String name; - - @Override - public String toString() - { - return name; - } + CENSOR_WORDS, + CENSOR_MESSAGE, + REMOVE_MESSAGE } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java index 8536f7a67a..25f855f1c5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fps/FpsLimitMode.java @@ -24,22 +24,9 @@ */ package net.runelite.client.plugins.fps; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor public enum FpsLimitMode { - NEVER("Never"), - UNFOCUSED("Unfocused"), - ALWAYS("Always"); - - private final String name; - - @Override - public String toString() - { - return name; - } + NEVER, + UNFOCUSED, + ALWAYS } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationMode.java index 7b9f11217c..3a692822b9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationMode.java @@ -24,21 +24,8 @@ */ package net.runelite.client.plugins.itemidentification; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor public enum ItemIdentificationMode { - SHORT("Short"), - MEDIUM("Medium"); - - private final String type; - - @Override - public String toString() - { - return type; - } + SHORT, + MEDIUM } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/RenderStyle.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/RenderStyle.java index d00029abe0..811ee5dda9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/RenderStyle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/RenderStyle.java @@ -26,21 +26,8 @@ package net.runelite.client.plugins.npchighlight; public enum RenderStyle { - OFF("Off"), - TILE("Tile"), - HULL("Hull"), - SOUTH_WEST_TILE("South West Tile"); - - private final String name; - - RenderStyle(String name) - { - this.name = name; - } - - @Override - public String toString() - { - return name; - } + OFF, + TILE, + HULL, + SOUTH_WEST_TILE } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickLocation.java index a39825677e..593ad87bc8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickLocation.java @@ -26,23 +26,10 @@ package net.runelite.client.plugins.prayer; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor public enum PrayerFlickLocation { - NONE("Off"), - PRAYER_ORB("Prayer Orb"), - PRAYER_BAR("Prayer Bar"), - BOTH("Both"); - - private final String name; - - @Override - public String toString() - { - return name; - } + NONE, + PRAYER_ORB, + PRAYER_BAR, + BOTH } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/config/RunePouchOverlayMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/config/RunePouchOverlayMode.java index 2ea02e883c..70d2564f26 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/config/RunePouchOverlayMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/config/RunePouchOverlayMode.java @@ -24,22 +24,9 @@ */ package net.runelite.client.plugins.runepouch.config; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor public enum RunePouchOverlayMode { - INVENTORY("Inventory"), - MOUSE_HOVER("Mouse hover"), - BOTH("Both"); - - private final String name; - - @Override - public String toString() - { - return name; - } + INVENTORY, + MOUSE_HOVER, + BOTH } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/SubscriptionFilterMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/SubscriptionFilterMode.java index 42352f64aa..b95a41a468 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/SubscriptionFilterMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/SubscriptionFilterMode.java @@ -24,22 +24,9 @@ */ package net.runelite.client.plugins.worldhopper; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor public enum SubscriptionFilterMode { - BOTH("Both"), - FREE("Free"), - MEMBERS("Member"); - - private final String name; - - @Override - public String toString() - { - return name; - } + BOTH, + FREE, + MEMBERS } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java index 6bac32802a..d3ded4f54c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java @@ -35,18 +35,10 @@ public interface XpTrackerConfig extends Config @AllArgsConstructor enum OnScreenDisplayMode { - XP_GAINED("XP Gained"), - XP_LEFT("XP Left"), - ACTIONS_DONE("Actions Done"), - ACTIONS_LEFT("Actions Left"); - - private final String name; - - @Override - public String toString() - { - return name; - } + XP_GAINED, + XP_LEFT, + ACTIONS_DONE, + ACTIONS_LEFT } @ConfigItem( From 1cd1bbb005a89ad466ebacb67a010698627b9c6c Mon Sep 17 00:00:00 2001 From: Lotto Date: Sun, 12 May 2019 01:43:19 +0200 Subject: [PATCH 11/14] client: add BufferedImage -> IndexedSprite converter to ImageUtil --- .../net/runelite/client/util/ImageUtil.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 16a6b1c78a..d7f579b722 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -24,6 +24,7 @@ */ package net.runelite.client.util; +import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; @@ -34,12 +35,15 @@ import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.RescaleOp; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javax.imageio.ImageIO; import javax.swing.GrayFilter; import java.util.function.Predicate; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.IndexedSprite; import net.runelite.api.SpritePixels; /** @@ -448,4 +452,74 @@ public class ImageUtil return client.createSpritePixels(pixels, image.getWidth(), image.getHeight()); } + + /** + * Converts an image into an {@code IndexedSprite} instance. + * + * The passed in image can only have at max 255 different colors. + * + * @param image The image to be converted + * @param client Current client instance + * @return The image as an {@code IndexedSprite} + */ + public static IndexedSprite getImageIndexedSprite(BufferedImage image, Client client) + { + final byte[] pixels = new byte[image.getWidth() * image.getHeight()]; + final List palette = new ArrayList<>(); + /* + When drawing the indexed sprite, palette idx 0 is seen as fully transparent, + so pad the palette out so that our colors start at idx 1. + */ + palette.add(0); + + final int[] sourcePixels = image.getRGB(0, 0, + image.getWidth(), image.getHeight(), + null, 0, image.getWidth()); + + /* + Build a color palette and assign the pixels to positions in the palette. + */ + for (int j = 0; j < sourcePixels.length; j++) + { + final int argb = sourcePixels[j]; + final int a = (argb >> 24) & 0xFF; + final int rgb = argb & 0xFF_FF_FF; + + // Default to not drawing the pixel. + int paletteIdx = 0; + + // If the pixel is fully opaque, draw it. + if (a == 0xFF) + { + paletteIdx = palette.indexOf(rgb); + + if (paletteIdx == -1) + { + paletteIdx = palette.size(); + palette.add(rgb); + } + } + + pixels[j] = (byte) paletteIdx; + } + + if (palette.size() > 256) + { + throw new RuntimeException("Passed in image had " + (palette.size() - 1) + + " different colors, exceeding the max of 255."); + } + + final IndexedSprite sprite = client.createIndexedSprite(); + + sprite.setPixels(pixels); + sprite.setPalette(Ints.toArray(palette)); + sprite.setWidth(image.getWidth()); + sprite.setHeight(image.getHeight()); + sprite.setOriginalWidth(image.getWidth()); + sprite.setOriginalHeight(image.getHeight()); + sprite.setOffsetX(0); + sprite.setOffsetY(0); + + return sprite; + } } From da2c195a17f253fe96fa2057992cb4749963a015 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sun, 12 May 2019 01:44:39 +0200 Subject: [PATCH 12/14] client: change ClanManager to use ImageUtil image converter --- .../net/runelite/client/game/ClanManager.java | 56 +------------------ 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java b/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java index bbfd3452cf..0b80bbc7e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ClanManager.java @@ -30,10 +30,6 @@ import com.google.common.cache.LoadingCache; import java.awt.Color; import java.awt.Dimension; 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.util.Arrays; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -152,8 +148,8 @@ public class ClanManager for (int i = 0; i < CLANCHAT_IMAGES.length; i++, curPosition++) { final int resource = CLANCHAT_IMAGES[i]; - clanChatImages[i] = rgbaToIndexedBufferedImage(clanChatImageFromSprite(spriteManager.getSprite(resource, 0))); - newModIcons[curPosition] = createIndexedSprite(client, clanChatImages[i]); + clanChatImages[i] = clanChatImageFromSprite(spriteManager.getSprite(resource, 0)); + newModIcons[curPosition] = ImageUtil.getImageIndexedSprite(clanChatImages[i], client); } client.setModIcons(newModIcons); @@ -166,54 +162,6 @@ public class ClanManager return cleaned.replace('\u00A0', ' '); } - private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) - { - 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 static BufferedImage clanChatImageFromSprite(final BufferedImage clanSprite) { final BufferedImage clanChatCanvas = ImageUtil.resizeCanvas(clanSprite, CLANCHAT_IMAGE_DIMENSION.width, CLANCHAT_IMAGE_DIMENSION.height); From 64019ea785ab062f0e0524ccbeb6ca60260ad07a Mon Sep 17 00:00:00 2001 From: Lotto Date: Sun, 12 May 2019 01:47:40 +0200 Subject: [PATCH 13/14] client: add emoji plugin Replaces various emoticons entered in public/friends/private chats with their corresponding emoji images. Co-authored-by: Adam Co-authored-by: Tomas Slusny --- .../runelite/client/plugins/emojis/Emoji.java | 114 +++++++++++ .../client/plugins/emojis/EmojiPlugin.java | 192 ++++++++++++++++++ .../runelite/client/plugins/emojis/LICENSE | 1 + .../runelite/client/plugins/emojis/blush.png | Bin 0 -> 1323 bytes .../client/plugins/emojis/broken_heart.png | Bin 0 -> 16185 bytes .../runelite/client/plugins/emojis/cat.png | Bin 0 -> 1501 bytes .../client/plugins/emojis/confused.png | Bin 0 -> 1225 bytes .../client/plugins/emojis/cooking.png | Bin 0 -> 1320 bytes .../runelite/client/plugins/emojis/cowboy.png | Bin 0 -> 1371 bytes .../runelite/client/plugins/emojis/crab.png | Bin 0 -> 15828 bytes .../runelite/client/plugins/emojis/cry.png | Bin 0 -> 312 bytes .../runelite/client/plugins/emojis/dancer.png | Bin 0 -> 15813 bytes .../runelite/client/plugins/emojis/dog.png | Bin 0 -> 1457 bytes .../client/plugins/emojis/expressionless.png | Bin 0 -> 1154 bytes .../runelite/client/plugins/emojis/eyes.png | Bin 0 -> 1406 bytes .../runelite/client/plugins/emojis/fish.png | Bin 0 -> 1280 bytes .../client/plugins/emojis/flushed.png | Bin 0 -> 1434 bytes .../client/plugins/emojis/fork_and_knife.png | Bin 0 -> 16173 bytes .../client/plugins/emojis/frowning2.png | Bin 0 -> 1215 bytes .../client/plugins/emojis/grinning.png | Bin 0 -> 1348 bytes .../runelite/client/plugins/emojis/hearts.png | Bin 0 -> 16179 bytes .../client/plugins/emojis/hugging.png | Bin 0 -> 1374 bytes .../runelite/client/plugins/emojis/hushed.png | Bin 0 -> 1285 bytes .../client/plugins/emojis/innocent.png | Bin 0 -> 1439 bytes .../runelite/client/plugins/emojis/joy.png | Bin 0 -> 1444 bytes .../client/plugins/emojis/kissing.png | Bin 0 -> 1181 bytes .../client/plugins/emojis/neutral_face.png | Bin 0 -> 1196 bytes .../client/plugins/emojis/ok_hand.png | Bin 0 -> 16210 bytes .../client/plugins/emojis/open_mouth.png | Bin 0 -> 1229 bytes .../client/plugins/emojis/party_popper.png | Bin 0 -> 1403 bytes .../client/plugins/emojis/persevere.png | Bin 0 -> 1366 bytes .../client/plugins/emojis/pile_of_poo.png | Bin 0 -> 1286 bytes .../runelite/client/plugins/emojis/rage.png | Bin 0 -> 1233 bytes .../runelite/client/plugins/emojis/scream.png | Bin 0 -> 1413 bytes .../client/plugins/emojis/see_no_evil.png | Bin 0 -> 1483 bytes .../client/plugins/emojis/slight_frown.png | Bin 0 -> 1243 bytes .../client/plugins/emojis/slight_smile.png | Bin 0 -> 1253 bytes .../runelite/client/plugins/emojis/smile.png | Bin 0 -> 1321 bytes .../client/plugins/emojis/smiling_imp.png | Bin 0 -> 1250 bytes .../runelite/client/plugins/emojis/sob.png | Bin 0 -> 1349 bytes .../plugins/emojis/stuck_out_tongue.png | Bin 0 -> 1314 bytes .../emojis/stuck_out_tongue_closed_eyes.png | Bin 0 -> 1344 bytes .../client/plugins/emojis/sunglasses.png | Bin 0 -> 1311 bytes .../runelite/client/plugins/emojis/sweat.png | Bin 0 -> 1081 bytes .../client/plugins/emojis/thinking.png | Bin 0 -> 15849 bytes .../client/plugins/emojis/thumbsdown.png | Bin 0 -> 1223 bytes .../client/plugins/emojis/thumbsup.png | Bin 0 -> 1218 bytes .../client/plugins/emojis/triumph.png | Bin 0 -> 1433 bytes .../client/plugins/emojis/unamused.png | Bin 0 -> 16276 bytes .../runelite/client/plugins/emojis/wink.png | Bin 0 -> 1303 bytes .../runelite/client/plugins/emojis/yum.png | Bin 0 -> 1318 bytes .../client/plugins/emojis/zipper_mouth.png | Bin 0 -> 1296 bytes .../runelite/client/plugins/emojis/zzz.png | Bin 0 -> 16185 bytes 53 files changed, 307 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/blush.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/broken_heart.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cat.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/confused.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cooking.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cowboy.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/crab.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cry.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dancer.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dog.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/expressionless.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/eyes.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fish.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/flushed.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/fork_and_knife.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/frowning2.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/grinning.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hearts.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hugging.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hushed.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/innocent.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/joy.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/kissing.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/neutral_face.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/ok_hand.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/open_mouth.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/party_popper.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/persevere.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/pile_of_poo.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/rage.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/scream.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/see_no_evil.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_frown.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_smile.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smile.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smiling_imp.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sob.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue_closed_eyes.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sunglasses.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/sweat.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thinking.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsdown.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsup.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/triumph.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/unamused.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/wink.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/yum.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zipper_mouth.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zzz.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java new file mode 100644 index 0000000000..b0ed60a55e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/Emoji.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019, Lotto + * 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.emojis; + +import com.google.common.collect.ImmutableMap; +import java.awt.image.BufferedImage; +import java.util.Map; +import net.runelite.client.util.ImageUtil; + +enum Emoji +{ + SLIGHT_SMILE(":)"), + JOY("=')"), + COWBOY("3:)"), + BLUSH("^_^"), + SMILE(":D"), + GRINNING("=D"), + WINK(";)"), + STUCK_OUT_TONGUE_CLOSED_EYES("X-P"), + STUCK_OUT_TONGUE(":P"), + YUM("=P~"), + HUGGING(":D"), // >:D< + TRIUMPH(":"), // :> + THINKING(":-?"), + CONFUSED(":/"), + NEUTRAL_FACE("=|"), + EXPRESSIONLESS(":|"), + UNAMUSED(":-|"), + SLIGHT_FROWN(":("), + FROWNING2("=("), + CRY(":'("), + SOB(":_("), + FLUSHED(":$"), + ZIPPER_MOUTH(":-#"), + PERSEVERE("_"), // >_< + SUNGLASSES("8-)"), + INNOCENT("O:)"), + SMILING_IMP(":)"), // >:) + RAGE(":("), // >:( + HUSHED(":-O"), + OPEN_MOUTH(":O"), + SCREAM(":-@"), + SEE_NO_EVIL("X_X"), + DANCER("\\:D/"), + OK_HAND("(Ok)"), + THUMBSUP("(Y)"), + THUMBSDOWN("(N)"), + HEARTS("3"), // <3 + BROKEN_HEART("/3"), // "), // <>< + CAT(":3"), + DOG("=3"), + CRAB("V(;,;)V"), + FORK_AND_KNIFE("--E"), + COOKING("--(o)"), + PARTY_POPPER("@@@"), + EYES("O.O"), + SWEAT(";;"), + PILE_OF_POO("~@~"); + + private static final Map emojiMap; + + private final String trigger; + + static + { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + + for (final Emoji emoji : values()) + { + builder.put(emoji.trigger, emoji); + } + + emojiMap = builder.build(); + } + + Emoji(String trigger) + { + this.trigger = trigger; + } + + BufferedImage loadImage() + { + return ImageUtil.getResourceStreamFromClass(getClass(), this.name().toLowerCase() + ".png"); + } + + static Emoji getEmoji(String trigger) + { + return emojiMap.get(trigger); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java new file mode 100644 index 0000000000..bfca89c184 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/emojis/EmojiPlugin.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2019, Lotto + * 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.emojis; + +import java.awt.image.BufferedImage; +import java.util.Arrays; +import javax.annotation.Nullable; +import javax.inject.Inject; +import joptsimple.internal.Strings; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.IndexedSprite; +import net.runelite.api.MessageNode; +import net.runelite.api.Player; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.OverheadTextChanged; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.ImageUtil; + +@PluginDescriptor( + name = "Emojis", + description = "Replaces common emoticons such as :) with their corresponding emoji in the chat", + enabledByDefault = false +) +@Slf4j +public class EmojiPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ChatMessageManager chatMessageManager; + + private int modIconsStart = -1; + + @Override + protected void startUp() + { + loadEmojiIcons(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged gameStateChanged) + { + if (gameStateChanged.getGameState() == GameState.LOGGED_IN) + { + loadEmojiIcons(); + } + } + + private void loadEmojiIcons() + { + final IndexedSprite[] modIcons = client.getModIcons(); + if (modIconsStart != -1 || modIcons == null) + { + return; + } + + final Emoji[] emojis = Emoji.values(); + final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + emojis.length); + modIconsStart = modIcons.length; + + for (int i = 0; i < emojis.length; i++) + { + final Emoji emoji = emojis[i]; + + try + { + final BufferedImage image = emoji.loadImage(); + final IndexedSprite sprite = ImageUtil.getImageIndexedSprite(image, client); + newModIcons[modIconsStart + i] = sprite; + } + catch (Exception ex) + { + log.warn("Failed to load the sprite for emoji " + emoji, ex); + } + } + + log.debug("Adding emoji icons"); + client.setModIcons(newModIcons); + } + + @Subscribe + public void onChatMessage(ChatMessage chatMessage) + { + if (client.getGameState() != GameState.LOGGED_IN || modIconsStart == -1) + { + return; + } + + switch (chatMessage.getType()) + { + case PUBLICCHAT: + case MODCHAT: + case FRIENDSCHAT: + case PRIVATECHAT: + case PRIVATECHATOUT: + break; + default: + return; + } + + final String message = chatMessage.getMessage(); + final String updatedMessage = updateMessage(message); + + if (updatedMessage == null) + { + return; + } + + final MessageNode messageNode = chatMessage.getMessageNode(); + messageNode.setRuneLiteFormatMessage(updatedMessage); + chatMessageManager.update(messageNode); + client.refreshChat(); + } + + @Subscribe + public void onOverheadTextChanged(final OverheadTextChanged event) + { + if (!(event.getActor() instanceof Player)) + { + return; + } + + final String message = event.getOverheadText(); + final String updatedMessage = updateMessage(message); + + if (updatedMessage == null) + { + return; + } + + event.getActor().setOverheadText(updatedMessage); + } + + @Nullable + private String updateMessage(final String message) + { + final String[] messageWords = message.split(" "); + + boolean editedMessage = false; + for (int i = 0; i < messageWords.length; i++) + { + final Emoji emoji = Emoji.getEmoji(messageWords[i]); + + if (emoji == null) + { + continue; + } + + final int emojiId = modIconsStart + emoji.ordinal(); + + messageWords[i] = ""; + editedMessage = true; + } + + // If we haven't edited the message any, don't update it. + if (!editedMessage) + { + return null; + } + + return Strings.join(messageWords, " "); + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE new file mode 100644 index 0000000000..9e2a9503a0 --- /dev/null +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/LICENSE @@ -0,0 +1 @@ +The images in this folder are derivatives of "twemoji" (https://github.com/twitter/twemoji) by "Twitter, Inc", used under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). The derivatives are licensed under the same license. \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/blush.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/blush.png new file mode 100644 index 0000000000000000000000000000000000000000..7024942ef0f45b10647ef71ec21a477b4b4f0d1a GIT binary patch literal 1323 zcmbVLYiJx*6rLs$+U*8{52XH(=>)NX&d$uvzGlc8vpbt+ZFaleY@4&SwkKL zMIdXFPcDLPf@q!4OJ!Kj4T!2`gk)bQUo6h_C##J08l19qh`9Im!wwhig@o|GZeY10>_fn z8mV%wK&CARkkL?#RyjUF#)S|U6%ygdZZgbrF@_ZwE<&@M$OD!_@2bP@NB1&M3nPg21q0CLE@*2JKFoQ1)ok?QB|*fU7#X4Ry;TeT%YU zjl(2`nXZLk*ty(>Vbfht6iylA$u`45MblR_aoZK~}o0?U3yZkb(MJ)kGp8#5)V;SUX zo<)5V4*xFxHN5tJ^T%LPjNdH(XrAU3?nr;TF$(ywF-*Y36Xf7g`O$#4@tD0>7${}X z^&Ij}ptDu9P(YUsp{0Fj`nf+A_O8tLpFXk^T`8}4M{k|)K_3sEIsEYZ$GX0qOQV@* zZ&~%*7gA4^w}1Y29L*m%+n|=u=Z`8KlLrH6DgWN=uHUX@D;WY^d3^4fo#?}%?lE5f8uw2f3@pADM)ReY>>a-}TuiO8{r8Ws2*YB2 z5dGIhv=?4p#^|xE)LZgyDC}J=Z5;&vMs4fsTdr<#KJ|j1-F>)Gh~i&(6*cJbHjUbZYw4vE#!JE~sCQl=f>QpQtzQ`Qi9|-+wiFv*p#d ox;h`4yS6y3x4ts`!Z+JGMu?@8fv(y`ibrJgbiaRa3zgbuS6)J70hGlvz| zClWMIN5qqs0RG#Zd-*)l5Ww#s(~7j#U?PDGO|ucvX%R8{v_!qaz;71lt8yrTfSI6i zp2KXi*p-d|zEf8Telx`=pXaPXCkF6?n1sAoZ6q(4vJpI)&`+SpB>p_PLWs!}{$gnp zo>+wWp&|u}Nd+QIDN-m!7%%g~5A+4UR5pWA8Kn-%Ob4t0egaKfl_;8$k|Ioz2q{}U ziYXKdR3t{lVgaZju%}vR+##^oYr90;I%>kMw~5rS#ls<{+SC~2wID`h$pft)b zoX}x}Kq~UX1QM~-PoNXaFo8i&_$iDEOfK`+snA?yJhLh@RSqda6!Kt=Tq2W8#Vs&Q zqX?4u`Gv?uAu>%!ut*~lyXCz?v&n{8>@;rC6PYb1LCfVv9VVAZP)@0Ruo&nB%VY-BQF2(eLS=Yp}~Hao#g-T=OP_GYcHOsdZ5uOzd# zDQ`5hg?rir5~y5m!+$$g*}^^QZX8}+&OTW}Njpv1QoS5ZqnNEEn&|m=soP;9^GGg> zA6WHDT+eJ$fp#3wSD|*=tIX46R|J#DRUrrH5?n6DjF?G^p(s;c zCL$c-!R=8a)HqFeuMx~oDF(3p+@!NaTs0vLEoC5$sefx^A1y}1t0t@gZej+U#`C1& zUDr#;pjR3xn;EAANi!Z#pjJz~3iT9v)yz84mBEyWvVmrS?yJz8ioK$kvz$47!4`l! zH#?Vhcoe$*Y za6v%WO%4}3AIQt$f`G7_94>Y~ke9;+0bw^eTCz>19>@I5D<2g!^O@A@^ZK!AnYcGi=7YT<#0hj*i8->J0Hl);evp$ zn;b57K9HBg1p#3W-`xY+qXUJe%ogxzGtKi4rABmMmGSRH@RX zOP48Arfk`=<;s;SU%q^W3Kc3=tXQd1rOK5nSE*8^YSpUMs#U9Ay?TurHEPzZ3A$OU zRxLiCU%PhgI(6#Qty{NVy?XWQ*Kg3ELBoa(8#QXwxN+kqO_~S<0-;cdq9}Mufnk_f zES5+lQmIrX1Md<2sR9B50s{k^HEY(qdGny4pcXA!1P2GJ z)oP7K6A}{AvSrKA(9p23uvV>FwQk)yJUm>h)kZ`_v}w~OGBUDl+qO|rQPI)SF)=ai z+O=!nzI}%d9b#i+V_IJ9p{QrEAx&-MV$_-n~1H<2s#Auh$z427(}r zMq_+@d_qD3Ns>K!^hiuhG?`3hv)N*?P!wggT6^~FX|vhvb~{beNl8h`$;sfMu*2a< zO-)TpOY7CESMT1v`}FD4w{PEm{rdIq-+#b>0RsmP95iUq;K7533>h+X=+I%qh7BJ+ ze8h+mBS(%LHEPu8(WA$V88de5*m2{=rKhKlA3uJ=gb5QTPMkDp(&WjLr%ahLb?Ve< z)22eT7er_Y=@bN1}nbLY;TKY#whg$oxiUc7Ya(&fvS zuUxru_3G7Y*REZ^e*MOc8#iy>ymjl=?c2BS+_`i2?%jL$?%ltC|G|R?4<9~!^yty! z$B&;pdGhq>(`V0~J%9fE#fuj&U%q_x>ecJluiw0R^Y-oAckkZ4fB*i&hYue=e*E<5 z)925hzkK=f_3PJf-@bkS{{6>~A3uNo{PpYC@87@w{P~lSk+HvhdK|L==%|S34CL`v zQ7d4{!qh=AjvJlFhLu1>h4T%|=(nTLvdI&+h1Y3xgWt1h|Ks`68}?|Bw(J14)HrFT fW`n)Y5bl9y&kkB zx;ZokGPk%8$JETIxGWoHOkv#|erA$L#x}q?Kr@$xXiSW5j1A?(p6>xg|5z4d;+xz( z@B7~Kd!FC(b?w!@@-_L7(2LE!w5vUcJUK zbWufav|~%8>b=#dQIWj-+%1y1X#x zO=2UIpDtVW1y6P?D$8*S$CJsVHfhj`QUgwqB#G#_( zxVX%T0;*bMLSmC_#~{KEGG)43{Np}oY3lUo>${q)K18L@HdUyY9|8e zIKcfNAvQ^2SdU0S4h(a5XGf|cWJ7J1I9L=WMvLJl9tg6Vwqx*%mgQKA1caHjFjfu0 z8cZ5<$Otry#lUI|AqHj@=qzCa$l19a-r}&9nvG7Y#b|I4go`9i7Ax&^ILa)9!Q#}> zIjmbq$czvMIo}-gy^OWo5lcBGz{sK$5XD%o3#y}{EGD929CbR?s$0;ZxERd-c;0xo69tDFxiXFbZfEy{(h%8*YP32np;v&W0(Pdj$M)}fsBX2;Th zbX&9IJCyUazYm47W2uENT&{}p`BNpCF5%P%?aD>|7k>M}w(9J}uIV#Xy+?M>_1Wio z?R(S3%4p>JV07U^sHnu*|0bg@^Y{H#Jkb1!$&oGgEFx*J6LsV!1HTUG&}yn%(+-5)1wSOJ$$6R%(Hp_&XSXz zu1qI=xzBwyxM#WyC*PMy$~67@rtzMNKh;2zUF{BK6wJKyvUSWWTRQ`9Bs?>5WZ54}08nX(08Taj$dT-CK|WeTM%&!(UN0P4`Er z?!s-K=3n2p>i&kRwfA*=_UNH)wKtsUw&CG|$!6?QXJy{@s;L+69X-8X{wXgQeeC1$ z^}l&f)a|);_2;8+XCEA3Y-cpqkGjn-*#=+!_SMz_?enqpCzFVI>YFQv^ZCi4TN|{k nmkxCZZyl_hTf6Y%j(Z+LX4h?CM@DW0Au+`5^3lf}&$j*rOk8Qi literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/confused.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/confused.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3275a23660e27b81ce51dd679b08be5d17e1bc GIT binary patch literal 1225 zcmbVLOKj6-95+on3IbN73IPXZ+#Z;OV>^xG*lI|V*r91Z5CVyZ!~rhA=eFr~sHzD|_V@7b z_y7H$$BTu%8`p1NPY}e$T)$ij*5GXq;jhAX7VxqSDMM%wR#07a0g*DG2FRSH4ucX< zjmEJXpqC&*V`g~>4dn+U9a>>Ez=VCv!EA!)P5O?ij{rn!VA!-1)XOVV6lod>>JXo2 z^G*g-&Hiy042~Dd`uK=08dP!*+3QQ#fCZ3B`c}>MBtJnd*p=`;xMnDF0fI&n)S^>E z`68KtE+F}EjMllHI4Ou>ju+#R=x#E?axsP#87@k*oWzO}%aKbDh1Fc6B9-Lqk`_KC zs47B^#4z=GJzVbzLwA_rL{Vhe2os6W7(sgt8>v2RdtFTnGVpZQbdU*cGO(y>a1bM@2t|l4h zZgrsmh`o^xxF#-&T9ctZY5^PN0LRCLSVg0G(NJlv5{=Vp571~s7X?ia zbU}>>O*<>`SuPdj<%}RiBN>iU#CTSS#Fea);>EO(meWmc&i0UM>!7J^V(levY*nt5 zae<1UTZXXK?1EwyBIs42LuN8T)dh0bA=5Ts-TN{q(_+*zaLqAbWL;>H3wf5z6@2)A z@h|d?Pt6~LonnG!`A_pSuW&~O+vQQfhvi`cHl83CkBSNBx8N~5QXD8NA7=CKuJ3y_ zrM#NTRutmx^?k3Wv-i(Q-|L&7U&-8_nleP8}YyMp0-tqgU|5?{P*LpIorDr#6craPqk(}5a3Vpuz zm%p!V>h6B`aK6z7^FLwodwoB9oyZ6j#>mkR;SuTIh5g7vkLwt_SP&EYkVp1ci6gLR$PFzXm$ahDO2eM zGElUEt!F_qf~?wR!#0+c0UxJpNwP>v^PmTzLB_o56%$4H7N=_pRo0>ujyjV>(=dUG{hkj2&| zU+@&iioWj%Bv~$(iE@On-CmOBd7h*gl3{SDfqMg%uLQW|HB>E#z*Akr@eSKTLyJnm zF8Of`GOdJQI+@I}Var=e6igWzC=N*z6lt1aT#MSCFN42ntf=kf1{^@jz_UxP3hSXa zRKYNJ*LD;tLN>xC*MLP)`bAqUnZWW>VjP1ngl1?$tU&9W#__n$@;t8T(HLG}V+>A5 z02k3CG{-ivRXZ!;sRY*|aZ!qkMj4ux_$HcW6B5UZ49!R_5>v&dEYDXg6;yp2(02tJ zX}u;^NV-7rZ8vAz{najLFWSEC6>SGiCc~<8=(^2@rP*b#F)ULhY7w}`HlVe-wuvt0 zSuj@M@bBWU;I;poKN6B6!)EzM^Hi^3M~2(wQGkc#VFDJMAQz6x;M%Wmgk$!6dpajI zl99P9zw4!)>#1nsA-R!?cBy@Tp4hVEnHM^GiWh&JT^Nl#`k4Fj8^;o9`H%7Kb8|mm zJyYH_G<;=d{G&6Ujl6PXi*Ap9F*$!}>b0X|>CW!b&Zi$X+`0LA-P?Zb{SWt!9QuCt z@=uq4eNfKNT>RnnqhsC^dlruK)8Aflc08Nu>i+GkcMlwX3(^_or-q>*d^y{(@Lv|P zd!N?{kwHpq$pv2)CN5k6$aRm@Bg5z9+Qa7`KUaU}hJCdS4M%G3*^s|&=s=#n*VXqRSAV(XouNcc9pr$dq^x*6(X;z6BJk&v literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cowboy.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cowboy.png new file mode 100644 index 0000000000000000000000000000000000000000..9c255c613b6081abcbb7602d27361d8717b7399b GIT binary patch literal 1371 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 literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cry.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/cry.png new file mode 100644 index 0000000000000000000000000000000000000000..dda95de8f96a1f27e1893d854b1af7f022d26e55 GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uGBwbBK{D72XiEBhjaDG}zd16s2gJVj5QmTSy zZen_BP-0{?RV8FpFdGn>*pZ_aMCvS0cvP)!15is5R>@zQ?f%pw0 z=D?e&YJ7Toggej7Fm%uSDRMDM>h?j!&V=h57jyD|iksAzopr0KdkCfdBvi literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dancer.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/dancer.png new file mode 100644 index 0000000000000000000000000000000000000000..4a307a4d4da930e1b99322437cf4dc21bb42903b GIT binary patch literal 15813 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 E0?*VvHUIzs literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/expressionless.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/expressionless.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6904de0622e2954c7ec4e765cc0540c0759818 GIT binary patch literal 1154 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 H`NHHs6Ys^i literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/flushed.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/flushed.png new file mode 100644 index 0000000000000000000000000000000000000000..2ca84e2af01239b489b3d1be13169caddddb8b18 GIT binary patch literal 1434 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 ONO(wuW=-?>0sjEWP9^{V literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/frowning2.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/frowning2.png new file mode 100644 index 0000000000000000000000000000000000000000..bbc46462e141c3547f1b40c9e77f045834967254 GIT binary patch literal 1215 zcmbVLOK8(z9FIC0|Uwu31sk z9mL@fFN%sFJBZ-H2cjrL)PnhzAdP@bzU|r-w1bK=M8E`~Cj!p=6?U zC-34&M|Ym-vm>b=V<@K+A5OW{pFXafhIfChr7 z=+`q@l#TBbRcQDW594zU3$qELq0zMzwHF{V2fB4LLVX^6K#{r@p*n(bHf}{hkKR_Y zLAsR4sHI+2(5S{eWP>YW0Rtd~bd5gK5#0zitt;Zacg;}bGz9fVs2QiS@gy0AHXwsO zo>sZ~Fc}hjTu=!61G`8+%kc~=FkFCUIgu4amLq2$3R|u3Ca8Y5_Dz(k5mn@&wxK?06y>lV_XNqUM(4i->^!k*5AU|8|^ zoUrN4CJLvFaTSZSv*YszGtyM+yTKoz%Rs=s?F9b9?$MJv;hxvSc&d;&AJSgkT z$LE@5o(~4Xp@2WiaWa=ffQ%U{h?zQP^pZRbV-ALfP$n0SJ0JSw{jOOD_%>qzd)$iK$pw@>cK%fy#Qt$N$y ziIKqJ&Z;*zBKJo1|8(kWW9_zV?!?#k8|0yzRpH5phXixYk8`KrRV0I3*59cZJoCJJ`{~m6RBJz9 r_4yn({K|M+d8I1x>Gk^;UsiV!cULT3H2Jgr2bL#dazeV++%@`nL{K#g2fUyHtS@QDmso`P~7cG}&rtU3UT>2?9&NmK0s zS)l5Jug!u8hSd%jxjf9LQ=(>@l?{Wnz-R4LwTi z45pcMDFJ$o_8|v!4rOxMP@g8~#O6(Sq#_~$6F?QOm_^GKD^X&BS44a7nkMiC6WA9e z7DeUL9eBca03M`5q{ar?@UTF!L7|P~U%)wr4bhB1vpmVLA|r?li!VI{^5*E>VpdX? ze4$g6=!LK((sa38rpf`zc6w-55CodxXpSS11?di2P_2-b+gxRkfU7x12^zMAdyHzq z?uStVDP0V~ETz-S#Fo31D3mg~qLyfuVrbL!;##nFVHW%=V?}E>H&_C67Pxl5qoI0q zH&?+ZcMo>t86q{}Hpf6kQHzqT^_#$gNhwO8Ka_6hA_sVmXY~LX3ThfD6nK^_=vvDyV4y*9MnUb}=R5?Q$U&nramzo7#_U{2DktBc zOLxoIcb6l7%)IpXoz!2Sr|yo6r{OcZ+gJT|L%DFY@5`~!wZpB`C+RB(Tkc*Gubdm6 zImLYQf$-xev7aXrUtb7+`^9HJT-);J?XB}4isJ`}{jd6G&#*U-Q+v9akL}CMO^wf9 zKR;4#935=Bc-(^9AHDRR`|G6q`%H4`7&ZUZ%{!A9?_HPPA71yTNM_T9l!TTL%w{_8Kg@%TzMWwa1M1XRt}9$Dpk91EN+){oRo)i|+; z-+I#L3-$XB9N3o8c*y$_0Gpl(>~Qu6lKT0kM?e%Rv#TbQa4TBzE@YzVBg<(Z0&G7whQ^k Ml5$469N+c&KPTkm`v3p{ literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hearts.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hearts.png new file mode 100644 index 0000000000000000000000000000000000000000..4639733791b63f61a3ac9950b347f09b01078b0e GIT binary patch literal 16179 zcmeI3ONbmr7{@CHL{|c$LL>+_6GcUPx~rel?aai@%*0)jS(n|BY)+;hHM?zQy2tL` z%Q~Q8zrDWp;)$hGO8|fqt1I;l@=HGV9mn4d{gE~NbANB;QUbsO50lR^@Zm>~0`R;a zw6@Z%<^|h}x<$v2TvQx%d$=|L9AEP z?4)VWmZW~aU+k;JDBhN!Wm%G}NQxrj8e*~+rp`bNlheZ><2ZGccyZ86gD4b8T*r-e z(@LR05>1{_zq-9dV7RGjjJe3=Z3;##tt+uzwb?adb@Ea1MPbf>Yy&plVApLE`Z)nlt#%; zv>@d~&LGZ9oCfU$0Ex2D4Gn??ZbTWnWpipc)MX5%*|cAd13dkmPCfE=NxxR>RV)z1n2v|6Jsm&W09t}|g*!z6V=4~<$L;FhbZr9fAaMWf_cqS4k2(S>bQR9#Qg zy|(EqhBXeIbDs%aM{#f!`RC%On=P206DNpF-b!ISdnYSwL^YfKb}-u}-&K+9D4M95 zx*~c$X_KQP5&D{MYARF>Q!Ps~?$b8m1m&UZ|I@LWai2yX4E`=!$LV8lvxN zj_7!R-p~`XJy5f<#AK9T8o1u zQ9JEBFROLk?u79$5Q=~fhVjxrHx zmnrUPG*ov|bZCvpHZ*c;WD;aplZw%d{Gh!z6GO2NjTVWKt4YVeH!#uU1u9fy>PoMO$&21CnvgHi#kz^n}xeymgW`byvSKjPG7tQIN4?g%hF64 zU4M%lJDuIEzNyIgks$dVx#nfs^%C1PFVn75&sV}AC4I{pN)_k4$c1AFV-sJpQPt3O zRWD0)G3~J)3{YpQ9^iXOLbiX1_vXxp7Unu$TI84$MvlXUlDiIPJK(SsU$*f*Uz%L> zXEw*lv2!>7OnY=Uqf)VW5()_0|d?=OUqJXeX zj*HEQQaLUP2;1bi*nB9J|d?=OUqJXeXj*HEQQaLUP2;1bi*nB9J|d?=OUqJXeXCa$IFtFtJ?@5}b_i?P>#v9|F`wSu>@(F9=sNdVq>3xK~4@b7N` z?8*TAei;D!0{~7&@4kBT9013``h`~GcCmhNfNSxG6Zk(8c<1bG@+SK|>BidT0r>R` z`6X;gtM%p9;O9@j|K!-W@`K;KaQn{rlh=ND;>&yAzxmkp<Szszd+) literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hugging.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/hugging.png new file mode 100644 index 0000000000000000000000000000000000000000..146af729064b96a972807421cd21d656c164409d GIT binary patch literal 1374 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uGBwbBK{D72XiEBhjaDG}zd16s2gJVj5QmTSy zZen_BP-lO)W`O zsL0L9E4HezRRWu91!RMS^_3LBN=mYAl^~9a@C{IK&M!(;Fx4~DO*S;PP%yXDGc>id zFf!3mFfuSS(>JixH#E^TFtjqTv@$SMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy z7U!21B?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}N>@2e7^0=Xz?c(ce=(9}l>FKkE5yj>M!KvA>6${-5@K-7WZas?fjV?(e#|pEq+? zhH<^^S>wl1&llSr|DEu>vC6VPQ}k0G&-Vqg&ziVC_w)We z==i>0@LeDOugyk(kGNb~V)k>jW|}L*lX|Z23*~Oi)Bd$y@B4h2Ii=D+*XjJ;X8O3E z>)&ag&;2~#=14Zj^FP{T_h%2V&|ru(U?>GrRwY4x!T-qx4CV*^gUYWuPZ!6Kid#14 zuJbho2(Vm`bYK6FVdQ&MBb@0IlO)W`O zsL0L9E4HezRRWu91!RMS^_3LBN=mYAl^~9a@C{IK&M!(;Fx4~DO*S;PP%yXDGc>id zFf!3mFfuSS(>JixH#E^TFtjqTv@$SMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy z7U!21B?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}NOLId5 z%haSKU4uju16|WplVsgQLlbk|L?c7tSm^wL{!Ss6O6_+IDC8xsd&IH;G)oYGdua$FAYGO%#QAmD%4lES} zWaO9R7iZ)bC^$QVV%=OpBRn%NCBM8_6BJDlU%R9hWtOF;xE1B+DuBb;Diezvi1R;0 ze+s$brw??LJ}9vuB_5a%Fhzox@T>sjz%x^79xw+L0kg^}_Y>N{Y*rWG6XN>+jBlDN z!;fR0|IYY+I_SQwM{{eJ`niQBn>*EipYT2~MK{Nbd2yB8%N_fOINxZmyV9+&0yichxKZ|l~$x87!Z zkH*P4M$fl9W_d8JY*53Spz}R;TskoKX z=g!w)z{4Wz^nUO6dH?GL9xEJaoXBrIDOZ<+B~Rmlifq@adx0M;FI}8=M)%^QdyCFq zSocDuJS^Z3vx>6uf#jpf2iGx}tN&2HD<%1&|Cry*leelWeD?gl^5*hqp#%o)2#$nS T!Jpzl3mH6J{an^LB{Ts5HfGJs literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/innocent.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/innocent.png new file mode 100644 index 0000000000000000000000000000000000000000..01ee7c2f754c917c80a392c4ab59b4abad4c6a0e GIT binary patch literal 1439 zcmb_beM}o=7(cTtF(_L!Xi(!k5B@+$dv|TG^e$9Zu4PnchouU-EpokkOHb%sy}PcZ zxX26y9cIyBSYl>OaApatEQ)MIK4%G$fisY}Fc)W>n-1ArrbNvotM36t{~(JozRCOj zJiq7ne7#ZS-I<;Ba2A3f+3s?uPv7-<_a?Zys2nfc9@1R3TD2V1Vw?gHhad+4>JD@D zzy~;?>E$UFywa@fe}GRAl~0<{sOxFjCo_y(Y%0Z=bWcI?K`7>0_1 z9jl={geSs+kXW8jKy||F=MxP)Enp>2p~Z0q0)&Caq498|q%v_kwt~yRv;K@@=!%He zV8>QT)q1K>R#pH?8LbAMG~3W3+DKBg&15M=O$2Gh2^uFY27+V=njuJZZD7!vA_N(q zvuw>4yxFmkrbQSWkHuofnAs>R^*Bk>G)|aslgR)j3~H04adCsB=4B9^K;;!NqKUGE z>WExGj%s!cGF^2c9PxP8fhBb2I1`kNvE_W@Oo zDm=_bFfXGFV|Qmmx*%l3>{3LS6t2-J^U*MnG`G`^!5^a_3Jf2lIJ4PC7|aAA7--&N zHE=;d830dNY-W>%vf`KJ#!MAdg=9@uLvjRVSv~7TXhDrA335z*LQm7G*G`~_ z`+!iU$YFFP&WyMLhkxh)s=n}FKd=CSXmqtHrNuR0szP}_rvGY(UCq2fd z#@lb5srqUn$|tXMH*dQ+UN+EC&|0_k`QD$pp6hU z_s|FSZux!Ky)anXo!ADQ8+uZ?47YO4=dDivKLa^(?Uy=;+3t2a{PC}g-)!5G+Ho)2 zIq(e=3|@uvw{&{;=ftrWp1yo+{&93q?u()5$YXZ}@-F1t6c{(Op51 literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/joy.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/joy.png new file mode 100644 index 0000000000000000000000000000000000000000..6bc95ee669d52efe9836473b180bccf7b1104dc1 GIT binary patch literal 1444 zcmb_beM}o=9KMZzmN_(z?cJ4r-AO5JuSgy3NLxdbDRA7qr6=^RyF1!K zmQ2io7#tX*W9&nguuL)s4EMntStLWo&`mSK#&8S4DI{|Yk|m2FOT_npqJNOZ7%#bd zKkoNDzvuV$QIYS>^z|9*5d=y16fk~m)!ub!@ar~h^ugsN)g4j;Qdmu}GC&->R1Q#2 zl&t`M!16V_hCvR3q{W3`NDX-lX-;hC?73)8l7<9Ppt5K(S|uuU(uOVa(r~X`;~2VV zqE_0lB~c-75$cj;fSUAX9Yu6qq!}kDoHXhPk|rpcAkpOqgWhC5 zO#7MqWnb`Q!y>90qj5ZuNaz#UdP%OpNs6Ly!hjnLI%uI&YDASy>O>_o#lQfClZBWn zNFu5+vgJ~>YQvz?r4XVquXlx5RF)G3Q-&wm7*6U5JQ~&FTC`SFKloe5s@6)dCI)an zP^4;^gY^h!rob?FPj;jkLN)XbS%5`hs~Cx^jsj8jFg6VS(enaNlVNkVndf;OOOQav z@kXVl$(q)JLeilHu-R&@)ywO9~&DWPoB%CrP8fexFNfA2_z6!9}1fy8+$IceyrHfHE!+NyZKaoR%Q1D*Kw<@ z`}5tQrw-MJDvpml8YsBhUpqc1pYLesJQOeKyx$yW1`iP5U#k10_rm3a#IfDz#MqU+ zWzUQrx4hRq`NyDVcDRK9^48Z4TYl-uegDkx)Y-hL$Z%WSR>98@w|2j8R@E10G BKPCVG literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/kissing.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/kissing.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc6f2ee44280e2d1c64512dbaa88621b06225cd GIT binary patch literal 1181 zcmbVLPiWIn7|*QA5QjU+aOxpuA_}I-OOv*VtGXr8)va}O)$M4OyslwQUY5MA*$$$+ zh4A-plvkxDn~ZL&qa%it5}KdWJa)F+B`NY&XMvemKL>wv}N9r5vC0R9LoqrhGUs zl`oo8qo!;z`}WeEp+X28hz&Y)DsG^J8D^1JA?N6sW9UT{JepyaoEpmY(<<^IEya_p z2@+{KCC7mzrv-60E$|@8@iGTQmIn$iD?FgGJ^b%Txug9ZcBw>@klmyQ^XVKk024Doa+1jozemWkb< zo+y$sE;Kw2#CgtfqPP~d16+W=-B?jOC{B8iE5HDa`zEPJsiOfVx%<1JNRfD>9QJKe z6r-XcbKHS0&T1Kk{E1t(rKD40N-7x=D{7ZQ2fAhx?r?{wD z{%D@Y6Y0q4xI7BvvOG-CB@^V6QF(jlaWrP#{e4CK=kwg_Yx1W@YUNPu&Y7LJPwgn_ z)Q5Xr-{!K{PcSbpOAA+%AMba6nbAKz(rV|~@AJLqDs4BWJ7&(aU!V36nz0|#4~S^P zh5W$Jl@`_Xs`j2}xL&=*EStLx_!&0HSOCv`3q-{Yg<}J@Whg{_m5S^q#d1 z8yg6MSexuovi|D7t84K$E;Og{(t_gss1FuUNp%1b)nOixNmCsFS)l5pM<0Vuf~Xxa za{Z`3)hlbz45~gR=$STV6GUg1XRF#EKx7^a7*>S(Ff&V$h902~3Mn>a$3W5O8FN72 zSURVT4Qi53b?qWMJsAs_0I8&B4q2}3MX0i_jQ9RELy=_&8jMgCr}|SFG6o$$3PF+9 zxKIb#E(JM3>fpmWNS@_HhLspDOtYNKN;1olOAm#uIeJ0PDv2dq_!Oav2-z~jluD&w zDHMdx0K-X=#IQWW^E5`#?x=-SkG9;_s)7Ps%`t3bK#TMh)jS+V5ej=+3Bj~esbyiy zT}l*A8RMxo!v$H!H2t{BXcuL{FE>_1ySY&tFj?TjVMoLDD703|ICpV6paeexY!*P#8|f=g+f(s(sGe%X`pJ`@NHMP++VqJ%mFHbP7cDMY8PaR z5J9&HZ88?~tKLp-J7`!sEVfu;EazD^R`TJW;;-=a|IHtRonriE z`K@`XSGXhn?eZw#!}2fz3r~=PM`iuh0RfNMzD#c}{^LpN^^M5Q@hxwsqaSDEFR$(V zG?#dPPkA>J8`sv^>H5pZHh+J(_v38h&8@C4_xC)%BA0S&3UT7|eBxBG`Rjw^)aa%o zJvCVG(3#shURqE#-S^`U4-p7AOk+?csYG+$i~MP#W>pgrx-_)*aFwwNLwsynTvyUjE?c2m;=Yd31(}{BnPwHx}O^BE7)IUE@1XdB= VR9zdjC>+JwL^7UMu6G|k{u5JajzItb literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/ok_hand.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/ok_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..677a3f045f18dbef35706fb256debd6cfdeb742f GIT binary patch literal 16210 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 KcCusd%YOkT#tq>B literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/persevere.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/persevere.png new file mode 100644 index 0000000000000000000000000000000000000000..743a6d40c6e5666a5038cb6d0d9dd09a6d2a30ef GIT binary patch literal 1366 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uGBwbBK{D72XiEBhjaDG}zd16s2gJVj5QmTSy zZen_BP-lO)W`O zsL0L9E4HezRRWu91!RMS^_3LBN=mYAl^~9a@C{IK&M!(;Fx4~DO*S;PP%yXDGc>id zFf!3mFfuSS(>JixH#E^TFtjqTv@$SMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy z7U!21B?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}N^As~9 z^R(1NT~i~2G~Fai6EoeUq$D%l6l2rGG!rumb7M0Tm^s+=n;97xn^`(KnVT3n8ydP= zT9~@HIk}md8kxDcI5|1H!t{FP6_+IDC8xsd&IH;G)$52?ua$FAYGO%#QAmD%4lES} zWaO9R7iZ)bC^$QVV%=OpBRn%NCBM8_6BJDlU%R9hWtOF;xE1B+DuBb;Diezvi1R;0 ze+s$brw??LJ}9vuB_5a%Fhzox@T>sjz%x^79xw+L0kcY@i}o>KHd_(k6XN>+jPLt> zuFtkP++An$^SIaENje+aR6p!@eX+yo-)Y}@o>>qFRYYnh~d4q!t&fglkZ18 zw{~kh+vYeSOZ3N4&p#)zeGpk6dCW3oO zwS0y<}O}(6Y z!7TMMQ=!UH*Pf-4GeSc}BpPiTC0FnX^RjKQ)cJJE=8yt=L#0s7o>!X|CCsyIo++o! k+$_a@L-)ix77hc3(kPzO{{3z8K$kFhy85}Sb4q9e049g-YXATM literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/pile_of_poo.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/pile_of_poo.png new file mode 100644 index 0000000000000000000000000000000000000000..9626a3582c6170668c4549747e593d5cfbe2107f GIT binary patch literal 1286 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 S`=7;%nj){;&-Bx8y!{uz^Fa6j literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/see_no_evil.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/see_no_evil.png new file mode 100644 index 0000000000000000000000000000000000000000..8c24967ce84d07bbbc4580b507144cd6f37ca42a GIT binary patch literal 1483 zcmb_bZA=?w9B(#F=7g9{qropbkA!Hny_deg-6*s4iquh7OE(a4c)fet9_3zoceJIT z7CN^1#wIZRu+2|SoikJ8=As~oo#SOV>6j2r)Tnd%VTs9{*%Cj@=YXOg$YP9_+&wS% z|NZ{I|J!r^`bUb_-@D#qG8KDknSikx@4B_{>#^Te50?_%)1)`ZVLi#Jz~tiP5J0>l z8vy~p@}2Q1P-!x)O$fmzy~$TcbFye*4I4{JR3O@9s@#%NSS|*1Bm^RYsvvC-AtX*XFr2~&n;9o)oT708S$yb1y4>is_P1kVaa6DlC)Z6HG&ZoMPWFJk)#<~n6*wxXH#ZLD=jcEK;u+F(FIvT z3`RC2cj!(ODqRXeRD8Y_Vo6(06igYGVikFDJDJj4~}n%>Y$M z0KP_*MPxD0w6KbXe;5A}p8v1;!=Nb4XqJC8PvHu7q_JHY1$bB)CLqBHQsJlwt~dJO znEmdr3wp+cz`|?0`1|gDUvEA4f;!zJoO?b#)7QRmIQvnAnLpH<)0+>s`c84xbFXyI z_UqF<(XqCMxdUCJU3@P7_}oy}5iSl z8R7g;I;XWvba7{U+s>pz)7iH3gXyVEli=#J$x66)(ZO5*Cutq4#lw2w<`{9o4 ziF_k-ar@_0rG1xuzsw;sPTFCH!X^3`n1;OLqn(-pns Vk9%Iq{|cp%_F*{6rXm)%D(LWo78FEKMDPV1bAs!hw7t#`Ma4k!yyW-$ z|NgIgIp++MOtQ@>Jl?t z##KPC)jr~Z&XH{180j}8lWJW@wv=UTzy?Ss%l3fd%jGyVWmm@g;F_h#DG2J1Q`1g$ zXF5m)dVmy}2yO787#WoqUX)@&cnv9Ve1zpBmJib$FLRR2@#M@yVKvVz$~iSPqlHg# zsuv+wX4z7y#FRn|^m(5Qfp2)0i!A7nfknLl2T`2D zo=%5gyP3?aVaK0I6iyji)?JooIM%jihh4ztfDZ>f1J|S2SRv!w zy^arSn`{LGEGOV0?!%(X3B#$IhAMGn!|_p zi+`GLerWz!>=YX`%Nxy8xxyV8Y-dLSA7+OMICz3QJSx>M79GW7R_sXUlap67#U%0M zSM~49+Uq~kFE4Aie~?dYUvYd}!#`siUR~Mn?0oXaubVC&WX|nv{>J!pbpPrzI~$*0 zNWC1>9{jw%uYKOllhKJY@?V$Qj}F%#DJ|Re)#880)5o?oJRVgZolD#}7Qs?Wzn?dP z7YgOFos;i+h}!Fywqo>`n%b5xPYmqcxab16P&qu5ULLwTd0@3V(R8ihyCaFQ6CXGB z- XRaYxMtf_9^bn1Bhj;8u6*7`fU)06UP@>)z>KzCE*LH_8t1| ei@Os1XgT; literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_smile.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/slight_smile.png new file mode 100644 index 0000000000000000000000000000000000000000..7fe967d03368e540b42e7ed43bd4ec5827d5af48 GIT binary patch literal 1253 zcmbVMTWHi+7!EDUTCB35tW}U06_hpCxizulSd$q$(u`$hu!E>HlblSmo#e#i)S0P> zBEBdn!m{|Hh`Oj05p~&BsG{|u;N?Y8min|P=!594?n_0~P_9wzU$-0?nxH zz6aU}qH&LvFQ9_jDe2H=v_OZc+Ac;DL|dZjYI+|)WD%4sCrMj^s}NpC3LGD0Ig#bVG{;MvC~-VFy(rA)8K#s~Qqx@c6sLL- zawV3nR4Pm*#6Yja@}elRoWKeKjWuY$<{+&~JO0YL1qJxJXSv9N4jEX~im)HWDeUP~ z2)3)LGlm_1I#D=fY*lkvp5a*A4&s{B_E8pma${C)KVNeJn*~1X_jFtjb7dWjbN6MU zKoNT*ZS^c%6s@d4z2627N-J>+e_;&EkOV`B@tjtqO@RkAh=p5eQH+Q*2!mowi~=*l znRPp};iF+i4yW3MSXhvGJ}HWd!YPUzl0$q*P6?4ZHtqOGb97MWwlMcJmj5DFl0Bdy z=;a|S*Snyr7b58QLYI`~pz1MlO}FJ3u;Q-`$}|B9aMA4ayky`{Xlsf<79e0L``Hj+M5TmJq|>dE=o%ilH*9smB1tMNzYqOXVK+P0>P z`&W!VP{&5L{B=9|qy3$mnKS-S9sY^gy>;%hOVSS=4WonNy_3TG;mt38NnpZn|1m#c zu?l4~xrzT?L}6WX@Ne0fR@(E`XXRtv3l4De zU4u&&u6eTP<%XVLxn=2jJC2O?{M<5J3?0rNy*qsRx!O}$`1j)erzdj1yA4-L%U|sq ey192(!+c`X#M~RV8qdDKL_|87Q7&)lIrtII(7Mh5 literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smile.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smile.png new file mode 100644 index 0000000000000000000000000000000000000000..547d0c1af61f249a1c16bf5ba0fb67ebdf794b93 GIT binary patch literal 1321 zcmbVLTWl0n7@n4B2o+Kd5~(DeOrrsHb}l=!bFoWzJF~S*y34vOB$_Lu~NDXaZgzG#KOMK|IrTs}BuPPcrkL z%m4lV_uqDA()TT2*0v18u;s~KH5ll>?$Ygb15;F==vSrs@G zCFV%wQyE-wT!8bT2&pq+5f`Ko!%HH|-Gj3<6QO8{VmOj!WLlDG2A^L9^5z;vIji=} z`$DHEF$iHUPr@%3OwC4%g}UeJg}%0 zoC=H*i0NDiRymbgFl>ACi9#u(e636|A)2zRAg)<$4`#vNG#1tNawBCxWr62ZTpiV; z*wFx^++E*MporMW8(k9>MJuU}Ua^1;lWLSeFCoJ;WR_=nO%OFw<5`L102d)eK@dq+ zWQBqd7Q#k^YuH%~FQ`&NjB}j8u?oW^BvFj;i3q1EoDz@6BTNIEv^}WVI%xPdk?(nI z__|nGae)RMH|IE|Mi*oT9q4$2P8nB}py~p?c9UrvPR&~vlxZ$%6}V;<7(K3I;j?*` z%|$r;yZGnu#{bP9g-B6Bv;3oZ8dsT43vz6}2EyQcP?%GvV>yNho`cCrDX!|d3^`1KNbai%Pd)t6i`=D2`P~WH&D}cTwLRl? zA$B`fbo_us7-rM`*Z%XuhWEWWhTy0};yM5G0^QtvV=ERuP+Gdb>0Fb0!M`o`acpAC zL-)s4oxfQxd{fNK?4G&d=M%8*=T2Y#ZTnPbYL&G@c`(kWk4eu>-ZFiVedCYKt+(%4 t9gnRkweNoE?K`LI*l^47dz+eX!gh|ev~Ion*b~ShmQ1A8m%AU?`WN3W+!+7> literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smiling_imp.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/smiling_imp.png new file mode 100644 index 0000000000000000000000000000000000000000..988f863b67fe66c11e186488baa644092ad40e5d GIT binary patch literal 1250 zcmbVLTWHi+7>d>R@NuosK%iYbH6^86)P$#;uR4UMXiF0h=}aI`6&3fFDu=XPN(`%R175NlJEP!|2o)` zS~06`ZXH1ovl1)Sw7>dq?R5N&i*r(V`3c3ds1@c>Npk_wXuupG6PDHv(m*r1wvK`Z zf|$O|%w$nE*(B@GVl*Galr0Cd38G5Y(Yi6{oVv7BU81 zK#EL=*7-n$3`-0zN)aKrgcLYF#BvhL2WgI%IZ5Vta^j(|nrr0cw7Psk3!fCKfRH1z zY^hXYN&yDC?JO@z63Yp!AkY{=dtElt%Czm(S1qW((_Pa+CbUW4qLzc5NTIN&l@Kf^ znVd9idlQMmDPzl;!}1KrT9zNzINC#L@X3uS(O#y@0c;w0u+!CXJ@WNcGS1zXg?u3P zMs9XZTokRSLcP-hHcF@ph5s;yX~^M-Vem#IM+ZSfqa{8VqNQLS&_O{IL%BQ%>zY`# zGbKM7h=#&}KsYGGcs?#g8+j=j5rwFzsv%Y7s@#O_AS!vt(RK`tJZ!}r>r;W0B?nlkaTzrQ)L_r+>yV8FaO z-1F#wb@N#7Q!_bybmwTBa$t?T@2@@2huqs8%}0ASpWk1+-nIVBpmk$IH8l~em(_8FH>55DTvFaFu@tM%R=>A_1qN~c=K zzWNaPMY|7U_{N0Vm?^(SLv26YC2Q4R&;9f74tR5H{%?hs?1H}GA8V%(v+vd2uG!o7 z{?+1`@`3$1@T3mCo@r+v&pWjK19KSj#rEC(}9Ic?9H`=|hdrNak?nsNcQ%lG~C&QzJ}v!!EN3OR^2Hm}(XPp4R1F zkOi_@eti){Fl@tqE!PdZrFKCvbxQUyl&f2ajbV{Jt|cq|0OAGEs~J(^?#v|u*VHJn zmy;ODN`OACZO8^)Lz$d1)UWU=vF8Om;tEKB4xo&?`hejGZj@M-E1*0_JgbmE39)354;0A)#}rAx zaSRWbV1Q*pRXOYNLt!rDXZTPk;7_n@l8>`&C>3VoEFVuLQ~p?$n>HLM8w#lE){yR1 zZt$U8Az=d<(?vT-SJ6SdiRM|&>$ zU`gsZbLaMgK70A-;+5gsQ_<0a@1r-KyLC-Je{AO|g}HyVZK1*(w;IkKYW{mkx_If> zsjl$%laaf#$>|b%t~2r5mDZ1o-0$=0iHbTiw(Igc@uh=3Pn4fxS6>!+WdBX)%^_zbh~`kJb9HmWhG7@tV0BI~Hk@ z-m0w)KJOcwYkT$JQ#+`oh3z#b=D!8}zQ(V(Ez`LdPoK;+-EVL=4#Gd?-fOJ<`1Scp zL#1IN!Yi-UU4MLj^EX?6!0xr&6D*~?CkKb Oo;T@aMx2c2hyMYtwCK+O literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue.png new file mode 100644 index 0000000000000000000000000000000000000000..3e650a63e6840075b938c930a4611912f4c12c1e GIT binary patch literal 1314 zcmbVLTWs4@7fd#D83R4zhmS*HmmO@I)BJ%B(HATFC$5Su`39Jfu`Lp2SK zWdG;#fB*mew|#?!%-S`#uc0VvZMI)61~T|M+Q~l^Syv!p15OR&A!Ohta3Ph@Q5n)% z3shhc0)6a>k6NYv)K$a#Sn5UoFL0G$A`Iam?avlH)dntv$ogWvY@E$fg5} zpo|(g&Jd=HAy`g6ziim{mJ&r$#`(bEgb>eJRuI>Mwug)GUm7cFd!;c4az*H&hO3c! z7~L%}$=&rG1&V}?vfVXFQ9xZqTEl`i&Z=>Syo7X9S9lGGnjz|}VMrQl012|P!D}qg zV=@qFb5k_7WIdn1^R6R;>+F{x{YI>W4GA%}}Lf704^|XsDdLhq> zxdMk9i+>TX|KI#^gcKJv%Qel@x*{DJY?nuY9F~U(+GK)UGAhUJdio18X3r1iN~x=- zb3cyQFmuOu>drq;4ZPCWa^8o>CZuz@^3U(3&o_*BUWmNCPnw_UKl9M8ucs2f)Xe=u z@}9@nP@uj%5I zk8@|ektZMR{`AANAuyyVaR(e^Gg(KS); moTm2NciS6JG0(Pjj#78tvihs-KXv>{JX6_JL7nOw-TMzezTP?j literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue_closed_eyes.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/stuck_out_tongue_closed_eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..a92049bb60ad19c5260cf18fac1aeff8a3bbbd1d GIT binary patch literal 1344 zcmbVLU2GIp6rNIDYYPbvJV-ThG7Sk!x;sC+)7cqzTic!O?%?jyY!})p80P2hcCtHj zr!&*;v=4-ssIe-L@?wIC1%k$ykOK8TsKqLRpwal$m>7`<6#@iIG#bS_ZMXW+5cOte z&b@cecg}bIp6$!0*EP2`V;Hth%7_JD`fpPs`li?oc_cQvsX@0NmfV_b1FTzv3cw{p zE`tJ)wegYjAdX>;V|sDW9n56~6&hjL*9m)uh0qul@A52JtpFESKv_2v#EthpAaGqv z5Cd$E%2`P;tY;={&_9tcsuLBJ*NCo8Jnjj|fB{??_l&CP2ws9%v@4*!e@znjqKaEd z5KE*6bA5Oc+5l(69U+yD#Bh!e(<~ojqU|_C(H$hklXNsh(E`N_6pb%00(rBwl28zP zmwlmAf*5vPOCZTwtro6D!q6_0G|%%S#gGgWLK-1w+;n9xWIAni3nFk-Ten;tnz(OK zR^X_cAQ01~5DY7qTQO`p%ZWlMBR$z7=`ckah9B3Ww&NDS-!xX$c8cQ`APc~Oqqd6b zQEID$QSR>U$X7&cgzdJDiXvA zXW1WyOpt!?_+IjtdFkrAy+6H^x-336WdyH}mcBaP`Rm8qu6y9zVd0On`PoA5_qPhK z?(8`{)_w?XnRzC1^ZoR-ihgE_+q=&p+_pEKkCvr}Zk$P9IuifxWY3k^x?Cx*7Zy`Q}_9e=T(KTrvN{YvN0bD3{7 z1reMs2WTXsZXw@)=f5xP(E$P=yeEm>MQ=f&0&4>6vB-3_>E(vG2K!5I?OK7j^~ltY z=Qg&V{p8~OMLhh`k><-YO;>Mkp=N$;4xU~!{*8TV&!(q$9mOx~leSBb?>;ECR`<8w z*VVT5*wK4h<^#bT{zc~A>ca)!HRlkEIABsL KFP`Yx^Wc6xQvPc59z= z2GS+E*vnj-KO6*wXj ztE8%>K3wqvfTxo@X)-AR&xlDTEeb667|zlRPthX9a3sx0v?$RGzP1SDEwJiRMJ=xR zLMNFRhR~NNs@ZHNo2jH13{i|IiWJRKEK4E{G8}WE5s_}#*|MO5&Ia*RF8UR z3ygAiXGgIjVj~?4Y*ZAZp?c=116-)7GJ#%_mTgHUU^8N>ZjqdjHb|4_>ZF+Fc@mf= zD+oNBN%3sU&PI5?ATq3?6f+#FFib%d)I49zq{Y0*a%#7lYGE}ugobN^mTw#RUc(md zh?SH87|;uJ&ug^0pl{fNUO4RexT3^W&)|CpY}fLd;l8*`t5K^Uu#W(%7;b&AAahfcn0qJcuIlw z?DBlicb{rMeW9H{seJb8BfP+!fL+r^bBN2_J;iP$NLVTN-~JB^J9l&2Ed&fTHLpk4 zYhSl*+I%0DdbhFVowmzuK?0thoe@5N>D-Myvx}oUbuN)eEKgUD@9Es#{sK2u8T@h6 zsgH6?zviAkcKp!9$tSnH|JK0t?w*dx4M^x@J4g zA&B4~;L*G2bq5cE7ZJRwAb6a35d0JLrCq0oGQ>dgeczYw=kxvjq}jMJH+yLo05Dgp z8m&~O@A(<_HI<7ECg!Qxrt73j2X=%($t4{OYregOTiAB@9=ylP0L<)qR-3l#YnnrR z!A@<2#19!7faR4Ww4H5CVFzz{fzJJW{f2{{t8*Jl9o54!?s?Vy2(RxqEN6e)QC)83 z8eC2^M&M&=!^GbSVlC0RA+N^H>9xqgp$XmAxlvHv? zt58N#UPP)W<#;4%NY#)8PackWi`=f(GAbv&n5J_*N<&Q)2ZMny$OT>LVNA4+t-TP7EgX}6G$JkmBQ#)|**teJZ9%0Qhv06F8HYJfo$j*2Qnms~E+#?|@m(#8n;L?T{ zxMUDtN!v8a+Q5;wi`_~@d^oJL=1q#>pYk8!-T$qh$bu5nVfkx###d}2)8pwXFy(Za zaKJVwVyj}_|5jydmT9h8=Dn9c*m24`S7KtCwi@fd!0{2f$uzZQl&s`SXY09{vWaXGg~X literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thinking.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thinking.png new file mode 100644 index 0000000000000000000000000000000000000000..6be3b18d7fd93e22faa11df3f0a7c3a3f2a8bdba GIT binary patch literal 15849 zcmeI3c~BEs9>;sis;yaPX8%~HYNobocVg6?b=T0{IY}FWkOV;qBA|dLO?L-cl5|WO z2zcK&-WT4tc;6`AqKM#yx8i*tc!0MeY$6JI5h<60^JUrNTFCsB9%nj1Eeqa9+XOGGC&%uG9zY(fl8)BGo4g) zW<(5;nL=nuX`sHP&W&*aY!r)2+%~J-g}DQyp12ri^Tn`K;*qc^0n#8op(M^6DKRik zN}}>p%Lr8AFVSfIP?gqSuIwO@Bd8iiv@oiaAt;7uF$9&=K2m*4&eAza3l?PzsZGcI z3y>zWtOJAL^z?MUbcG+|OoCCZRtqC?ST2`w3Yjaz&f;#F-PNWhh&PUrauH72!P1Of z!pFrEnN&7FD&-T^J+=L^In3s|RCZS_J&q&n#vL%~hrl))+?c0}jiTxs*{G*0Cc{C& zQIv~GbrKXOZ_{`nQySO0+TJ!JkSUF_vyF!0#_ZdH8p}@-bv}+%r_}?RBw)%)*|L>-rcsgpG8Lk<$ovUXDN}0*6@e&81+G@;;3mV= z&#Kx~jigWqhp07(QLa(S4Jc~TY7vtm$e;-J4-O7iYE2q%c)+zm*f6_`#q9)D+j5#~ zxl)-(q6lS?k#Y+z(~?SmS)xTl$Pf!6M@W@iAt#jH(13e`&_>Ehr%_~xld*Xgj01PN zD1Pz=NWHVSZiUrS^-O<^ZrG;g(QM#e-zF}BuBMv&f5)nUdwp~-4xq~oCrc>pVi{)! zP{B8f-%6sXfnS$;E39-g$<^`WRy~Fj{3fM$;T(M(>|%kk`X<+S@QG>!jX-bSL}=jN zbdL07%C6^jZLJJZ$xt*#F2|H8hARGp$T0-*Hr1nQI*5z0u<5vy3QFP@oWACmi1h9n z5`%$17BrH7#nN_?Nq4pPM*Z5Y>F`7{Zcm~}J?wS#7Wlg8V1DSV^w%R-Q~LFQdS^$& z3Ba#y%;2POZeqkRjI}x4@pY+hSA8_fh_e((8dYO*6qBpHr0aszD1Bm>8IrbS_{Q)Z zEj|XI^o_xt=OoVJ&58nQfjA_ASs14cXZ5rVPoiLlJxK@G7Xr$sLSi|f7) zZmbya;!gyA59cNl?pZRZ4sKB9tB>P1FKentuaP6%1Ec(Rtt(jV>l*)USFqaGwcfLb zoo4yIc^c|d40!R!Rt=13?p2M_t5qt6N(cKE`+7vuZps>Gq`A|~#cv`gcSw1Bd@CAt zjBm;jsHkHf`~wYhzq14Xp6W65rF~`7f3_U7I6t80tF&2kcOZw;u1sz3PfBW4MF>x zxLVdK{ob2N3p~$`?ytGvN9lN1d`2ms4nVSRTN&futUY{Hdk^2E9SI)mKTy5 zBgvbl-Z4p8S=e=HhOF{HaOsAiw4RbryL9hXz!fv3yR%f~(OArE!PJWMdfn2LZMJ9l`54=tyXI^8h?L(?xH4!VI4bm)ai5q0ReiwJ}@w_Q>RWr zK|$P=H-o`oG#X7NQ%Fci=gyr&Lqo&D!n$X@bGZ6*&GoO(XCsz$jHd<-MdFc zMMXzP$Hc_+=+UER&z`Zdv2k&6@$vD!diCnvyLX>Hefsw8+pk~0{{8zWBqZQCo|u?O z5Cln*6h&DqmZYSl-Mn>2$hWE|z6eQ&ZE@ z(zxrUZnrxlBO^02bI_ncg9i^DGGxfmp+koa8#a9S@DU?Mj2t;~)TmLTM~@yeX3W^J zW5*0Z)TvXaO`A4-`t%tyX3U&9bJna`vuDqq zGiT1+xpU{un>T;{{Os)P1q&7|T)1%2qD6}rFJ7`_$KR!V@P>6crT}7Z;yAdGge$Q>Ra#K6B>G*|TR$N=nY1J9qy4`3n~= zT)cSk(xpq6FJHcL<;vBoSFc^WR$5wm{rdGAH*Va#dGpq-TeolDzH{f!-Me@1-Me@H z{{06J9z1;b@X@13j~_pN^5n_Wr%#_fdsbFf_Wb$t7cXACeEIU#t5@aab#?Wt?1HEKoMWRRqPf5S z(*ymM9nqR|c7z#&V%*olvs8c0?*z4oU5#Mje>skSsZMSGV&dA;l9OGo{0S;8co_3M zdjz_n-;>`j{ObPkF>|ohkI1mxJGyqO_l}cKIqP3Bw|Lt>{;n>`f2B?d_$A(v)#K;) vDZhV5Y;N~<+irVUQLFFIbZDPz`>cV=ihoFNT^Loy<%Ysc5ynly2_ydt0i{2s literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsdown.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsdown.png new file mode 100644 index 0000000000000000000000000000000000000000..674b5dd6592c1e3428ca38a76238cbe449963a49 GIT binary patch literal 1223 zcmbVLOK8++9M9TCv?%VugNkTK6!EHBU;FLRR2@#OqNVQa3@Dd&{rye)i+Qr!qS zGRu}qC8iW)pxedrk|eQQfDHs_jG(=K8);?Q_8Mvm3h;E-bdU*c(pS_vU>}N7*weWX zEJsxrgl%s=Q8;C6S#wyP;aJP^sH$>3uh7K8z`&AdoZLOwlz>@c~U#7XJ72ukOfRS{eMb73~HW%^X+v1<& z8{eBh7CXiI&GJ?A)UI$x`rCz3z=wrl0ydr?7mvyym|la&Y=1UgNK{|9f4o(g{D1F< zYuTycTxFy<^Rlfv+CKBDt@3c+)Np?MlKTF9diq}L=IF!Q2q{6f0& zXy3cDzm1(~9>19Wc)R7pwLO&w#p#ja_+=H#|0kVXj+ad+m&sR`dWg5{HnwAAYf6a~ z%A?00iOUXitLpBYS(`ijpJskoPHa83qGjjkuYY0_L@JR{t~MP! F@)-sMvlajV literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsup.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/thumbsup.png new file mode 100644 index 0000000000000000000000000000000000000000..e52f8364ff61260b46b4083b7e73098b814d8c95 GIT binary patch literal 1218 zcmbVLNodqi7!K$`iVJ8FEs7z%D4I!LnpqM$md<3fqt0|TJ5#mAO!C^sHhD35b*4o@ zdJuZ^=s{6DxE!kD0)n7;P!v=U5x0vTL{P+vZK+jTU)oOfP>L8x-jeV8{(Uf&+`g=; zri!AdW$`8@Zl0mxT$u+3{>^LgAZXnMJ+mH z}5Yt82X;@+A%dI;MZRlYp?@#avI|{purhW%z z`;$4Xzgv@ZreP~xUzUl039(9-%^u5@%VB0(S0;P!nq%l`2<{FuGfou}DLRTANc(*O zRs(e*Iw<*oUkVB07Fyszfa4_&h%66eUXpo0&pr&X=I9-AM%gxNi=4tt7sj^Caivnp zSE}ZAC$WuI3mvHjqVoifR${;xI!zoe9CT6Nx!t z%biUWNf}pGZ4UT&&NRKarqM3Wz&~!xi*|E;HsmtUMZJzj>d{eKA(PxKY{&x=Z{%jj zAVpDo6r}Z<(86&g%#c4m-Oy!G6nP!$0aok?KsLmS0k#N&fE7iZ_p3qOAFR_VI`i=r zMF1f_77U7l0zgcPfSAw-B9X?35)vXoe}x;jT&!9etk^b)?OASML9QHipo)=`L#U_H z1*tBCk=uoAIvVw=9;7$s4NFHQcavA9nWz=$7>A&~%|RwTooCsY$A^E5e}=FBZ~i#q z6z4U|U(HjwA|2^%=SG1X=7tGcWP%(rD#s?%)nv@_sa?6))SLE^%c;p1Z4>wNqgT`4 z@9rMEnfZ1xG4;BACr2x@!Ppy&-Q*jvvcxg+t`it#J&8;Q1jQbJ4dgl z$8KhaPwn{ieBbcN_|&VmpHKD>?QG2vlPv3TCYhaD;GtTNeKlO)W`O zsL0L9E4HezRRWu91!RMS^_3LBN=mYAl^~9a@C{IK&M!(;Fx4~DO*S;PP%yXDGc>id zFf!3mFfuSS(>JixH#E^TFtjqTv@$SMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy z7U!21B?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}NH1jlF^AwXLBXbK=1B)bMm^s+=JDZzWn!A}hnwuC~8XCG< zI=VUsjz%x^79xw+L0kcZj%J=-hY<4xkC&cyt8Q+I5 z-oD!D^y`H8uM4T454rz2<@4~x>rc04J$dsKhR(tDtJEn%yz$l=%L}wOY>BKfqx0T|gq#`;sEiK@6U*elF{r5}E-07(yBV literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/unamused.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/unamused.png new file mode 100644 index 0000000000000000000000000000000000000000..342dd80e79b03c82f84b7d81a1017c951daa88df GIT binary patch literal 16276 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 literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/wink.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/wink.png new file mode 100644 index 0000000000000000000000000000000000000000..def8b2775ac1aeab2a233be49dede62fc7813ce0 GIT binary patch literal 1303 zcmbVLTWB0r7@j1wwCNTiR%k`*I8kg`=eoO@Ipc2A&CIS@o85-ZLKpGDvomLtF*}#e zoMd++Vri?Q6`!P{sIAdd(NasHRw)vVRg4i0T11QbAmUwH^reEeo=LLNhfvf5Gyl2# z-~WIA?ZJWkt!vw_Zl@?}ZMIJ@gfjeAwUK{1zAjJ12AnS8LAQcy&_`6tbjyg&+HeRJ z5HuURW>A8n+QzJ6372yHs^Quk40X7=?GZFZC3@-}G)54n%V@}QlFYeNQw(jHNoHp} zC*(X04O@NVJ{la)7me`|1DH(DRyt8vi2)m7NZ0ME6R7nhGjCTV`|z4)=y?@9l4KT0 zm2v~L=K6?^bKR^VMip8HoEQg+6uX(01hJbJ058T^K~x2x3L?F@7~;)0D{4W{Eczm+ zBr}Y$r}BKQR^w_>&h>|Q5dgpo5-&+C(O`pygJGR@g3hJ|9R-GOdDwCtI_LB>$cVj)tVg?3Km_r06PtAc3>^bCeOtu$A{Ja0t7<-i z*!7F9TWxm1z_5$mVA%C&O$)0o)0=i$j_KBduCPoCQR~RJ#*mruU7McIvuZ8F;orr- zfH(hd{&+%)51Zv5&C|Rh9T{$yMu8lbh6y=jf_yS6;Mv)|WXv8I=r5)(y`TH>lvYVo zzr3y=yZ^?|UR1w0nm9j|`Sp#=*_YI(#;%z@z)jvme|IwV$ISL4dppk@mcM_k_k%;R z1Md1=`4!LIeci>`{%=pF{+#VUKb3y#G5)T;*5BW`?aP-FUmf52$qULW`!`*9J8Si| z9;{va+nbq*#>Tmc_{Wp-tB-U&fA95QpV&4rzL9VlL0hJYU~wTocT&eUVM!1k61rxzDz#elXH!3Gqic@e b($X5CoX=NlAC~Sb61P+~o!5`{-nr*5kDk$y literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/yum.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/yum.png new file mode 100644 index 0000000000000000000000000000000000000000..29d1bf7761cae8471154e0c3f0f4c8e2c374a225 GIT binary patch literal 1318 zcmbVLZ*0_L81Fa(jJV{`1=%F5>7oI&*Y>XWr{!*JckSSGJ;$xU1;5a1-`h32_APD4 z^`KL|uZ!s0#|lg+o=Zu(&%>YKFB z`{(&R&+qwnyg#?IWnKF^48vNoyM(+i{cmjm{l#c&4v98bEVu)(4I!-b)b+c6qe-uPFjwP;rM+ z#3HGJ)Q@MN4e)3vMygCCfycQJ6Xg!&Ep-A`Q~1nXclIrqkK5AOJ_Tb<5SEiTf6n zA{=&81Y)`vf?-M0vSHI%N)$>N>7BiAfI<$(i-Z57p{ z)Y$-|+&$cpuZY<2FW5RNic%4vI&1*b%?c?3y@WJfp!M3&z!&n& z>nm{hckwUcwf~zx3X!7xX8A|+G_Fub`rGAEK!@dF0w$Uu8;#1u6Vub&Ta|Ru%^`*AvaeJcdh9_p0TW$6V9a%9Q_Luw%c9+ literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zipper_mouth.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zipper_mouth.png new file mode 100644 index 0000000000000000000000000000000000000000..37e137c0c9a370aa227ba71be694e748511fcb23 GIT binary patch literal 1296 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uGBwbBK{D72XiEBhjaDG}zd16s2gJVj5QmTSy zZen_BP-lO)W`O zsL0L9E4HezRRWu91!RMS^_3LBN=mYAl^~9a@C{IK&M!(;Fx4~DO*S;PP%yXDGc>id zFf!3mFfuSS(>JixH#E^TFtjqTv@$SMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy z7U!21B?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}NQ&U6J zG&3`EUE?%MLtRUAlSJJ_bF*aKL^DfEL(`Nb0~1pNm^s+=TNpdK8W>x+nwuCo8ydP= zTDXB?!_v{f$i>Lq&BYO>*E6rUBrz{J6=ruP&~B(+7rc6{oQqNuOY)0C^7C_GsURRD zza+mnBfmhw*%=h;<_a3&nRzMs<;9wyXoC3KCABECEH%ZgC_h&L9L`pmSlmFI{~`KQ z$PGVzpriCbi3KU~z=VJ)62ydO1t15WnNstBIj9JjRnmgOM1a|>J-{c#_5T^)nX9&b zI3Dx)MC7A=aW9W1r@1oBDV4dhId;;Nwq5;NS)NR#K^$kc7XCZ!vwq{eNmDz1p9;LR zCE?zB+j9#|rp@XEaktaVzNpBNLkdgYkkKj`@rS8H*0ua9Z$l?5LO`DIs!Xq0^h3RXjX*E(Ofn zU?b1m+{VFdcHq!KZ58EZM|cd~TZ6r09i~j27%!BgHCbx%q6KqAHtQVHU2|)e6_3U{ c77hc3n|nF7+CCTV2HMBq>FVdQ&MBb@03n#tHvj+t literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zzz.png b/runelite-client/src/main/resources/net/runelite/client/plugins/emojis/zzz.png new file mode 100644 index 0000000000000000000000000000000000000000..02fc33fe713d9f0bb2931f94aa5a2e5cb4b1e6ef GIT binary patch literal 16185 zcmeI3O^72!6vs;kWF6g;3yL7LSp-EpUEN71>E0yEOpVhJIcwIz~9t34kuOcj7Jg651MHIn{r?IL#o%B?aVvs$ERzp5s{p-C~ z^{dZIU)$Pz^7Qh9%K(7W8|%$&@=HFamhg8=J+p~_?)KL&g#g@hANkw?-g)-{0M6M? zXE)kyU(hXYkT-14METLc$F%{do*(&!bp=I&iF%G(%l-bzXF0*KYq^VR8@Bxh+H=+q z1GICv*|83ItNpewyvJN#J%EI``)tB+VYG8Nu?dIAz9kyz@ zy(sc^Ng57^`C%dN1wBdDG);nvq$nb;A%+KTWQ;^NJeveb<1|rd1&$v%o-2^JhUx7` zwOo!Qnmprv4g7X{lFALo^e{(hWcZSthtgmm&GQVSZ8UA2LI#p0!WWV7XW-RHcPsrn73CYEFs@tP~nbd8J%b8nWEd zDh0KmzT61#

z{i+m3nX+k<6AzLosW1;Zgk8<5SfXr{6tQd-O|hck9kOUEWz{s1Y?^W!KjXeQ$8Zn1 zb-Zh9B2-0L?kI|0DC-67aj57J y(ajnHcLa!SQjR39m@Pex+$HZ2;YY2@7ITp&o zqZb|5_J-kOY1HFxi^E%chTB7ST}mC(0@|f2k)i85|HhF!*%F=^c)E+z*>Qa2lny>` z6;&_7|Io-K<9U23rt5lk>5^SpZv@D|OSn$=BU6)(fp22A5g8|nlC7JGV_SOH3kF71cLqieNxs{wO4Gtj z&B=+bH@v#*?ob@Wj6t?z$*vj^a-;FX`w?VKSP NH(Hy`4_7b0^fxrFvZ??8 literal 0 HcmV?d00001 From 09595863cde0e1080a4aae5acfeae8df50bef4cb Mon Sep 17 00:00:00 2001 From: Lotto Date: Wed, 15 May 2019 20:38:09 +0200 Subject: [PATCH 14/14] xp tracker: fix on-screen information type label --- .../runelite/client/plugins/xptracker/XpInfoBoxOverlay.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java index 32b9a44bfe..5ff11871e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java @@ -110,12 +110,12 @@ class XpInfoBoxOverlay extends Overlay rightNum = snapshot.getActionsRemainingToGoal(); break; case XP_LEFT: - leftStr = config.onScreenDisplayMode().toString(); + leftStr = "XP Left"; rightNum = snapshot.getXpRemainingToGoal(); break; case XP_GAINED: default: - leftStr = config.onScreenDisplayMode().toString(); + leftStr = "XP Gained"; rightNum = snapshot.getXpGainedInSession(); break; }