Merge remote-tracking branch 'Upstream/master' into runelite-master

Still needs mixins fixed. so do not merge yet.

# Conflicts:
#	runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/FixedPriceItem.java
#	runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java
This commit is contained in:
Zeruth
2019-07-10 20:06:09 -04:00
18 changed files with 1436 additions and 169 deletions

View File

@@ -385,6 +385,18 @@ public class ItemManager
* @return item price
*/
public int getItemPrice(int itemID)
{
return getItemPrice(itemID, false);
}
/**
* Look up an item's price
*
* @param itemID item id
* @param ignoreUntradeableMap should the price returned ignore the {@link UntradeableItemMapping}
* @return item price
*/
public int getItemPrice(int itemID, boolean ignoreUntradeableMap)
{
if (itemID == ItemID.COINS_995)
{
@@ -395,10 +407,13 @@ public class ItemManager
return 1000;
}
UntradeableItemMapping p = UntradeableItemMapping.map(ItemVariationMapping.map(itemID));
if (p != null)
if (!ignoreUntradeableMap)
{
return getItemPrice(p.getPriceID()) * p.getQuantity();
UntradeableItemMapping p = UntradeableItemMapping.map(ItemVariationMapping.map(itemID));
if (p != null)
{
return getItemPrice(p.getPriceID()) * p.getQuantity();
}
}
int price = 0;

View File

@@ -57,7 +57,8 @@ enum Boss
KRAKEN(NpcID.KRAKEN, 8400, ChronoUnit.MILLIS, ItemID.PET_KRAKEN),
KALPHITE_QUEEN(NpcID.KALPHITE_QUEEN_965, 30, ChronoUnit.SECONDS, ItemID.KALPHITE_PRINCESS),
DUSK(NpcID.DUSK_7889, 2, ChronoUnit.MINUTES, ItemID.NOON),
ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA);
ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA),
SARACHNIS(NpcID.SARACHNIS, 30, ChronoUnit.SECONDS, ItemID.SRARACHA);
private static final Map<Integer, Boss> bosses;

View File

@@ -86,4 +86,15 @@ public interface ChatFilterConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "filterLogin",
name = "Filter Logged In/Out Messages",
description = "Filter your private chat to remove logged in/out messages",
position = 6
)
default boolean filterLogin()
{
return false;
}
}

View File

@@ -133,6 +133,13 @@ public class ChatFilterPlugin extends Plugin
case FRIENDSCHAT:
case GAMEMESSAGE:
break;
case LOGINLOGOUTNOTIFICATION:
if (config.filterLogin())
{
// Block the message
intStack[intStackSize - 3] = 0;
}
return;
default:
return;
}

View File

@@ -253,7 +253,12 @@ public class IdleNotifierPlugin extends Plugin
case USING_GILDED_ALTAR:
/* Farming */
case FARMING_MIX_ULTRACOMPOST:
/* Misc */
case FARMING_HARVEST_BUSH:
case FARMING_HARVEST_HERB:
case FARMING_HARVEST_FRUIT_TREE:
case FARMING_HARVEST_FLOWER:
case FARMING_HARVEST_ALLOTMENT:
/* Misc */
case PISCARILIUS_CRANE_REPAIR:
case HOME_MAKE_TABLET:
case SAND_COLLECTION:

View File

