Merge remote-tracking branch 'runelite/master'
This commit is contained in:
@@ -179,6 +179,18 @@ public interface ChatCommandsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "pets",
|
||||
name = "Pets Command",
|
||||
description = "Configures whether the player pet list command is enabled<br> !pets<br>" +
|
||||
" Note: Update your pet list by looking at the All Pets tab in the Collection Log"
|
||||
)
|
||||
default boolean pets()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 20,
|
||||
keyName = "clearSingleWord",
|
||||
name = "Clear Single Word",
|
||||
description = "Enable hot key to clear single word at a time"
|
||||
@@ -189,7 +201,7 @@ public interface ChatCommandsConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
position = 21,
|
||||
keyName = "clearEntireChatBox",
|
||||
name = "Clear Chat Box",
|
||||
description = "Enable hotkey to clear entire chat box"
|
||||
|
||||
@@ -28,14 +28,23 @@ package net.runelite.client.plugins.chatcommands;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -43,6 +52,7 @@ import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.IconID;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Player;
|
||||
@@ -57,9 +67,11 @@ import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.vars.AccountType;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID;
|
||||
import static net.runelite.api.widgets.WidgetID.COLLECTION_LOG_ID;
|
||||
import static net.runelite.api.widgets.WidgetID.GENERIC_SCROLL_GROUP_ID;
|
||||
import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatCommandManager;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
@@ -72,6 +84,7 @@ import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.chat.ChatClient;
|
||||
@@ -112,6 +125,7 @@ public class ChatCommandsPlugin extends Plugin
|
||||
"(?:<br>Overall time: <col=ff0000>(?<otime>[0-9:]+(?:\\.[0-9]+)?)</col>(?: \\(new personal best\\)|. Personal best: (?<opb>[0-9:]+(?:\\.[0-9]+)?)))?");
|
||||
private static final Pattern HS_KC_FLOOR_PATTERN = Pattern.compile("You have completed Floor (\\d) of the Hallowed Sepulchre! Total completions: <col=ff0000>([0-9,]+)</col>\\.");
|
||||
private static final Pattern HS_KC_GHC_PATTERN = Pattern.compile("You have opened the Grand Hallowed Coffin <col=ff0000>([0-9,]+)</col> times?!");
|
||||
private static final Pattern COLLECTION_LOG_ITEM_PATTERN = Pattern.compile("New item added to your collection log: (.*)");
|
||||
|
||||
private static final String TOTAL_LEVEL_COMMAND_STRING = "!total";
|
||||
private static final String PRICE_COMMAND_STRING = "!price";
|
||||
@@ -128,9 +142,11 @@ public class ChatCommandsPlugin extends Plugin
|
||||
private static final String DUEL_ARENA_COMMAND = "!duels";
|
||||
private static final String LEAGUE_POINTS_COMMAND = "!lp";
|
||||
private static final String SOUL_WARS_ZEAL_COMMAND = "!sw";
|
||||
private static final String PET_LIST_COMMAND = "!pets";
|
||||
|
||||
@VisibleForTesting
|
||||
static final int ADV_LOG_EXPLOITS_TEXT_INDEX = 1;
|
||||
static final int COL_LOG_ENTRY_HEADER_TITLE_INDEX = 0;
|
||||
|
||||
private static final Map<String, String> KILLCOUNT_RENAMES = ImmutableMap.of(
|
||||
"Barrows chest", "Barrows Chests"
|
||||
@@ -139,15 +155,20 @@ public class ChatCommandsPlugin extends Plugin
|
||||
private boolean bossLogLoaded;
|
||||
private boolean advLogLoaded;
|
||||
private boolean scrollInterfaceLoaded;
|
||||
private boolean collectionLogLoaded;
|
||||
private String pohOwner;
|
||||
private HiscoreEndpoint hiscoreEndpoint; // hiscore endpoint for current player
|
||||
private String lastBossKill;
|
||||
private int lastBossTime = -1;
|
||||
private double lastPb = -1;
|
||||
private int modIconIdx = -1;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ChatCommandsConfig config;
|
||||
|
||||
@@ -181,6 +202,9 @@ public class ChatCommandsPlugin extends Plugin
|
||||
@Inject
|
||||
private RuneLiteConfig runeLiteConfig;
|
||||
|
||||
@Inject
|
||||
private Gson gson;
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
@@ -201,6 +225,9 @@ public class ChatCommandsPlugin extends Plugin
|
||||
chatCommandManager.registerCommandAsync(GC_COMMAND_STRING, this::gambleCountLookup, this::gambleCountSubmit);
|
||||
chatCommandManager.registerCommandAsync(DUEL_ARENA_COMMAND, this::duelArenaLookup, this::duelArenaSubmit);
|
||||
chatCommandManager.registerCommandAsync(SOUL_WARS_ZEAL_COMMAND, this::soulWarsZealLookup);
|
||||
chatCommandManager.registerCommandAsync(PET_LIST_COMMAND, this::petListLookup, this::petListSubmit);
|
||||
|
||||
clientThread.invoke(this::loadPetIcons);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,6 +253,7 @@ public class ChatCommandsPlugin extends Plugin
|
||||
chatCommandManager.unregisterCommand(GC_COMMAND_STRING);
|
||||
chatCommandManager.unregisterCommand(DUEL_ARENA_COMMAND);
|
||||
chatCommandManager.unregisterCommand(SOUL_WARS_ZEAL_COMMAND);
|
||||
chatCommandManager.unregisterCommand(PET_LIST_COMMAND);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -272,6 +300,69 @@ public class ChatCommandsPlugin extends Plugin
|
||||
return personalBest == null ? 0 : personalBest;
|
||||
}
|
||||
|
||||
private void loadPetIcons()
|
||||
{
|
||||
final IndexedSprite[] modIcons = client.getModIcons();
|
||||
if (modIconIdx != -1 || modIcons == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Pet[] pets = Pet.values();
|
||||
final IndexedSprite[] newModIcons = Arrays.copyOf(modIcons, modIcons.length + pets.length);
|
||||
modIconIdx = modIcons.length;
|
||||
|
||||
for (int i = 0; i < pets.length; i++)
|
||||
{
|
||||
final Pet pet = pets[i];
|
||||
|
||||
final BufferedImage image = ImageUtil.resizeImage(itemManager.getImage(pet.getIconID()), 18, 16);
|
||||
final IndexedSprite sprite = ImageUtil.getImageIndexedSprite(image, client);
|
||||
newModIcons[modIconIdx + i] = sprite;
|
||||
}
|
||||
|
||||
client.setModIcons(newModIcons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of owned pets for the local player
|
||||
*
|
||||
* @param petList The total list of owned pets for the local player
|
||||
*/
|
||||
private void setPetList(List<Pet> petList)
|
||||
{
|
||||
if (petList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
configManager.setRSProfileConfiguration("chatcommands", "pets",
|
||||
gson.toJson(petList));
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the list of owned pets for the local player
|
||||
*/
|
||||
private List<Pet> getPetList()
|
||||
{
|
||||
String petListJson = configManager.getRSProfileConfiguration("chatcommands", "pets",
|
||||
String.class);
|
||||
|
||||
List<Pet> petList;
|
||||
try
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
petList = gson.fromJson(petListJson, new TypeToken<List<Pet>>(){}.getType());
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
catch (JsonSyntaxException ex)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return petList != null ? petList : Collections.emptyList();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
@@ -431,6 +522,24 @@ public class ChatCommandsPlugin extends Plugin
|
||||
lastBossKill = null;
|
||||
lastBossTime = -1;
|
||||
}
|
||||
|
||||
matcher = COLLECTION_LOG_ITEM_PATTERN.matcher(message);
|
||||
if (matcher.find())
|
||||
{
|
||||
String item = matcher.group(1);
|
||||
Pet pet = Pet.findPet(item);
|
||||
|
||||
if (pet != null)
|
||||
{
|
||||
List<Pet> petList = new ArrayList<>(getPetList());
|
||||
if (!petList.contains(pet))
|
||||
{
|
||||
log.debug("New pet added: {}", pet);
|
||||
petList.add(pet);
|
||||
setPetList(petList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -490,6 +599,39 @@ public class ChatCommandsPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
if (collectionLogLoaded && (pohOwner == null || pohOwner.equals(client.getLocalPlayer().getName())))
|
||||
{
|
||||
collectionLogLoaded = false;
|
||||
|
||||
Widget collectionLogEntryHeader = client.getWidget(WidgetInfo.COLLECTION_LOG_ENTRY_HEADER);
|
||||
if (collectionLogEntryHeader != null && collectionLogEntryHeader.getChildren() != null)
|
||||
{
|
||||
Widget entryTitle = collectionLogEntryHeader.getChild(COL_LOG_ENTRY_HEADER_TITLE_INDEX);
|
||||
// Make sure that the player is looking in the All Pets tab of the collection log
|
||||
if (entryTitle.getText().equals("All Pets"))
|
||||
{
|
||||
Widget collectionLogEntryItems = client.getWidget(WidgetInfo.COLLECTION_LOG_ENTRY_ITEMS);
|
||||
if (collectionLogEntryItems != null && collectionLogEntryItems.getChildren() != null)
|
||||
{
|
||||
List<Pet> petList = new ArrayList<>();
|
||||
for (Widget child : collectionLogEntryItems.getChildren())
|
||||
{
|
||||
if (child.getOpacity() == 0)
|
||||
{
|
||||
Pet pet = Pet.findPet(Text.removeTags(child.getName()));
|
||||
if (pet != null)
|
||||
{
|
||||
petList.add(pet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setPetList(petList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bossLogLoaded && (pohOwner == null || pohOwner.equals(client.getLocalPlayer().getName())))
|
||||
{
|
||||
bossLogLoaded = false;
|
||||
@@ -566,6 +708,9 @@ public class ChatCommandsPlugin extends Plugin
|
||||
case ADVENTURE_LOG_ID:
|
||||
advLogLoaded = true;
|
||||
break;
|
||||
case COLLECTION_LOG_ID:
|
||||
collectionLogLoaded = true;
|
||||
break;
|
||||
case KILL_LOGS_GROUP_ID:
|
||||
bossLogLoaded = true;
|
||||
break;
|
||||
@@ -583,6 +728,10 @@ public class ChatCommandsPlugin extends Plugin
|
||||
case LOADING:
|
||||
case HOPPING:
|
||||
pohOwner = null;
|
||||
break;
|
||||
case LOGGED_IN:
|
||||
loadPetIcons();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,6 +1148,103 @@ public class ChatCommandsPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the pet list for the player who triggered !pets
|
||||
*
|
||||
* @param chatMessage The chat message containing the command.
|
||||
* @param message The chat message in string format
|
||||
* <p>
|
||||
*/
|
||||
private void petListLookup(ChatMessage chatMessage, String message)
|
||||
{
|
||||
if (!config.pets())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChatMessageType type = chatMessage.getType();
|
||||
|
||||
final String player;
|
||||
if (type.equals(ChatMessageType.PRIVATECHATOUT))
|
||||
{
|
||||
player = client.getLocalPlayer().getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
player = Text.sanitize(chatMessage.getName());
|
||||
}
|
||||
|
||||
Set<Integer> playerPetList;
|
||||
try
|
||||
{
|
||||
playerPetList = chatClient.getPetList(player);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.debug("unable to lookup pet list", ex);
|
||||
|
||||
if (player.equals(client.getLocalPlayer().getName()))
|
||||
{
|
||||
String response = "Open the 'All Pets' tab in the Collection Log to update your pet list";
|
||||
log.debug("Setting response {}", response);
|
||||
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||
messageNode.setValue(response);
|
||||
client.refreshChat();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ChatMessageBuilder responseBuilder = new ChatMessageBuilder().append("Pets: ")
|
||||
.append("(" + playerPetList.size() + ")");
|
||||
|
||||
// Append pets that the player owns
|
||||
Pet[] pets = Pet.values();
|
||||
for (Pet pet : pets)
|
||||
{
|
||||
if (playerPetList.contains(pet.getIconID()))
|
||||
{
|
||||
responseBuilder.append(" ").img(modIconIdx + pet.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
String response = responseBuilder.build();
|
||||
|
||||
log.debug("Setting response {}", response);
|
||||
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||
messageNode.setValue(response);
|
||||
client.refreshChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits the pet list for the local player
|
||||
*
|
||||
* @param chatInput The chat message containing the command.
|
||||
* @param value The chat message
|
||||
*/
|
||||
private boolean petListSubmit(ChatInput chatInput, String value)
|
||||
{
|
||||
final String playerName = client.getLocalPlayer().getName();
|
||||
|
||||
executor.execute(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Integer> petList = getPetList().stream().map(Pet::getIconID).collect(Collectors.toList());
|
||||
chatClient.submitPetList(playerName, petList);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.warn("unable to submit pet list", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
chatInput.resume();
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the item price and changes the original message to the
|
||||
* response.
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Illya Myshakov <https://github.com/IllyaMyshakov>
|
||||
* 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.chatcommands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
enum Pet
|
||||
{
|
||||
ABYSSAL_ORPHAN("Abyssal orphan", ItemID.ABYSSAL_ORPHAN),
|
||||
IKKLE_HYDRA("Ikkle hydra", ItemID.IKKLE_HYDRA),
|
||||
CALLISTO_CUB("Callisto cub", ItemID.CALLISTO_CUB),
|
||||
HELLPUPPY("Hellpuppy", ItemID.HELLPUPPY),
|
||||
PET_CHAOS_ELEMENTAL("Pet chaos elemental", ItemID.PET_CHAOS_ELEMENTAL),
|
||||
PET_ZILYANA("Pet zilyana", ItemID.PET_ZILYANA),
|
||||
PET_DARK_CORE("Pet dark core", ItemID.PET_DARK_CORE),
|
||||
PET_DAGANNOTH_PRIME("Pet dagannoth prime", ItemID.PET_DAGANNOTH_PRIME),
|
||||
PET_DAGANNOTH_SUPREME("Pet dagannoth supreme", ItemID.PET_DAGANNOTH_SUPREME),
|
||||
PET_DAGANNOTH_REX("Pet dagannoth rex", ItemID.PET_DAGANNOTH_REX),
|
||||
TZREKJAD("Tzrek-jad", ItemID.TZREKJAD),
|
||||
PET_GENERAL_GRAARDOR("Pet general graardor", ItemID.PET_GENERAL_GRAARDOR),
|
||||
BABY_MOLE("Baby mole", ItemID.BABY_MOLE),
|
||||
NOON("Noon", ItemID.NOON),
|
||||
JALNIBREK("Jal-nib-rek", ItemID.JALNIBREK),
|
||||
KALPHITE_PRINCESS("Kalphite princess", ItemID.KALPHITE_PRINCESS),
|
||||
PRINCE_BLACK_DRAGON("Prince black dragon", ItemID.PRINCE_BLACK_DRAGON),
|
||||
PET_KRAKEN("Pet kraken", ItemID.PET_KRAKEN),
|
||||
PET_KREEARRA("Pet kree'arra", ItemID.PET_KREEARRA),
|
||||
PET_KRIL_TSUTSAROTH("Pet k'ril tsutsaroth", ItemID.PET_KRIL_TSUTSAROTH),
|
||||
SCORPIAS_OFFSPRING("Scorpia's offspring", ItemID.SCORPIAS_OFFSPRING),
|
||||
SKOTOS("Skotos", ItemID.SKOTOS),
|
||||
PET_SMOKE_DEVIL("Pet smoke devil", ItemID.PET_SMOKE_DEVIL),
|
||||
VENENATIS_SPIDERLING("Venenatis spiderling", ItemID.VENENATIS_SPIDERLING),
|
||||
VETION_JR("Vet'ion jr.", ItemID.VETION_JR),
|
||||
VORKI("Vorki", ItemID.VORKI),
|
||||
PHOENIX("Phoenix", ItemID.PHOENIX),
|
||||
PET_SNAKELING("Pet snakeling", ItemID.PET_SNAKELING),
|
||||
OLMLET("Olmlet", ItemID.OLMLET),
|
||||
LIL_ZIK("Lil' zik", ItemID.LIL_ZIK),
|
||||
BLOODHOUND("Bloodhound", ItemID.BLOODHOUND),
|
||||
PET_PENANCE_QUEEN("Pet penance queen", ItemID.PET_PENANCE_QUEEN),
|
||||
HERON("Heron", ItemID.HERON),
|
||||
ROCK_GOLEM("Rock golem", ItemID.ROCK_GOLEM),
|
||||
BEAVER("Beaver", ItemID.BEAVER),
|
||||
BABY_CHINCHOMPA("Baby chinchompa", ItemID.BABY_CHINCHOMPA),
|
||||
GIANT_SQUIRREL("Giant squirrel", ItemID.GIANT_SQUIRREL),
|
||||
TANGLEROOT("Tangleroot", ItemID.TANGLEROOT),
|
||||
ROCKY("Rocky", ItemID.ROCKY),
|
||||
RIFT_GUARDIAN("Rift guardian", ItemID.RIFT_GUARDIAN),
|
||||
HERBI("Herbi", ItemID.HERBI),
|
||||
CHOMPY_CHICK("Chompy chick", ItemID.CHOMPY_CHICK),
|
||||
SRARACHA("Sraracha", ItemID.SRARACHA),
|
||||
SMOLCANO("Smolcano", ItemID.SMOLCANO),
|
||||
YOUNGLLEF("Youngllef", ItemID.YOUNGLLEF),
|
||||
LITTLE_NIGHTMARE("Little nightmare", ItemID.LITTLE_NIGHTMARE),
|
||||
LIL_CREATOR("Lil' creator", ItemID.LIL_CREATOR),
|
||||
TINY_TEMPOR("Tiny tempor", ItemID.TINY_TEMPOR);
|
||||
|
||||
private final String name;
|
||||
private final Integer iconID;
|
||||
|
||||
static Pet findPet(String petName)
|
||||
{
|
||||
for (Pet pet : values())
|
||||
{
|
||||
if (pet.name.equals(petName))
|
||||
{
|
||||
return pet;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -207,8 +207,8 @@ public class CoordinateClue extends ClueScroll implements TextClueScroll, Locati
|
||||
.put(new WorldPoint(2484, 4016, 0), new CoordinateClueInfo("Northeast corner of the Island of Stone.", ARMADYLEAN_OR_BANDOSIAN_GUARD))
|
||||
.put(new WorldPoint(2222, 3331, 0), new CoordinateClueInfo("Prifddinas, west of the Tower of Voices", ARMADYLEAN_OR_BANDOSIAN_GUARD))
|
||||
.put(new WorldPoint(3560, 3987, 0), new CoordinateClueInfo("Lithkren. Digsite pendant teleport if unlocked, otherwise take rowboat from west of Mushroom Meadow Mushtree.", ARMADYLEAN_OR_BANDOSIAN_GUARD))
|
||||
.put(new WorldPoint(2318, 2954, 0), new CoordinateClueInfo("North-east corner of the Isle of Souls.", ARMADYLEAN_OR_BANDOSIAN_GUARD))
|
||||
.put(new WorldPoint(2094, 2889, 0), new CoordinateClueInfo("West side of the Isle of Souls.", ARMADYLEAN_OR_BANDOSIAN_GUARD))
|
||||
.put(new WorldPoint(2318, 2954, 0), new CoordinateClueInfo("North-east corner of the Isle of Souls.", BANDOSIAN_GUARD))
|
||||
.put(new WorldPoint(2094, 2889, 0), new CoordinateClueInfo("West side of the Isle of Souls.", ARMADYLEAN_GUARD))
|
||||
.put(new WorldPoint(1451, 3509, 0), new CoordinateClueInfo("Ruins of Morra.", ARMADYLEAN_OR_BANDOSIAN_GUARD))
|
||||
// Master
|
||||
.put(new WorldPoint(2178, 3209, 0), new CoordinateClueInfo("South of Iorwerth Camp.", BRASSICAN_MAGE))
|
||||
|
||||
@@ -327,7 +327,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("Elvish onions.", new WorldPoint(3303, 6092, 0), "Dig in the onion patch east of the Prifddinas allotments."),
|
||||
new CrypticClue("Dig by the Giant's Den entrance, looking out over Lake Molch.", new WorldPoint(1418, 3591, 0), "South-east of Lake Molch in Zeah, outside the cave entrance."),
|
||||
new CrypticClue("Search the crates in the fruit store just east of the Hosidius town centre.", CRATES_27533, new WorldPoint(1798, 3612, 0), "Search the crates in the back room of the Hosidius fruit store."),
|
||||
new CrypticClue("A graceful man of many colours, his crates must be full of many delights.", "Hill Giant", CRATE_42067, new WorldPoint(1506, 3591, 2), "Kill any Hill Giant for a medium key. Then search the crate on the top floor of Osten's clothing shop in Shayzien."),
|
||||
new CrypticClue("A graceful man of many colours, his crates must be full of many delights.", "Hill Giant", CRATE_42067, new WorldPoint(1506, 3590, 2), "Kill any Hill Giant for a medium key. Then search the crate on the top floor of Osten's clothing shop in Shayzien."),
|
||||
new CrypticClue("Search the basket of apples in an orchard, south of the unknown grave surrounded by white roses.", APPLE_BASKET, new WorldPoint(1718, 3626, 0), "Search the middle apple basket in the apple orchard north of Hosidius."),
|
||||
new CrypticClue("Dig in the lair of red wings, within the temple of the Sun and Moon.", new WorldPoint(1820, 9935, 0), "Forthos Dungeon. In the center of the red dragons.")
|
||||
);
|
||||
|
||||
@@ -41,8 +41,12 @@ public enum Enemy
|
||||
ZAMORAK_WIZARD("Zamorak Wizard"),
|
||||
//appears for hard clue coordinate steps not in the wilderness
|
||||
SARADOMIN_WIZARD("Saradomin Wizard"),
|
||||
//appears for elite clue coordinate steps all areas
|
||||
//appears for elite clue coordinate steps in most areas
|
||||
ARMADYLEAN_OR_BANDOSIAN_GUARD("Armadylean OR Bandosian Guard"),
|
||||
//appears for elite clue coordinate steps on the west side of the Isle of Souls
|
||||
ARMADYLEAN_GUARD("Armadylean Guard"),
|
||||
//appears for elite clue coordinate steps on the east side of the Isle of Souls
|
||||
BANDOSIAN_GUARD("Bandosian Guard"),
|
||||
//appears for master clue coordinate and hot cold clues when single-way combat
|
||||
BRASSICAN_MAGE("Brassican Mage"),
|
||||
//appears for master clue coordinate and hot cold clues when multi-way combat
|
||||
|
||||
@@ -29,7 +29,6 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Data
|
||||
@@ -66,11 +65,4 @@ class GroundItem
|
||||
{
|
||||
return lootType != LootType.UNKNOWN;
|
||||
}
|
||||
|
||||
@Value
|
||||
static class GroundItemKey
|
||||
{
|
||||
private int itemId;
|
||||
private WorldPoint location;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,4 +403,26 @@ public interface GroundItemsConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showLootbeamForHighlighted",
|
||||
name = "Highlighted item lootbeams",
|
||||
description = "Configures lootbeams to show for all highlighted items.",
|
||||
position = 30
|
||||
)
|
||||
default boolean showLootbeamForHighlighted()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showLootbeamTier",
|
||||
name = "Lootbeam tier",
|
||||
description = "Configures which price tiers will trigger a lootbeam",
|
||||
position = 31
|
||||
)
|
||||
default HighlightTier showLootbeamTier()
|
||||
{
|
||||
return HighlightTier.HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import net.runelite.api.coords.WorldPoint;
|
||||
import static net.runelite.client.plugins.grounditems.GroundItemsPlugin.MAX_QUANTITY;
|
||||
import net.runelite.client.plugins.grounditems.config.DespawnTimerMode;
|
||||
import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.MENU;
|
||||
import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.NONE;
|
||||
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
@@ -107,7 +108,8 @@ public class GroundItemsOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final boolean dontShowOverlay = (config.itemHighlightMode() == MENU || plugin.isHideAll()) && !plugin.isHotKeyPressed();
|
||||
final boolean dontShowOverlay = (config.itemHighlightMode() == MENU || config.itemHighlightMode() == NONE
|
||||
|| plugin.isHideAll()) && !plugin.isHotKeyPressed();
|
||||
|
||||
if (dontShowOverlay && !config.highlightTiles())
|
||||
{
|
||||
|
||||
@@ -28,7 +28,9 @@ package net.runelite.client.plugins.grounditems;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.EvictingQueue;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
@@ -38,7 +40,7 @@ import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
@@ -71,6 +73,7 @@ import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
@@ -83,7 +86,7 @@ import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.grounditems.config.HighlightTier;
|
||||
import static net.runelite.client.plugins.grounditems.config.ItemHighlightMode.OVERLAY;
|
||||
import net.runelite.client.plugins.grounditems.config.ItemHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
|
||||
import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.BOTH;
|
||||
import static net.runelite.client.plugins.grounditems.config.MenuHighlightMode.NAME;
|
||||
@@ -158,6 +161,9 @@ public class GroundItemsPlugin extends Plugin
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@@ -177,12 +183,13 @@ public class GroundItemsPlugin extends Plugin
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
@Getter
|
||||
private final Map<GroundItem.GroundItemKey, GroundItem> collectedGroundItems = new LinkedHashMap<>();
|
||||
private final Table<WorldPoint, Integer, GroundItem> collectedGroundItems = HashBasedTable.create();
|
||||
private List<PriceHighlight> priceChecks = ImmutableList.of();
|
||||
private LoadingCache<NamedQuantity, Boolean> highlightedItems;
|
||||
private LoadingCache<NamedQuantity, Boolean> hiddenItems;
|
||||
private final Queue<Integer> droppedItemQueue = EvictingQueue.create(16); // recently dropped items
|
||||
private int lastUsedItem;
|
||||
private final Map<WorldPoint, Lootbeam> lootbeams = new HashMap<>();
|
||||
|
||||
@Provides
|
||||
GroundItemsConfig provideConfig(ConfigManager configManager)
|
||||
@@ -213,6 +220,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
hiddenItemList = null;
|
||||
highlightedItemsList = null;
|
||||
collectedGroundItems.clear();
|
||||
clientThread.invokeLater(this::removeAllLootbeams);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -230,6 +238,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
collectedGroundItems.clear();
|
||||
lootbeams.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,19 +249,23 @@ public class GroundItemsPlugin extends Plugin
|
||||
Tile tile = itemSpawned.getTile();
|
||||
|
||||
GroundItem groundItem = buildGroundItem(tile, item);
|
||||
|
||||
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
|
||||
GroundItem existing = collectedGroundItems.putIfAbsent(groundItemKey, groundItem);
|
||||
GroundItem existing = collectedGroundItems.get(tile.getWorldLocation(), item.getId());
|
||||
if (existing != null)
|
||||
{
|
||||
existing.setQuantity(existing.getQuantity() + groundItem.getQuantity());
|
||||
// The spawn time remains set at the oldest spawn
|
||||
}
|
||||
else
|
||||
{
|
||||
collectedGroundItems.put(tile.getWorldLocation(), item.getId(), groundItem);
|
||||
}
|
||||
|
||||
if (!config.onlyShowLoot())
|
||||
{
|
||||
notifyHighlightedItem(groundItem);
|
||||
}
|
||||
|
||||
handleLootbeam(tile.getWorldLocation());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -261,8 +274,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
TileItem item = itemDespawned.getItem();
|
||||
Tile tile = itemDespawned.getTile();
|
||||
|
||||
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
|
||||
GroundItem groundItem = collectedGroundItems.get(groundItemKey);
|
||||
GroundItem groundItem = collectedGroundItems.get(tile.getWorldLocation(), item.getId());
|
||||
if (groundItem == null)
|
||||
{
|
||||
return;
|
||||
@@ -270,7 +282,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
|
||||
if (groundItem.getQuantity() <= item.getQuantity())
|
||||
{
|
||||
collectedGroundItems.remove(groundItemKey);
|
||||
collectedGroundItems.remove(tile.getWorldLocation(), item.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -280,6 +292,8 @@ public class GroundItemsPlugin extends Plugin
|
||||
// time
|
||||
groundItem.setSpawnTime(null);
|
||||
}
|
||||
|
||||
handleLootbeam(tile.getWorldLocation());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -291,12 +305,13 @@ public class GroundItemsPlugin extends Plugin
|
||||
int newQuantity = itemQuantityChanged.getNewQuantity();
|
||||
|
||||
int diff = newQuantity - oldQuantity;
|
||||
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(item.getId(), tile.getWorldLocation());
|
||||
GroundItem groundItem = collectedGroundItems.get(groundItemKey);
|
||||
GroundItem groundItem = collectedGroundItems.get(tile.getWorldLocation(), item.getId());
|
||||
if (groundItem != null)
|
||||
{
|
||||
groundItem.setQuantity(groundItem.getQuantity() + diff);
|
||||
}
|
||||
|
||||
handleLootbeam(tile.getWorldLocation());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -366,8 +381,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
for (ItemStack itemStack : items)
|
||||
{
|
||||
WorldPoint location = WorldPoint.fromLocal(client, itemStack.getLocation());
|
||||
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(itemStack.getId(), location);
|
||||
GroundItem groundItem = collectedGroundItems.get(groundItemKey);
|
||||
GroundItem groundItem = collectedGroundItems.get(location, itemStack.getId());
|
||||
if (groundItem != null)
|
||||
{
|
||||
groundItem.setLootType(lootType);
|
||||
@@ -460,12 +474,14 @@ public class GroundItemsPlugin extends Plugin
|
||||
}
|
||||
|
||||
priceChecks = priceCheckBuilder.build();
|
||||
|
||||
clientThread.invokeLater(this::handleLootbeams);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (config.itemHighlightMode() != OVERLAY)
|
||||
if (config.itemHighlightMode() == ItemHighlightMode.MENU || config.itemHighlightMode() == ItemHighlightMode.BOTH)
|
||||
{
|
||||
final boolean telegrabEntry = event.getOption().equals("Cast") && event.getTarget().startsWith(TELEGRAB_TEXT) && event.getType() == CAST_ON_ITEM;
|
||||
if (!(event.getOption().equals("Take") && event.getType() == THIRD_OPTION) && !telegrabEntry)
|
||||
@@ -481,8 +497,7 @@ public class GroundItemsPlugin extends Plugin
|
||||
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
|
||||
|
||||
final WorldPoint worldPoint = WorldPoint.fromScene(client, sceneX, sceneY, client.getPlane());
|
||||
GroundItem.GroundItemKey groundItemKey = new GroundItem.GroundItemKey(itemId, worldPoint);
|
||||
GroundItem groundItem = collectedGroundItems.get(groundItemKey);
|
||||
GroundItem groundItem = collectedGroundItems.get(worldPoint, itemId);
|
||||
int quantity = groundItem.getQuantity();
|
||||
|
||||
final int gePrice = groundItem.getGePrice();
|
||||
@@ -705,4 +720,103 @@ public class GroundItemsPlugin extends Plugin
|
||||
lastUsedItem = clickedItem.getId();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLootbeam(WorldPoint worldPoint)
|
||||
{
|
||||
/*
|
||||
* Return and remove the lootbeam from this location if lootbeam are disabled
|
||||
* Lootbeam can be at this location if the config was just changed
|
||||
*/
|
||||
if (!(config.showLootbeamForHighlighted() || config.showLootbeamTier() != HighlightTier.OFF))
|
||||
{
|
||||
removeLootbeam(worldPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
int price = -1;
|
||||
Collection<GroundItem> groundItems = collectedGroundItems.row(worldPoint).values();
|
||||
for (GroundItem groundItem : groundItems)
|
||||
{
|
||||
if ((config.onlyShowLoot() && !groundItem.isMine()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* highlighted items have the highest priority so if an item is highlighted at this location
|
||||
* we can early return
|
||||
*/
|
||||
NamedQuantity item = new NamedQuantity(groundItem);
|
||||
if (config.showLootbeamForHighlighted()
|
||||
&& TRUE.equals(highlightedItems.getUnchecked(item)))
|
||||
{
|
||||
addLootbeam(worldPoint, config.highlightedColor());
|
||||
return;
|
||||
}
|
||||
|
||||
// Explicit hide takes priority over implicit highlight
|
||||
if (TRUE.equals(hiddenItems.getUnchecked(item)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int itemPrice = getValueByMode(groundItem.getGePrice(), groundItem.getHaPrice());
|
||||
price = Math.max(itemPrice, price);
|
||||
}
|
||||
|
||||
if (config.showLootbeamTier() != HighlightTier.OFF)
|
||||
{
|
||||
for (PriceHighlight highlight : priceChecks)
|
||||
{
|
||||
if (price > highlight.getPrice() && price > config.showLootbeamTier().getValueFromTier(config))
|
||||
{
|
||||
addLootbeam(worldPoint, highlight.color);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeLootbeam(worldPoint);
|
||||
}
|
||||
|
||||
private void handleLootbeams()
|
||||
{
|
||||
for (WorldPoint worldPoint : collectedGroundItems.rowKeySet())
|
||||
{
|
||||
handleLootbeam(worldPoint);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAllLootbeams()
|
||||
{
|
||||
for (Lootbeam lootbeam : lootbeams.values())
|
||||
{
|
||||
lootbeam.remove();
|
||||
}
|
||||
|
||||
lootbeams.clear();
|
||||
}
|
||||
|
||||
private void addLootbeam(WorldPoint worldPoint, Color color)
|
||||
{
|
||||
Lootbeam lootbeam = lootbeams.get(worldPoint);
|
||||
if (lootbeam == null)
|
||||
{
|
||||
lootbeam = new Lootbeam(client, worldPoint, color);
|
||||
lootbeams.put(worldPoint, lootbeam);
|
||||
}
|
||||
else
|
||||
{
|
||||
lootbeam.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeLootbeam(WorldPoint worldPoint)
|
||||
{
|
||||
Lootbeam lootbeam = lootbeams.remove(worldPoint);
|
||||
if (lootbeam != null)
|
||||
{
|
||||
lootbeam.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Trevor <https://github.com/Trevor159>
|
||||
* 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.grounditems;
|
||||
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.JagexColor;
|
||||
import net.runelite.api.RuneLiteObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import java.awt.Color;
|
||||
|
||||
class Lootbeam
|
||||
{
|
||||
private static final int RAID_LIGHT_MODEL = 5809;
|
||||
private static final short RAID_LIGHT_FIND_COLOR = 6371;
|
||||
|
||||
private final RuneLiteObject runeLiteObject;
|
||||
private final Client client;
|
||||
private Color color;
|
||||
|
||||
public Lootbeam(Client client, WorldPoint worldPoint, Color color)
|
||||
{
|
||||
this.client = client;
|
||||
runeLiteObject = client.createRuneLiteObject();
|
||||
|
||||
setColor(color);
|
||||
runeLiteObject.setAnimation(client.loadAnimation(AnimationID.RAID_LIGHT_ANIMATION));
|
||||
runeLiteObject.setShouldLoop(true);
|
||||
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, worldPoint);
|
||||
runeLiteObject.setLocation(lp, client.getPlane());
|
||||
|
||||
runeLiteObject.setActive(true);
|
||||
}
|
||||
|
||||
public void setColor(Color color)
|
||||
{
|
||||
if (this.color != null && this.color.equals(color))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.color = color;
|
||||
runeLiteObject.setModel(client.loadModel(
|
||||
RAID_LIGHT_MODEL,
|
||||
new short[]{RAID_LIGHT_FIND_COLOR},
|
||||
new short[]{JagexColor.rgbToHSL(color.getRGB(), 1.0d)}
|
||||
));
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
runeLiteObject.setActive(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import lombok.RequiredArgsConstructor;
|
||||
@RequiredArgsConstructor
|
||||
public enum ItemHighlightMode
|
||||
{
|
||||
NONE("None"),
|
||||
OVERLAY("Overlay"),
|
||||
MENU("Right-click menu"),
|
||||
BOTH("Both");
|
||||
|
||||
@@ -748,7 +748,7 @@ public class MusicPlugin extends Plugin
|
||||
s.update();
|
||||
s.getChannel().setWindowSlider(s);
|
||||
}
|
||||
|
||||
|
||||
if (ev.getScriptId() == ScriptID.TOPLEVEL_REDRAW && musicConfig.granularSliders())
|
||||
{
|
||||
// we have to set the var to our value so toplevel_redraw doesn't try to set
|
||||
@@ -857,11 +857,12 @@ public class MusicPlugin extends Plugin
|
||||
windowSlider.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateVar()
|
||||
{
|
||||
int val = getValue();
|
||||
client.getVarps()[this.var.getId()] = val * 100 / this.max;
|
||||
int varVal = Math.round((float) val / (max / 100.f));
|
||||
client.getVarps()[this.var.getId()] = varVal;
|
||||
}
|
||||
|
||||
public void shutDown()
|
||||
|
||||
@@ -27,11 +27,14 @@ package net.runelite.client.plugins.statusbars;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Units;
|
||||
import net.runelite.client.plugins.statusbars.config.BarMode;
|
||||
|
||||
@ConfigGroup("statusbars")
|
||||
@ConfigGroup(StatusBarsConfig.GROUP)
|
||||
public interface StatusBarsConfig extends Config
|
||||
{
|
||||
String GROUP = "statusbars";
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "enableCounter",
|
||||
name = "Show counters",
|
||||
@@ -81,4 +84,15 @@ public interface StatusBarsConfig extends Config
|
||||
{
|
||||
return BarMode.PRAYER;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideAfterCombatDelay",
|
||||
name = "Hide after combat delay",
|
||||
description = "Amount of ticks before hiding status bars after no longer in combat. 0 = always show status bars."
|
||||
)
|
||||
@Units(Units.TICKS)
|
||||
default int hideAfterCombatDelay()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ class StatusBarsOverlay extends Overlay
|
||||
private static final int MAX_RUN_ENERGY_VALUE = 100;
|
||||
|
||||
private final Client client;
|
||||
private final StatusBarsPlugin plugin;
|
||||
private final StatusBarsConfig config;
|
||||
private final ItemStatChangesService itemStatService;
|
||||
private final SpriteManager spriteManager;
|
||||
@@ -94,11 +95,12 @@ class StatusBarsOverlay extends Overlay
|
||||
private final Map<BarMode, BarRenderer> barRenderers = new EnumMap<>(BarMode.class);
|
||||
|
||||
@Inject
|
||||
private StatusBarsOverlay(Client client, StatusBarsConfig config, SkillIconManager skillIconManager, ItemStatChangesService itemstatservice, SpriteManager spriteManager)
|
||||
private StatusBarsOverlay(Client client, StatusBarsPlugin plugin, StatusBarsConfig config, SkillIconManager skillIconManager, ItemStatChangesService itemstatservice, SpriteManager spriteManager)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.itemStatService = itemstatservice;
|
||||
this.spriteManager = spriteManager;
|
||||
@@ -216,6 +218,11 @@ class StatusBarsOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
if (!plugin.isBarsDisplayed())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Viewport curViewport = null;
|
||||
Widget curWidget = null;
|
||||
|
||||
|
||||
@@ -26,12 +26,24 @@ package net.runelite.client.plugins.statusbars;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDependency;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.itemstats.ItemStatPlugin;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Status Bars",
|
||||
@@ -47,9 +59,24 @@ public class StatusBarsPlugin extends Plugin
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private StatusBarsConfig config;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean barsDisplayed;
|
||||
|
||||
private int lastCombatActionTickCount;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
clientThread.invokeLater(this::checkStatusBars);
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@@ -57,6 +84,7 @@ public class StatusBarsPlugin extends Plugin
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
barsDisplayed = false;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -64,4 +92,45 @@ public class StatusBarsPlugin extends Plugin
|
||||
{
|
||||
return configManager.getConfig(StatusBarsConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick gameTick)
|
||||
{
|
||||
checkStatusBars();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (StatusBarsConfig.GROUP.equals(event.getGroup()) && event.getKey().equals("hideAfterCombatDelay"))
|
||||
{
|
||||
clientThread.invokeLater(this::checkStatusBars);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStatusBars()
|
||||
{
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
if (localPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Actor interacting = localPlayer.getInteracting();
|
||||
|
||||
if (config.hideAfterCombatDelay() == 0)
|
||||
{
|
||||
barsDisplayed = true;
|
||||
}
|
||||
else if ((interacting instanceof NPC && ArrayUtils.contains(((NPC) interacting).getComposition().getActions(), "Attack"))
|
||||
|| (interacting instanceof Player && client.getVar(Varbits.PVP_SPEC_ORB) == 1))
|
||||
{
|
||||
lastCombatActionTickCount = client.getTickCount();
|
||||
barsDisplayed = true;
|
||||
}
|
||||
else if (client.getTickCount() - lastCombatActionTickCount >= config.hideAfterCombatDelay())
|
||||
{
|
||||
barsDisplayed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.clocks.ClockManager;
|
||||
import net.runelite.client.plugins.timetracking.farming.CropState;
|
||||
import net.runelite.client.plugins.timetracking.farming.FarmingContractManager;
|
||||
import net.runelite.client.plugins.timetracking.farming.FarmingTracker;
|
||||
import net.runelite.client.plugins.timetracking.hunter.BirdHouseTracker;
|
||||
@@ -124,14 +124,13 @@ class OverviewTabPanel extends TabContentPanel
|
||||
}
|
||||
|
||||
farmingOverviews.forEach((patchType, panel) ->
|
||||
updateItemPanel(panel, farmingTracker.getSummary(patchType), farmingTracker.getCompletionTime(patchType), null));
|
||||
updateItemPanel(panel, farmingTracker.getSummary(patchType), farmingTracker.getCompletionTime(patchType)));
|
||||
|
||||
updateItemPanel(birdHouseOverview, birdHouseTracker.getSummary(), birdHouseTracker.getCompletionTime(), null);
|
||||
updateItemPanel(farmingContractOverview, farmingContractManager.getSummary(), farmingContractManager.getCompletionTime(),
|
||||
farmingContractManager.getContractName());
|
||||
updateItemPanel(birdHouseOverview, birdHouseTracker.getSummary(), birdHouseTracker.getCompletionTime());
|
||||
updateContractPanel();
|
||||
}
|
||||
|
||||
private void updateItemPanel(OverviewItemPanel panel, SummaryState summary, long completionTime, @Nullable String farmingContract)
|
||||
private void updateItemPanel(OverviewItemPanel panel, SummaryState summary, long completionTime)
|
||||
{
|
||||
switch (summary)
|
||||
{
|
||||
@@ -151,10 +150,7 @@ class OverviewTabPanel extends TabContentPanel
|
||||
break;
|
||||
}
|
||||
case EMPTY:
|
||||
panel.updateStatus(farmingContract == null ? "Empty" : farmingContract, Color.GRAY);
|
||||
break;
|
||||
case OCCUPIED:
|
||||
panel.updateStatus(farmingContract == null ? "" : farmingContract, Color.RED);
|
||||
panel.updateStatus("Empty", Color.GRAY);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
@@ -162,4 +158,45 @@ class OverviewTabPanel extends TabContentPanel
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContractPanel()
|
||||
{
|
||||
switch (farmingContractManager.getSummary())
|
||||
{
|
||||
case COMPLETED:
|
||||
case IN_PROGRESS:
|
||||
switch (farmingContractManager.getContractCropState())
|
||||
{
|
||||
case HARVESTABLE:
|
||||
case GROWING:
|
||||
long duration = farmingContractManager.getCompletionTime() - Instant.now().getEpochSecond();
|
||||
|
||||
if (duration <= 0)
|
||||
{
|
||||
farmingContractOverview.updateStatus("Ready", ColorScheme.PROGRESS_COMPLETE_COLOR);
|
||||
return;
|
||||
}
|
||||
|
||||
farmingContractOverview.updateStatus("Ready " + getFormattedEstimate(duration, config.timeFormatMode()), Color.GRAY);
|
||||
return;
|
||||
case DISEASED:
|
||||
farmingContractOverview.updateStatus("Diseased", CropState.DISEASED.getColor());
|
||||
return;
|
||||
case DEAD:
|
||||
farmingContractOverview.updateStatus("Dead", CropState.DEAD.getColor());
|
||||
return;
|
||||
}
|
||||
// fallthrough
|
||||
case UNKNOWN:
|
||||
default:
|
||||
farmingContractOverview.updateStatus("Unknown", Color.GRAY);
|
||||
return;
|
||||
case EMPTY:
|
||||
farmingContractOverview.updateStatus(farmingContractManager.getContractName(), Color.GRAY);
|
||||
return;
|
||||
case OCCUPIED:
|
||||
farmingContractOverview.updateStatus(farmingContractManager.getContractName(), Color.RED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,16 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.timetracking;
|
||||
|
||||
import java.time.DateTimeException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.TextStyle;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Locale;
|
||||
import javax.swing.JPanel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public abstract class TabContentPanel extends JPanel
|
||||
{
|
||||
private static final DateTimeFormatter DATETIME_FORMATTER_24H = DateTimeFormatter.ofPattern("HH:mm");
|
||||
@@ -72,17 +75,25 @@ public abstract class TabContentPanel extends JPanel
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
LocalDateTime endTime = LocalDateTime.now().plus(remainingSeconds, ChronoUnit.SECONDS);
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
if (endTime.getDayOfWeek() != currentTime.getDayOfWeek())
|
||||
try
|
||||
{
|
||||
sb.append(endTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.getDefault())).append(" ");
|
||||
}
|
||||
sb.append("at ");
|
||||
sb.append(formatter.format(endTime));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
LocalDateTime endTime = LocalDateTime.now().plus(remainingSeconds, ChronoUnit.SECONDS);
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
if (endTime.getDayOfWeek() != currentTime.getDayOfWeek())
|
||||
{
|
||||
sb.append(endTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.getDefault())).append(" ");
|
||||
}
|
||||
sb.append("at ");
|
||||
sb.append(formatter.format(endTime));
|
||||
|
||||
return sb.toString();
|
||||
return sb.toString();
|
||||
}
|
||||
catch (DateTimeException e)
|
||||
{
|
||||
log.warn("error formatting absolute time: now + {}", remainingSeconds, e);
|
||||
return "Invalid";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public class CustomScrollBarUI extends BasicScrollBarUI
|
||||
{
|
||||
JScrollBar bar = (JScrollBar) c;
|
||||
bar.setUnitIncrement(16);
|
||||
bar.setPreferredSize(new Dimension(7, 0));
|
||||
bar.setPreferredSize(new Dimension(7, 7));
|
||||
return new CustomScrollBarUI();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ public class WorldMapOverlay extends Overlay
|
||||
Area currentClip = null;
|
||||
|
||||
Point mousePos = client.getMouseCanvasPosition();
|
||||
if (!canvasViewArea.contains(mousePos.getX(), mousePos.getY()))
|
||||
if (!mapViewArea.contains(mousePos.getX(), mousePos.getY()))
|
||||
{
|
||||
mousePos = null;
|
||||
}
|
||||
|
||||
@@ -3765,7 +3765,13 @@
|
||||
23072,
|
||||
23082,
|
||||
25753,
|
||||
25820
|
||||
25820,
|
||||
25920,
|
||||
25921,
|
||||
25922,
|
||||
25923,
|
||||
25924,
|
||||
25925
|
||||
],
|
||||
"herb tea mix": [
|
||||
4464,
|
||||
@@ -7528,7 +7534,16 @@
|
||||
25185,
|
||||
25187,
|
||||
25189,
|
||||
25191
|
||||
25191,
|
||||
25898,
|
||||
25900,
|
||||
25902,
|
||||
25904,
|
||||
25906,
|
||||
25908,
|
||||
25910,
|
||||
25912,
|
||||
25914
|
||||
],
|
||||
"slayer ring": [
|
||||
11866,
|
||||
@@ -8641,6 +8656,11 @@
|
||||
21009,
|
||||
21206
|
||||
],
|
||||
"dragon hunter crossbow": [
|
||||
21012,
|
||||
25916,
|
||||
25918
|
||||
],
|
||||
"ancestral hat": [
|
||||
21018,
|
||||
25518
|
||||
@@ -9884,5 +9904,21 @@
|
||||
25892,
|
||||
25894,
|
||||
25896
|
||||
],
|
||||
"ghommals hilt": [
|
||||
25926,
|
||||
25928,
|
||||
25930,
|
||||
25932,
|
||||
25934,
|
||||
25936
|
||||
],
|
||||
"anim offhand": [
|
||||
25938,
|
||||
25941,
|
||||
25944,
|
||||
25947,
|
||||
25950,
|
||||
25953
|
||||
]
|
||||
}
|
||||
@@ -552,7 +552,7 @@
|
||||
"rx2": 50,
|
||||
"ry2": 29,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
"z2": 2
|
||||
},
|
||||
{
|
||||
"rx1": 13,
|
||||
@@ -724,6 +724,14 @@
|
||||
}
|
||||
],
|
||||
"10288": [ // Yanille East
|
||||
{
|
||||
"rx1": 27,
|
||||
"ry1": 12,
|
||||
"rx2": 33,
|
||||
"ry2": 19,
|
||||
"z1": 1,
|
||||
"z2": 1
|
||||
},
|
||||
{
|
||||
"rx1": 47,
|
||||
"ry1": 19,
|
||||
@@ -2167,5 +2175,243 @@
|
||||
"z1": 0,
|
||||
"z2": 2
|
||||
}
|
||||
],
|
||||
"11310": [ // Shilo Village
|
||||
{
|
||||
"rx1": 26,
|
||||
"ry1": 52,
|
||||
"rx2": 28,
|
||||
"ry2": 54,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 26,
|
||||
"ry1": 58,
|
||||
"rx2": 28,
|
||||
"ry2": 60,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 27,
|
||||
"ry1": 55,
|
||||
"rx2": 27,
|
||||
"ry2": 57,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 33,
|
||||
"ry1": 52,
|
||||
"rx2": 35,
|
||||
"ry2": 54,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 29,
|
||||
"ry1": 53,
|
||||
"rx2": 32,
|
||||
"ry2": 53,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 44,
|
||||
"ry1": 49,
|
||||
"rx2": 46,
|
||||
"ry2": 57,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 43,
|
||||
"ry1": 50,
|
||||
"rx2": 47,
|
||||
"ry2": 56,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 42,
|
||||
"ry1": 51,
|
||||
"rx2": 48,
|
||||
"ry2": 55,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 41,
|
||||
"ry1": 52,
|
||||
"rx2": 49,
|
||||
"ry2": 54,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 36,
|
||||
"ry1": 53,
|
||||
"rx2": 40,
|
||||
"ry2": 53,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 43,
|
||||
"ry1": 44,
|
||||
"rx2": 47,
|
||||
"ry2": 46,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 45,
|
||||
"ry1": 43,
|
||||
"rx2": 45,
|
||||
"ry2": 48,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 53,
|
||||
"ry1": 51,
|
||||
"rx2": 55,
|
||||
"ry2": 55,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 50,
|
||||
"ry1": 53,
|
||||
"rx2": 56,
|
||||
"ry2": 53,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 52,
|
||||
"ry1": 37,
|
||||
"rx2": 54,
|
||||
"ry2": 39,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 8,
|
||||
"ry1": 18,
|
||||
"rx2": 9,
|
||||
"ry2": 19,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 53,
|
||||
"ry1": 29,
|
||||
"rx2": 53,
|
||||
"ry2": 36,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
}
|
||||
],
|
||||
"12340": [ // Draynor Manor
|
||||
{
|
||||
"rx1": 30,
|
||||
"ry1": 24,
|
||||
"rx2": 43,
|
||||
"ry2": 24,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
}
|
||||
],
|
||||
"9265": [ // Lletya
|
||||
{
|
||||
"rx1": 23,
|
||||
"ry1": 34,
|
||||
"rx2": 23,
|
||||
"ry2": 37,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
}
|
||||
],
|
||||
"15148": [ // Harmony Island
|
||||
{
|
||||
"rx1": 30,
|
||||
"ry1": 24,
|
||||
"rx2": 40,
|
||||
"ry2": 32,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 41,
|
||||
"ry1": 18,
|
||||
"rx2": 48,
|
||||
"ry2": 36,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 41,
|
||||
"ry1": 37,
|
||||
"rx2": 45,
|
||||
"ry2": 38,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 34,
|
||||
"ry1": 57,
|
||||
"rx2": 38,
|
||||
"ry2": 57,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
}
|
||||
],
|
||||
"11423": [ // NW Keldagrim
|
||||
{
|
||||
"rx1": 60,
|
||||
"ry1": 11,
|
||||
"rx2": 63,
|
||||
"ry2": 36,
|
||||
"z1": 0,
|
||||
"z2": 1
|
||||
}
|
||||
],
|
||||
"11678": [ // SE Keldagrim
|
||||
{
|
||||
"rx1": 49,
|
||||
"ry1": 46,
|
||||
"rx2": 49,
|
||||
"ry2": 51,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 50,
|
||||
"ry1": 56,
|
||||
"rx2": 51,
|
||||
"ry2": 63,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
}
|
||||
],
|
||||
"11679": [ // NE Keldagrim
|
||||
{
|
||||
"rx1": 50,
|
||||
"ry1": 0,
|
||||
"rx2": 51,
|
||||
"ry2": 1,
|
||||
"z1": 0,
|
||||
"z2": 0
|
||||
},
|
||||
{
|
||||
"rx1": 0,
|
||||
"ry1": 11,
|
||||
"rx2": 3,
|
||||
"ry2": 36,
|
||||
"z1": 0,
|
||||
"z2": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2FE66C1A3B63EEF10142A955C927054613F59A34C4A929C8AC79DBE0F1B06C30
|
||||
9D5F23C8B25B79FF2B23F6AE449EDF74645E808B67ECF0E389B626966E86B1BD
|
||||
@@ -273,7 +273,7 @@ LABEL226:
|
||||
iload 6 ; prefix length
|
||||
iload 5 ; chat type
|
||||
sconst "preChatSendpublic"
|
||||
runelite_callback
|
||||
runelite_callback
|
||||
istore 5 ; chat type
|
||||
istore 6 ; prefix length
|
||||
get_varc_string 335 ; load input string
|
||||
@@ -565,7 +565,7 @@ LABEL441:
|
||||
if_icmpeq LABEL445
|
||||
jump LABEL490
|
||||
LABEL445:
|
||||
iconst 40697935
|
||||
iconst 40697936
|
||||
iconst 1
|
||||
cc_find
|
||||
iconst 1
|
||||
|
||||
@@ -111,6 +111,8 @@ public class GroundItemsPluginTest
|
||||
|
||||
when(client.getLocalPlayer()).thenReturn(mock(Player.class));
|
||||
when(config.getHiddenItems()).thenReturn("");
|
||||
when(config.showLootbeamForHighlighted()).thenReturn(false);
|
||||
when(config.showLootbeamTier()).thenReturn(HighlightTier.OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user