@@ -42,7 +42,9 @@ enum AlwaysLostItem
{
RUNE_POUCH(ItemID.RUNE_POUCH, true),
LOOTING_BAG(ItemID.LOOTING_BAG, false),
CLUE_BOX(ItemID.CLUE_BOX, false);
CLUE_BOX(ItemID.CLUE_BOX, false),
BRACELET_OF_ETHEREUM(ItemID.BRACELET_OF_ETHEREUM, false),
BRACELET_OF_ETHEREUM_UNCHARGED(ItemID.BRACELET_OF_ETHEREUM_UNCHARGED, false);
private final int itemID;
private final boolean keptOutsideOfWilderness;

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.annotation.Nullable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.ItemID;
/**
* Degradable/Non-rechargeable Jewelry death prices are usually determined by the amount of charges the item has left.
* The price of each charge is based on the GE price of the fully charged item divided by the maximum item charges
* Charge price = GE Price / Max Charges
* Death Price = Charge price * Current Charges
*/
@AllArgsConstructor
@Getter
enum DynamicPriceItem
{
GAMES_NECKLACE1(ItemID.GAMES_NECKLACE1, 1, 8, ItemID.GAMES_NECKLACE8),
GAMES_NECKLACE2(ItemID.GAMES_NECKLACE2, 2, 8, ItemID.GAMES_NECKLACE8),
GAMES_NECKLACE3(ItemID.GAMES_NECKLACE3, 3, 8, ItemID.GAMES_NECKLACE8),
GAMES_NECKLACE4(ItemID.GAMES_NECKLACE4, 4, 8, ItemID.GAMES_NECKLACE8),
GAMES_NECKLACE5(ItemID.GAMES_NECKLACE5, 5, 8, ItemID.GAMES_NECKLACE8),
GAMES_NECKLACE6(ItemID.GAMES_NECKLACE6, 6, 8, ItemID.GAMES_NECKLACE8),
GAMES_NECKLACE7(ItemID.GAMES_NECKLACE7, 7, 8, ItemID.GAMES_NECKLACE8),
RING_OF_DUELING1(ItemID.RING_OF_DUELING1, 1, 8, ItemID.RING_OF_DUELING8),
RING_OF_DUELING2(ItemID.RING_OF_DUELING2, 2, 8, ItemID.RING_OF_DUELING8),
RING_OF_DUELING3(ItemID.RING_OF_DUELING3, 3, 8, ItemID.RING_OF_DUELING8),
RING_OF_DUELING4(ItemID.RING_OF_DUELING4, 4, 8, ItemID.RING_OF_DUELING8),
RING_OF_DUELING5(ItemID.RING_OF_DUELING5, 5, 8, ItemID.RING_OF_DUELING8),
RING_OF_DUELING6(ItemID.RING_OF_DUELING6, 6, 8, ItemID.RING_OF_DUELING8),
RING_OF_DUELING7(ItemID.RING_OF_DUELING7, 7, 8, ItemID.RING_OF_DUELING8),
RING_OF_RETURNING1(ItemID.RING_OF_RETURNING1, 1, 5, ItemID.RING_OF_RETURNING5),
RING_OF_RETURNING2(ItemID.RING_OF_RETURNING2, 2, 5, ItemID.RING_OF_RETURNING5),
RING_OF_RETURNING3(ItemID.RING_OF_RETURNING3, 3, 5, ItemID.RING_OF_RETURNING5),
RING_OF_RETURNING4(ItemID.RING_OF_RETURNING4, 4, 5, ItemID.RING_OF_RETURNING5),
NECKLACE_OF_PASSAGE1(ItemID.NECKLACE_OF_PASSAGE1, 1, 5, ItemID.NECKLACE_OF_PASSAGE5),
NECKLACE_OF_PASSAGE2(ItemID.NECKLACE_OF_PASSAGE2, 2, 5, ItemID.NECKLACE_OF_PASSAGE5),
NECKLACE_OF_PASSAGE3(ItemID.NECKLACE_OF_PASSAGE3, 3, 5, ItemID.NECKLACE_OF_PASSAGE5),
NECKLACE_OF_PASSAGE4(ItemID.NECKLACE_OF_PASSAGE4, 4, 5, ItemID.NECKLACE_OF_PASSAGE5),
BURNING_AMULET1(ItemID.BURNING_AMULET1, 1, 5, ItemID.BURNING_AMULET5),
BURNING_AMULET2(ItemID.BURNING_AMULET2, 2, 5, ItemID.BURNING_AMULET5),
BURNING_AMULET3(ItemID.BURNING_AMULET3, 3, 5, ItemID.BURNING_AMULET5),
BURNING_AMULET4(ItemID.BURNING_AMULET4, 4, 5, ItemID.BURNING_AMULET5);
private final int itemId;
private final int currentCharges;
private final int maxCharges;
private final int chargedId;
private static final Map<Integer, DynamicPriceItem> DYNAMIC_ITEMS;
static
{
final ImmutableMap.Builder<Integer, DynamicPriceItem> map = ImmutableMap.builder();
for (final DynamicPriceItem p : values())
{
map.put(p.itemId, p);
}
DYNAMIC_ITEMS = map.build();
}
/**
* Calculates the price off the partially charged jewelry based on the base items price
* @param basePrice price of the base item, usually the trade-able variant
* @return death price of the current DynamicPriceItem
*/
int calculateDeathPrice(final int basePrice)
{
return (basePrice / maxCharges) * currentCharges;
}
@Nullable
static DynamicPriceItem find(int itemId)
{
return DYNAMIC_ITEMS.get(itemId);
}
}

View File

@@ -28,8 +28,6 @@ package net.runelite.client.plugins.itemskeptondeath;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.annotation.Nullable;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.ItemID;
@@ -37,8 +35,7 @@ import net.runelite.api.ItemID;
* Some items have a fixed price that is added to its default value when calculating death prices.
* These are typically imbued items, such as Berserker ring (i), to help it protect over the non-imbued variants.
*/
@AllArgsConstructor
@Getter(AccessLevel.PACKAGE)
@Getter
enum FixedPriceItem
{
IMBUED_BLACK_MASK_I(ItemID.BLACK_MASK_I, 5000),
@@ -67,10 +64,161 @@ enum FixedPriceItem
IMBUED_RING_OF_THE_GODS_I(ItemID.RING_OF_THE_GODS_I, 2000),
IMBUED_TREASONOUS_RING_I(ItemID.TREASONOUS_RING_I, 2000),
IMBUED_TYRANNICAL_RING_I(ItemID.TYRANNICAL_RING_I, 2000);
IMBUED_TYRANNICAL_RING_I(ItemID.TYRANNICAL_RING_I, 2000),
GRACEFUL_HOOD(ItemID.GRACEFUL_HOOD, 1965),
GRACEFUL_CAPE(ItemID.GRACEFUL_CAPE, 2460),
GRACEFUL_TOP(ItemID.GRACEFUL_TOP, 2345),
GRACEFUL_LEGS(ItemID.GRACEFUL_LEGS, 2290),
GRACEFUL_GLOVES(ItemID.GRACEFUL_GLOVES, 1970),
GRACEFUL_BOOTS(ItemID.GRACEFUL_BOOTS, 2060),
ANGLER_HAT(ItemID.ANGLER_HAT, 2600),
ANGLER_TOP(ItemID.ANGLER_TOP, 3550),
ANGLER_WADERS(ItemID.ANGLER_WADERS, 4400),
ANGLER_BOOTS(ItemID.ANGLER_BOOTS, 5300),
PROSPECTOR_HELMET(ItemID.PROSPECTOR_HELMET, 2640),
PROSPECTOR_JACKET(ItemID.PROSPECTOR_JACKET, 3550),
PROSPECTOR_LEGS(ItemID.PROSPECTOR_LEGS, 4460),
PROSPECTOR_BOOTS(ItemID.PROSPECTOR_BOOTS, 5370),
LUMBERJACK_HAT(ItemID.LUMBERJACK_HAT, 19950),
LUMBERJACK_TOP(ItemID.LUMBERJACK_TOP, 19950),
LUMBERJACK_LEGS(ItemID.LUMBERJACK_LEGS, 19950),
LUMBERJACK_BOOTS(ItemID.LUMBERJACK_BOOTS, 19950),
ROGUE_MASK(ItemID.ROGUE_MASK, 725),
ROGUE_TOP(ItemID.ROGUE_TOP, 575),
ROGUE_TROUSERS(ItemID.ROGUE_TROUSERS, 500),
ROGUE_GLOVES(ItemID.ROGUE_GLOVES, 650),
ROGUE_BOOTS(ItemID.ROGUE_BOOTS, 650),
RING_OF_WEALTH_1(ItemID.RING_OF_WEALTH_1, 500, ItemID.RING_OF_WEALTH),
RING_OF_WEALTH_2(ItemID.RING_OF_WEALTH_2, 1000, ItemID.RING_OF_WEALTH),
RING_OF_WEALTH_3(ItemID.RING_OF_WEALTH_3, 1500, ItemID.RING_OF_WEALTH),
RING_OF_WEALTH_4(ItemID.RING_OF_WEALTH_4, 2000, ItemID.RING_OF_WEALTH),
AMULET_OF_GLORY1(ItemID.AMULET_OF_GLORY1, 500, ItemID.AMULET_OF_GLORY),
AMULET_OF_GLORY2(ItemID.AMULET_OF_GLORY2, 1000, ItemID.AMULET_OF_GLORY),
AMULET_OF_GLORY3(ItemID.AMULET_OF_GLORY3, 1500, ItemID.AMULET_OF_GLORY),
AMULET_OF_GLORY5(ItemID.AMULET_OF_GLORY5, 2500, ItemID.AMULET_OF_GLORY),
COMBAT_BRACELET1(ItemID.COMBAT_BRACELET1, 500, ItemID.COMBAT_BRACELET),
COMBAT_BRACELET2(ItemID.COMBAT_BRACELET2, 1000, ItemID.COMBAT_BRACELET),
COMBAT_BRACELET3(ItemID.COMBAT_BRACELET3, 1500, ItemID.COMBAT_BRACELET),
COMBAT_BRACELET5(ItemID.COMBAT_BRACELET5, 2500, ItemID.COMBAT_BRACELET),
SKILLS_NECKLACE1(ItemID.SKILLS_NECKLACE1, 500, ItemID.SKILLS_NECKLACE),
SKILLS_NECKLACE2(ItemID.SKILLS_NECKLACE2, 1000, ItemID.SKILLS_NECKLACE),
SKILLS_NECKLACE3(ItemID.SKILLS_NECKLACE3, 1500, ItemID.SKILLS_NECKLACE),
SKILLS_NECKLACE4(ItemID.SKILLS_NECKLACE5, 2500, ItemID.SKILLS_NECKLACE),
AHRIMS_HOOD_25(ItemID.AHRIMS_HOOD_25, 2500, ItemID.AHRIMS_HOOD_0),
AHRIMS_HOOD_50(ItemID.AHRIMS_HOOD_50, 5000, ItemID.AHRIMS_HOOD_0),
AHRIMS_HOOD_75(ItemID.AHRIMS_HOOD_75, 7500, ItemID.AHRIMS_HOOD_0),
AHRIMS_HOOD_100(ItemID.AHRIMS_HOOD_100, 10000, ItemID.AHRIMS_HOOD_0),
AHRIMS_ROBETOP_25(ItemID.AHRIMS_ROBETOP_25, 2500, ItemID.AHRIMS_ROBETOP_0),
AHRIMS_ROBETOP_50(ItemID.AHRIMS_ROBETOP_50, 5000, ItemID.AHRIMS_ROBETOP_0),
AHRIMS_ROBETOP_75(ItemID.AHRIMS_ROBETOP_75, 7500, ItemID.AHRIMS_ROBETOP_0),
AHRIMS_ROBETOP_100(ItemID.AHRIMS_ROBETOP_100, 10000, ItemID.AHRIMS_ROBETOP_0),
AHRIMS_ROBESKIRT_25(ItemID.AHRIMS_ROBESKIRT_25, 2500, ItemID.AHRIMS_ROBESKIRT_0),
AHRIMS_ROBESKIRT_50(ItemID.AHRIMS_ROBESKIRT_50, 5000, ItemID.AHRIMS_ROBESKIRT_0),
AHRIMS_ROBESKIRT_75(ItemID.AHRIMS_ROBESKIRT_75, 7500, ItemID.AHRIMS_ROBESKIRT_0),
AHRIMS_ROBESKIRT_100(ItemID.AHRIMS_ROBESKIRT_100, 10000, ItemID.AHRIMS_ROBESKIRT_0),
AHRIMS_STAFF_25(ItemID.AHRIMS_STAFF_25, 2500, ItemID.AHRIMS_STAFF_0),
AHRIMS_STAFF_50(ItemID.AHRIMS_STAFF_50, 5000, ItemID.AHRIMS_STAFF_0),
AHRIMS_STAFF_75(ItemID.AHRIMS_STAFF_75, 7500, ItemID.AHRIMS_STAFF_0),
AHRIMS_STAFF_100(ItemID.AHRIMS_STAFF_100, 10000, ItemID.AHRIMS_STAFF_0),
KARILS_COIF_25(ItemID.KARILS_COIF_25, 2500, ItemID.KARILS_COIF_0),
KARILS_COIF_50(ItemID.KARILS_COIF_50, 5000, ItemID.KARILS_COIF_0),
KARILS_COIF_75(ItemID.KARILS_COIF_75, 7500, ItemID.KARILS_COIF_0),
KARILS_COIF_100(ItemID.KARILS_COIF_100, 10000, ItemID.KARILS_COIF_0),
KARILS_LEATHERTOP_25(ItemID.KARILS_LEATHERTOP_25, 2500, ItemID.KARILS_LEATHERTOP_0),
KARILS_LEATHERTOP_50(ItemID.KARILS_LEATHERTOP_50, 5000, ItemID.KARILS_LEATHERTOP_0),
KARILS_LEATHERTOP_75(ItemID.KARILS_LEATHERTOP_75, 7500, ItemID.KARILS_LEATHERTOP_0),
KARILS_LEATHERTOP_100(ItemID.KARILS_LEATHERTOP_100, 10000, ItemID.KARILS_LEATHERTOP_0),
KARILS_LEATHERSKIRT_25(ItemID.KARILS_LEATHERSKIRT_25, 2500, ItemID.KARILS_LEATHERSKIRT_0),
KARILS_LEATHERSKIRT_50(ItemID.KARILS_LEATHERSKIRT_50, 5000, ItemID.KARILS_LEATHERSKIRT_0),
KARILS_LEATHERSKIRT_75(ItemID.KARILS_LEATHERSKIRT_75, 7500, ItemID.KARILS_LEATHERSKIRT_0),
KARILS_LEATHERSKIRT_100(ItemID.KARILS_LEATHERSKIRT_100, 10000, ItemID.KARILS_LEATHERSKIRT_0),
KARILS_CROSSBOW_25(ItemID.KARILS_CROSSBOW_25, 2500, ItemID.KARILS_CROSSBOW_0),
KARILS_CROSSBOW_50(ItemID.KARILS_CROSSBOW_50, 5000, ItemID.KARILS_CROSSBOW_0),
KARILS_CROSSBOW_75(ItemID.KARILS_CROSSBOW_75, 7500, ItemID.KARILS_CROSSBOW_0),
KARILS_CROSSBOW_100(ItemID.KARILS_CROSSBOW_100, 10000, ItemID.KARILS_CROSSBOW_0),
DHAROKS_HELM_25(ItemID.DHAROKS_HELM_25, 2500, ItemID.DHAROKS_HELM_0),
DHAROKS_HELM_50(ItemID.DHAROKS_HELM_50, 5000, ItemID.DHAROKS_HELM_0),
DHAROKS_HELM_75(ItemID.DHAROKS_HELM_75, 7500, ItemID.DHAROKS_HELM_0),
DHAROKS_HELM_100(ItemID.DHAROKS_HELM_100, 10000, ItemID.DHAROKS_HELM_0),
DHAROKS_PLATEBODY_25(ItemID.DHAROKS_PLATEBODY_25, 2500, ItemID.DHAROKS_PLATEBODY_0),
DHAROKS_PLATEBODY_50(ItemID.DHAROKS_PLATEBODY_50, 5000, ItemID.DHAROKS_PLATEBODY_0),
DHAROKS_PLATEBODY_75(ItemID.DHAROKS_PLATEBODY_75, 7500, ItemID.DHAROKS_PLATEBODY_0),
DHAROKS_PLATEBODY_100(ItemID.DHAROKS_PLATEBODY_100, 10000, ItemID.DHAROKS_PLATEBODY_0),
DHAROKS_PLATELEGS_25(ItemID.DHAROKS_PLATELEGS_25, 2500, ItemID.DHAROKS_PLATELEGS_0),
DHAROKS_PLATELEGS_50(ItemID.DHAROKS_PLATELEGS_50, 5000, ItemID.DHAROKS_PLATELEGS_0),
DHAROKS_PLATELEGS_75(ItemID.DHAROKS_PLATELEGS_75, 7500, ItemID.DHAROKS_PLATELEGS_0),
DHAROKS_PLATELEGS_100(ItemID.DHAROKS_PLATELEGS_100, 10000, ItemID.DHAROKS_PLATELEGS_0),
DHAROKS_GREATAXE_25(ItemID.DHAROKS_GREATAXE_25, 2500, ItemID.DHAROKS_GREATAXE_0),
DHAROKS_GREATAXE_50(ItemID.DHAROKS_GREATAXE_50, 5000, ItemID.DHAROKS_GREATAXE_0),
DHAROKS_GREATAXE_75(ItemID.DHAROKS_GREATAXE_75, 7500, ItemID.DHAROKS_GREATAXE_0),
DHAROKS_GREATAXE_100(ItemID.DHAROKS_GREATAXE_100, 10000, ItemID.DHAROKS_GREATAXE_0),
GUTHANS_HELM_25(ItemID.GUTHANS_HELM_25, 2500, ItemID.GUTHANS_HELM_0),
GUTHANS_HELM_50(ItemID.GUTHANS_HELM_50, 5000, ItemID.GUTHANS_HELM_0),
GUTHANS_HELM_75(ItemID.GUTHANS_HELM_75, 7500, ItemID.GUTHANS_HELM_0),
GUTHANS_HELM_100(ItemID.GUTHANS_HELM_100, 10000, ItemID.GUTHANS_HELM_0),
GUTHANS_PLATEBODY_25(ItemID.GUTHANS_PLATEBODY_25, 2500, ItemID.GUTHANS_PLATEBODY_0),
GUTHANS_PLATEBODY_50(ItemID.GUTHANS_PLATEBODY_50, 5000, ItemID.GUTHANS_PLATEBODY_0),
GUTHANS_PLATEBODY_75(ItemID.GUTHANS_PLATEBODY_75, 7500, ItemID.GUTHANS_PLATEBODY_0),
GUTHANS_PLATEBODY_100(ItemID.GUTHANS_PLATEBODY_100, 10000, ItemID.GUTHANS_PLATEBODY_0),
GUTHANS_CHAINSKIRT_25(ItemID.GUTHANS_CHAINSKIRT_25, 2500, ItemID.GUTHANS_CHAINSKIRT_0),
GUTHANS_CHAINSKIRT_50(ItemID.GUTHANS_CHAINSKIRT_50, 5000, ItemID.GUTHANS_CHAINSKIRT_0),
GUTHANS_CHAINSKIRT_75(ItemID.GUTHANS_CHAINSKIRT_75, 7500, ItemID.GUTHANS_CHAINSKIRT_0),
GUTHANS_CHAINSKIRT_100(ItemID.GUTHANS_CHAINSKIRT_100, 10000, ItemID.GUTHANS_CHAINSKIRT_0),
GUTHANS_WARSPEAR_25(ItemID.GUTHANS_WARSPEAR_25, 2500, ItemID.GUTHANS_WARSPEAR_0),
GUTHANS_WARSPEAR_50(ItemID.GUTHANS_WARSPEAR_50, 5000, ItemID.GUTHANS_WARSPEAR_0),
GUTHANS_WARSPEAR_75(ItemID.GUTHANS_WARSPEAR_75, 7500, ItemID.GUTHANS_WARSPEAR_0),
GUTHANS_WARSPEAR_100(ItemID.GUTHANS_WARSPEAR_100, 10000, ItemID.GUTHANS_WARSPEAR_0),
TORAGS_HELM_25(ItemID.TORAGS_HELM_25, 2500, ItemID.TORAGS_HELM_0),
TORAGS_HELM_50(ItemID.TORAGS_HELM_50, 5000, ItemID.TORAGS_HELM_0),
TORAGS_HELM_75(ItemID.TORAGS_HELM_75, 7500, ItemID.TORAGS_HELM_0),
TORAGS_HELM_100(ItemID.TORAGS_HELM_100, 10000, ItemID.TORAGS_HELM_0),
TORAGS_PLATEBODY_25(ItemID.TORAGS_PLATEBODY_25, 2500, ItemID.TORAGS_PLATEBODY_0),
TORAGS_PLATEBODY_50(ItemID.TORAGS_PLATEBODY_50, 5000, ItemID.TORAGS_PLATEBODY_0),
TORAGS_PLATEBODY_75(ItemID.TORAGS_PLATEBODY_75, 7500, ItemID.TORAGS_PLATEBODY_0),
TORAGS_PLATEBODY_100(ItemID.TORAGS_PLATEBODY_100, 10000, ItemID.TORAGS_PLATEBODY_0),
TORAGS_PLATELEGS_25(ItemID.TORAGS_PLATELEGS_25, 2500, ItemID.TORAGS_PLATELEGS_0),
TORAGS_PLATELEGS_50(ItemID.TORAGS_PLATELEGS_50, 5000, ItemID.TORAGS_PLATELEGS_0),
TORAGS_PLATELEGS_75(ItemID.TORAGS_PLATELEGS_75, 7500, ItemID.TORAGS_PLATELEGS_0),
TORAGS_PLATELEGS_100(ItemID.TORAGS_PLATELEGS_100, 10000, ItemID.TORAGS_PLATELEGS_0),
TORAGS_HAMMERS_25(ItemID.TORAGS_HAMMERS_25, 2500, ItemID.TORAGS_HAMMERS_0),
TORAGS_HAMMERS_50(ItemID.TORAGS_HAMMERS_50, 5000, ItemID.TORAGS_HAMMERS_0),
TORAGS_HAMMERS_75(ItemID.TORAGS_HAMMERS_75, 7500, ItemID.TORAGS_HAMMERS_0),
TORAGS_HAMMERS_100(ItemID.TORAGS_HAMMERS_100, 10000, ItemID.TORAGS_HAMMERS_0),
VERACS_HELM_25(ItemID.VERACS_HELM_25, 2500, ItemID.VERACS_HELM_0),
VERACS_HELM_50(ItemID.VERACS_HELM_50, 5000, ItemID.VERACS_HELM_0),
VERACS_HELM_75(ItemID.VERACS_HELM_75, 7500, ItemID.VERACS_HELM_0),
VERACS_HELM_100(ItemID.VERACS_HELM_100, 10000, ItemID.VERACS_HELM_0),
VERACS_BRASSARD_25(ItemID.VERACS_BRASSARD_25, 2500, ItemID.VERACS_BRASSARD_0),
VERACS_BRASSARD_50(ItemID.VERACS_BRASSARD_50, 5000, ItemID.VERACS_BRASSARD_0),
VERACS_BRASSARD_75(ItemID.VERACS_BRASSARD_75, 7500, ItemID.VERACS_BRASSARD_0),
VERACS_BRASSARD_100(ItemID.VERACS_BRASSARD_100, 10000, ItemID.VERACS_BRASSARD_0),
VERACS_PLATESKIRT_25(ItemID.VERACS_PLATESKIRT_25, 2500, ItemID.VERACS_PLATESKIRT_0),
VERACS_PLATESKIRT_50(ItemID.VERACS_PLATESKIRT_50, 5000, ItemID.VERACS_PLATESKIRT_0),
VERACS_PLATESKIRT_75(ItemID.VERACS_PLATESKIRT_75, 7500, ItemID.VERACS_PLATESKIRT_0),
VERACS_PLATESKIRT_100(ItemID.VERACS_PLATESKIRT_100, 10000, ItemID.VERACS_PLATESKIRT_0),
VERACS_FLAIL_25(ItemID.VERACS_FLAIL_25, 2500, ItemID.VERACS_FLAIL_0),
VERACS_FLAIL_50(ItemID.VERACS_FLAIL_50, 5000, ItemID.VERACS_FLAIL_0),
VERACS_FLAIL_75(ItemID.VERACS_FLAIL_75, 7500, ItemID.VERACS_FLAIL_0),
VERACS_FLAIL_100(ItemID.VERACS_FLAIL_100, 10000, ItemID.VERACS_FLAIL_0);
private final int itemId;
private final int offset;
private final int baseId;
private static final Map<Integer, FixedPriceItem> FIXED_ITEMS;
@@ -84,6 +232,18 @@ enum FixedPriceItem
FIXED_ITEMS = map.build();
}
FixedPriceItem(final int itemId, final int offset, final int baseId)
{
this.itemId = itemId;
this.offset = offset;
this.baseId = baseId;
}
FixedPriceItem(final int itemId, final int offset)
{
this(itemId, offset, -1);
}
@Nullable
static FixedPriceItem find(int itemId)
{

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
class ItemStack
{
private int id;
private int qty;
}

View File

@@ -25,6 +25,7 @@
*/
package net.runelite.client.plugins.itemskeptondeath;
import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -32,8 +33,11 @@ import java.util.EnumSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Constants;
@@ -55,6 +59,7 @@ import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.ItemMapping;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.StackFormatter;
@@ -71,6 +76,16 @@ public class ItemsKeptOnDeathPlugin extends Plugin
private static final int DEEP_WILDY = 20;
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+).*");
@AllArgsConstructor
@Getter
@VisibleForTesting
static class DeathItems
{
private final List<ItemStack> keptItems;
private final List<ItemStack> lostItems;
private final boolean hasAlwaysLost;
}
// Item Container helpers
private static final int MAX_ROW_ITEMS = 8;
private static final int ITEM_X_OFFSET = 5;
@@ -100,9 +115,12 @@ public class ItemsKeptOnDeathPlugin extends Plugin
private WidgetButton deepWildyButton;
private WidgetButton lowWildyButton;
private boolean isSkulled;
private boolean protectingItem;
private int wildyLevel;
@VisibleForTesting
boolean isSkulled;
@VisibleForTesting
boolean protectingItem;
@VisibleForTesting
int wildyLevel;
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent event)
@@ -225,97 +243,12 @@ public class ItemsKeptOnDeathPlugin extends Plugin
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
final Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
final List<Item> items = new ArrayList<>();
Collections.addAll(items, inv);
Collections.addAll(items, equip);
final DeathItems deathItems = calculateKeptLostItems(inv, equip);
// Sort by item price
items.sort(Comparator.comparing(this::getDeathPrice).reversed());
boolean hasAlwaysLost = false;
int keepCount = getDefaultItemsKept();
final List<Widget> keptItems = new ArrayList<>();
final List<Widget> lostItems = new ArrayList<>();
for (final Item i : items)
{
final int id = i.getId();
int itemQuantity = i.getQuantity();
if (id == -1)
{
continue;
}
final ItemDefinition c = itemManager.getItemDefinition(i.getId());
// Bonds are always kept and do not count towards the limit.
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
{
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
keptItems.add(itemWidget);
continue;
}
// Certain items are always lost on death and have a white outline which we need to add
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(i.getId());
if (alwaysLostItem != null)
{
// Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
if (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0)
{
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
itemWidget.setBorderType(2); // white outline
lostItems.add(itemWidget);
hasAlwaysLost = true;
continue;
}
// the rune pouch is "always lost" but its kept outside of pvp, and does not count towards your keep count
}
else if (keepCount > 0)
{
// Keep most valuable items regardless of trade-ability.
if (i.getQuantity() > keepCount)
{
final Widget itemWidget = createItemWidget(kept, keepCount, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, keepCount, c.getName());
keptItems.add(itemWidget);
itemQuantity -= keepCount;
keepCount = 0;
// Fall through to below to drop the rest of the stack
}
else
{
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
keptItems.add(itemWidget);
keepCount -= i.getQuantity();
continue;
}
}
// Items are kept if:
// 1) is not tradeable
// 2) is under the deep wilderness line
// 3) is outside of the wilderness, or item has a broken form
if (!Pets.isPet(id)
&& !isTradeable(c) && wildyLevel <= DEEP_WILDY
&& (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId())))
{
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
keptItems.add(itemWidget);
}
else
{
// Otherwise, the item is lost
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
lostItems.add(itemWidget);
}
}
final List<Widget> keptItems = deathItems.getKeptItems().stream()
.map(item -> createItemWidget(kept, item, true)).collect(Collectors.toList());
final List<Widget> lostItems = deathItems.getLostItems().stream()
.map(item -> createItemWidget(lost, item, false)).collect(Collectors.toList());
int rows = (keptItems.size() + MAX_ROW_ITEMS - 1) / MAX_ROW_ITEMS;
// Show an empty row if there isn't anything
@@ -330,36 +263,209 @@ public class ItemsKeptOnDeathPlugin extends Plugin
positionWidgetItems(kept, keptItems);
positionWidgetItems(lost, lostItems);
updateKeptWidgetInfoText(hasAlwaysLost, keptItems, lostItems);
updateKeptWidgetInfoText(deathItems.isHasAlwaysLost(), keptItems, lostItems);
}
/**
* Calculates which items will be kept/lost. first list is kept items, second is lost.
*
* @param inv players inventory
* @param equip players equipement
* @return list of items kept followed by a list of items lost
*/
@VisibleForTesting
DeathItems calculateKeptLostItems(final Item[] inv, final Item[] equip)
{
final List<Item> items = new ArrayList<>();
Collections.addAll(items, inv);
Collections.addAll(items, equip);
// Sort by item price
items.sort(Comparator.comparing(this::getDeathPrice).reversed());
boolean hasClueBox = false;
boolean hasAlwaysLost = false;
int keepCount = getDefaultItemsKept();
final List<ItemStack> keptItems = new ArrayList<>();
final List<ItemStack> lostItems = new ArrayList<>();
for (final Item i : items)
{
final int id = i.getId();
int qty = i.getQuantity();
if (id == -1)
{
continue;
}
final ItemDefinition c = itemManager.getItemDefinition(i.getId());
// Bonds are always kept and do not count towards the limit.
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
{
keptItems.add(new ItemStack(id, qty));
continue;
}
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(id);
if (alwaysLostItem != null && (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0))
{
hasAlwaysLost = true;
hasClueBox = hasClueBox || id == ItemID.CLUE_BOX;
lostItems.add(new ItemStack(id, qty));
continue;
}
if (keepCount > 0)
{
// Keep most valuable items regardless of trade-ability.
if (i.getQuantity() > keepCount)
{
keptItems.add(new ItemStack(id, keepCount));
qty -= keepCount;
keepCount = 0;
// Fall through to determine if the rest of the stack should drop
}
else
{
keptItems.add(new ItemStack(id, qty));
keepCount -= qty;
continue;
}
}
// Items are kept if:
// 1) is not tradeable
// 2) is under the deep wilderness line
// 3) is outside of the wilderness, or item has a broken form
if (!Pets.isPet(id)
&& !LostIfNotProtected.isLostIfNotProtected(id)
&& !isTradeable(itemManager.getItemDefinition(id)) && wildyLevel <= DEEP_WILDY
&& (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId())))
{
keptItems.add(new ItemStack(id, qty));
}
else
{
// Otherwise, the item is lost
lostItems.add(new ItemStack(id, qty));
}
}
if (hasClueBox)
{
boolean alreadyProtectingClue = false;
for (final ItemStack item : keptItems)
{
if (isClueBoxable(item.getId()))
{
alreadyProtectingClue = true;
break;
}
}
if (!alreadyProtectingClue)
{
int clueId = -1;
// Clue box protects the last clue in your inventory so loop over the players inv
for (final Item i : inv)
{
final int id = i.getId();
if (id != -1 && isClueBoxable(id))
{
clueId = id;
}
}
if (clueId != -1)
{
// Move the boxed item to the kept items container and remove it from the lost items container
for (final ItemStack boxableItem : lostItems)
{
if (boxableItem.getId() == clueId)
{
if (boxableItem.getQty() > 1)
{
boxableItem.setQty(boxableItem.getQty() - 1);
keptItems.add(new ItemStack(clueId, 1));
}
else
{
lostItems.remove(boxableItem);
keptItems.add(boxableItem);
}
break;
}
}
}
}
}
return new DeathItems(keptItems, lostItems, hasAlwaysLost);
}
@VisibleForTesting
boolean isClueBoxable(final int itemID)
{
final String name = itemManager.getItemDefinition(itemID).getName();
return name.contains("Clue scroll (") || name.contains("Reward casket (");
}
/**
* Get the price of an item
*
* @param item
* @return
*/
private int getDeathPrice(Item item)
@VisibleForTesting
int getDeathPrice(Item item)
{
// 1) Check if the death price is dynamically calculated, if so return that value
// 2) If death price is based off another item default to that price, otherwise apply normal ItemMapping GE price
// 3) If still no price, default to store price
// 4) Apply fixed price offset if applicable
int itemId = item.getId();
// Unnote/unplaceholder item
int canonicalizedItemId = itemManager.canonicalize(itemId);
int exchangePrice = itemManager.getItemPrice(canonicalizedItemId);
int exchangePrice = 0;
final DynamicPriceItem dynamicPrice = DynamicPriceItem.find(canonicalizedItemId);
if (dynamicPrice != null)
{
final ItemDefinition c1 = itemManager.getItemDefinition(canonicalizedItemId);
exchangePrice = c1.getPrice();
final int basePrice = itemManager.getItemPrice(dynamicPrice.getChargedId(), true);
return dynamicPrice.calculateDeathPrice(basePrice);
}
// Some items have artificially offset death prices - such as ring imbues
// which are +2k over the non imbues. Check if the item has a fixed price offset
final FixedPriceItem fixedPrice = FixedPriceItem.find(canonicalizedItemId);
if (fixedPrice != null && fixedPrice.getBaseId() != -1)
{
// Grab base item price
exchangePrice = itemManager.getItemPrice(fixedPrice.getBaseId(), true);
}
else
{
// Account for items whose death value comes from their tradeable variant (barrows) or components (ornate kits)
for (final int mappedID : ItemMapping.map(canonicalizedItemId))
{
exchangePrice += itemManager.getItemPrice(mappedID, true);
}
}
if (exchangePrice == 0)
{
final ItemDefinition c1 = itemManager.getItemDefinition(canonicalizedItemId);
exchangePrice = c1.getPrice();
}
else
{
// Some items have artifically applied death prices - such as ring imbues
// which are +2k over the non imbues. Check if the item has a fixed price.
FixedPriceItem fixedPrice = FixedPriceItem.find(canonicalizedItemId);
if (fixedPrice != null)
{
// Apply fixed price offset
exchangePrice += fixedPrice.getOffset();
}
}
// Apply fixed price offset
exchangePrice += fixedPrice == null ? 0 : fixedPrice.getOffset();
return exchangePrice;
}
@@ -591,21 +697,29 @@ public class ItemsKeptOnDeathPlugin extends Plugin
/**
* Creates an Item Widget for use inside the Kept on Death Interface
*
* @param qty Amount of item
* @param c Items Composition
* @return
* @param parent Widget to add element too as a child
* @param item the TempItem representing the item
* @param kept is the item being shown in the kept items container
* @return the Widget that was added to the `parent`
*/
private static Widget createItemWidget(final Widget parent, final int qty, final ItemDefinition c)
private Widget createItemWidget(final Widget parent, final ItemStack item, boolean kept)
{
final int id = item.getId();
final int qty = item.getQty();
final ItemDefinition c = itemManager.getItemComposition(id);
final Widget itemWidget = parent.createChild(-1, WidgetType.GRAPHIC);
itemWidget.setItemId(c.getId());
itemWidget.setItemQuantity(qty);
itemWidget.setHasListener(true);
itemWidget.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
itemWidget.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
itemWidget.setBorderType(1);
itemWidget.setItemId(id);
itemWidget.setItemQuantity(qty);
itemWidget.setAction(1, String.format("Item: <col=ff981f>%s", c.getName()));
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, kept ? 1 : 0, qty, c.getName());
itemWidget.setHasListener(true);
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(id);
final boolean whiteBorder = alwaysLostItem != null && (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0);
itemWidget.setBorderType(whiteBorder ? 2 : 1);
return itemWidget;
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import net.runelite.api.ItemID;
final class LostIfNotProtected
{
private static final Set<Integer> ITEMS = ImmutableSet.of(
ItemID.AMULET_OF_THE_DAMNED,
ItemID.RING_OF_CHAROS, ItemID.RING_OF_CHAROSA,
ItemID.LUNAR_STAFF,
ItemID.SHADOW_SWORD,
ItemID.KERIS, ItemID.KERISP, ItemID.KERISP_10583, ItemID.KERISP_10584
);
public static boolean isLostIfNotProtected(int id)
{
return ITEMS.contains(id);
}
}

View File

@@ -103,10 +103,153 @@ public interface KeyRemappingConfig extends Config
position = 6,
keyName = "fkeyRemap",
name = "Remap F Keys",
description = "Configures whether F-Keys are Remapped to 1 (F1) through 0 (F10), '-' (F11), and '=' (F12)"
description = "Configures whether F-Keys use remapped keys"
)
default boolean fkeyRemap()
{
return false;
}
@ConfigItem(
position = 7,
keyName = "f1",
name = "F1",
description = "The key which will replace {F1}."
)
default ModifierlessKeybind f1()
{
return new ModifierlessKeybind(KeyEvent.VK_1, 0);
}
@ConfigItem(
position = 8,
keyName = "f2",
name = "F2",
description = "The key which will replace {F2}."
)
default ModifierlessKeybind f2()
{
return new ModifierlessKeybind(KeyEvent.VK_2, 0);
}
@ConfigItem(
position = 9,
keyName = "f3",
name = "F3",
description = "The key which will replace {F3}."
)
default ModifierlessKeybind f3()
{
return new ModifierlessKeybind(KeyEvent.VK_3, 0);
}
@ConfigItem(
position = 10,
keyName = "f4",
name = "F4",
description = "The key which will replace {F4}."
)
default ModifierlessKeybind f4()
{
return new ModifierlessKeybind(KeyEvent.VK_4, 0);
}
@ConfigItem(
position = 11,
keyName = "f5",
name = "F5",
description = "The key which will replace {F5}."
)
default ModifierlessKeybind f5()
{
return new ModifierlessKeybind(KeyEvent.VK_5, 0);
}
@ConfigItem(
position = 12,
keyName = "f6",
name = "F6",
description = "The key which will replace {F6}."
)
default ModifierlessKeybind f6()
{
return new ModifierlessKeybind(KeyEvent.VK_6, 0);
}
@ConfigItem(
position = 13,
keyName = "f7",
name = "F7",
description = "The key which will replace {F7}."
)
default ModifierlessKeybind f7()
{
return new ModifierlessKeybind(KeyEvent.VK_7, 0);
}
@ConfigItem(
position = 14,
keyName = "f8",
name = "F8",
description = "The key which will replace {F8}."
)
default ModifierlessKeybind f8()
{
return new ModifierlessKeybind(KeyEvent.VK_8, 0);
}
@ConfigItem(
position = 15,
keyName = "f9",
name = "F9",
description = "The key which will replace {F9}."
)
default ModifierlessKeybind f9()
{
return new ModifierlessKeybind(KeyEvent.VK_9, 0);
}
@ConfigItem(
position = 16,
keyName = "f10",
name = "F10",
description = "The key which will replace {F10}."
)
default ModifierlessKeybind f10()
{
return new ModifierlessKeybind(KeyEvent.VK_0, 0);
}
@ConfigItem(
position = 17,
keyName = "f11",
name = "F11",
description = "The key which will replace {F11}."
)
default ModifierlessKeybind f11()
{
return new ModifierlessKeybind(KeyEvent.VK_MINUS, 0);
}
@ConfigItem(
position = 18,
keyName = "f12",
name = "F12",
description = "The key which will replace {F12}."
)
default ModifierlessKeybind f12()
{
return new ModifierlessKeybind(KeyEvent.VK_EQUALS, 0);
}
@ConfigItem(
position = 19,
keyName = "esc",
name = "ESC",
description = "The key which will replace {ESC}."
)
default ModifierlessKeybind esc()
{
return new ModifierlessKeybind(KeyEvent.VK_ESCAPE, 0);
}
}

View File

@@ -35,26 +35,12 @@ import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.VarClientStr;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.Keybind;
import net.runelite.client.config.ModifierlessKeybind;
import net.runelite.client.input.KeyListener;
import net.runelite.client.input.MouseAdapter;
@Singleton
class KeyRemappingListener extends MouseAdapter implements KeyListener
{
private static final Keybind ONE = new ModifierlessKeybind(KeyEvent.VK_1, 0);
private static final Keybind TWO = new ModifierlessKeybind(KeyEvent.VK_2, 0);
private static final Keybind THREE = new ModifierlessKeybind(KeyEvent.VK_3, 0);
private static final Keybind FOUR = new ModifierlessKeybind(KeyEvent.VK_4, 0);
private static final Keybind FIVE = new ModifierlessKeybind(KeyEvent.VK_5, 0);
private static final Keybind SIX = new ModifierlessKeybind(KeyEvent.VK_6, 0);
private static final Keybind SEVEN = new ModifierlessKeybind(KeyEvent.VK_7, 0);
private static final Keybind EIGHT = new ModifierlessKeybind(KeyEvent.VK_8, 0);
private static final Keybind NINE = new ModifierlessKeybind(KeyEvent.VK_9, 0);
private static final Keybind ZERO = new ModifierlessKeybind(KeyEvent.VK_0, 0);
private static final Keybind MINUS = new ModifierlessKeybind(KeyEvent.VK_MINUS, 0);
private static final Keybind EQUALS = new ModifierlessKeybind(KeyEvent.VK_EQUALS, 0);
@Inject
private KeyRemappingPlugin plugin;
@@ -111,66 +97,71 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
// to select options
if (plugin.isFkeyRemap() && !plugin.isDialogOpen())
{
if (ONE.matches(e))
if (config.f1().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F1);
e.setKeyCode(KeyEvent.VK_F1);
}
else if (TWO.matches(e))
else if (config.f2().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F2);
e.setKeyCode(KeyEvent.VK_F2);
}
else if (THREE.matches(e))
else if (config.f3().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F3);
e.setKeyCode(KeyEvent.VK_F3);
}
else if (FOUR.matches(e))
else if (config.f4().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F4);
e.setKeyCode(KeyEvent.VK_F4);
}
else if (FIVE.matches(e))
else if (config.f5().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F5);
e.setKeyCode(KeyEvent.VK_F5);
}
else if (SIX.matches(e))
else if (config.f6().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F6);
e.setKeyCode(KeyEvent.VK_F6);
}
else if (SEVEN.matches(e))
else if (config.f7().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F7);
e.setKeyCode(KeyEvent.VK_F7);
}
else if (EIGHT.matches(e))
else if (config.f8().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F8);
e.setKeyCode(KeyEvent.VK_F8);
}
else if (NINE.matches(e))
else if (config.f9().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F9);
e.setKeyCode(KeyEvent.VK_F9);
}
else if (ZERO.matches(e))
else if (config.f10().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F10);
e.setKeyCode(KeyEvent.VK_F10);
}
else if (MINUS.matches(e))
else if (config.f11().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F11);
e.setKeyCode(KeyEvent.VK_F11);
}
else if (EQUALS.matches(e))
else if (config.f12().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F12);
e.setKeyCode(KeyEvent.VK_F12);
}
else if (config.esc().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_ESCAPE);
e.setKeyCode(KeyEvent.VK_ESCAPE);
}
}
switch (e.getKeyCode())
@@ -189,8 +180,12 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
{
switch (e.getKeyCode())
{
case KeyEvent.VK_ENTER:
case KeyEvent.VK_ESCAPE:
// When existing typing mode, block the escape key
// so that it doesn't trigger the in-game hotkeys
e.consume();
// FALLTHROUGH
case KeyEvent.VK_ENTER:
plugin.setTyping(false);
clientThread.invoke(plugin::lockChat);
break;
@@ -240,54 +235,58 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
if (plugin.isFkeyRemap())
{
if (ONE.matches(e))
if (config.f1().matches(e))
{
e.setKeyCode(KeyEvent.VK_F1);
}
else if (TWO.matches(e))
else if (config.f2().matches(e))
{
e.setKeyCode(KeyEvent.VK_F2);
}
else if (THREE.matches(e))
else if (config.f3().matches(e))
{
e.setKeyCode(KeyEvent.VK_F3);
}
else if (FOUR.matches(e))
else if (config.f4().matches(e))
{
e.setKeyCode(KeyEvent.VK_F4);
}
else if (FIVE.matches(e))
else if (config.f5().matches(e))
{
e.setKeyCode(KeyEvent.VK_F5);
}
else if (SIX.matches(e))
else if (config.f6().matches(e))
{
e.setKeyCode(KeyEvent.VK_F6);
}
else if (SEVEN.matches(e))
else if (config.f7().matches(e))
{
e.setKeyCode(KeyEvent.VK_F7);
}
else if (EIGHT.matches(e))
else if (config.f8().matches(e))
{
e.setKeyCode(KeyEvent.VK_F8);
}
else if (NINE.matches(e))
else if (config.f9().matches(e))
{
e.setKeyCode(KeyEvent.VK_F9);
}
else if (ZERO.matches(e))
else if (config.f10().matches(e))
{
e.setKeyCode(KeyEvent.VK_F10);
}
else if (MINUS.matches(e))
else if (config.f11().matches(e))
{
e.setKeyCode(KeyEvent.VK_F11);
}
else if (EQUALS.matches(e))
else if (config.f12().matches(e))
{
e.setKeyCode(KeyEvent.VK_F12);
}
else if (config.esc().matches(e))
{
e.setKeyCode(KeyEvent.VK_ESCAPE);
}
}
}
else

View File

@@ -118,7 +118,7 @@ public class GameEventManager
if (itemContainer != null)
{
eventBus.post(new ItemContainerChanged(itemContainer));
eventBus.post(new ItemContainerChanged(inventory.getId(), itemContainer));
}
}