* LOTS!

* updates + fixes

new plugin type.

* .

* Update MenuEntrySwapperPlugin.java

oops

* Update MenuEntrySwapperPlugin.java

checkstyle

* missed a bit

* Update PluginSorterConfig.java

S = s

* portal nexus

* Update MenuEntrySwapperPlugin.java

* Update ItemMapping.java

* Update AnimationID.java

* Update ThievingOverlay.java

* Update AntiDragPlugin.java
This commit is contained in:
Kyleeld
2019-05-22 17:31:26 +01:00
committed by ThatGamerBlue
parent 2804f72b87
commit 58086b605d
16 changed files with 765 additions and 32 deletions

View File

@@ -155,13 +155,15 @@ public final class AnimationID
public static final int SAND_COLLECTION = 895;
public static final int PISCARILIUS_CRANE_REPAIR = 7199;
public static final int HOME_MAKE_TABLET = 4067;
public static final int THIEVING_STALL = 832;
public static final int PICKPOCKET_SUCCESS = 881;
//block animations for players and perhaps npcs as well?
public static final int BLOCK_DEFENDER = 4177;
public static final int BLOCK_NO_SHIELD = 420;
public static final int BLOCK_SHIELD = 1156;
public static final int BLOCK_SWORD = 388;
public static final int BLOCK_UNARMED = 424;
public static final int BLOCK_UNARMED = 424; // Same Animation as failed pickpocked
// NPC animations
public static final int TZTOK_JAD_MAGIC_ATTACK = 2656;

View File

@@ -2,15 +2,11 @@ package net.runelite.client.plugins;
public enum PluginType
{
PVM,
PVP,
SKILLING,
UTILITY,
GENERAL_USE,
EXTERNAL,
PLUGIN_ORGANIZER
}

View File

@@ -38,7 +38,7 @@ import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.HotkeyListener;
@PluginDescriptor(
name = "Shift Anti Drag",
name = "Anti Drag",
description = "Prevent dragging an item for a specified delay",
tags = {"antidrag", "delay", "inventory", "items"},
type = PluginType.UTILITY,

View File

@@ -49,7 +49,7 @@ import static net.runelite.client.util.MenuUtil.swap;
name = "Blackjack",
description = "Uses chat messages and tick timers instead of animations to read",
tags = {"blackjack", "thieving"},
type = PluginType.UTILITY
type = PluginType.SKILLING
)
@Singleton
@Slf4j

View File

@@ -248,6 +248,25 @@ public class ConfigPanel extends PluginPanel
pvmPlugins.sort(Comparator.comparing(PluginListItem::getName));
pluginList.addAll(pvmPlugins);
List<PluginListItem> skillingPlugins = new ArrayList<>();
// populate pluginList with all non-hidden plugins
pluginManager.getPlugins().stream()
.filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.SKILLING))
.forEach(plugin ->
{
final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
final Config config = pluginManager.getPluginConfigProxy(plugin);
final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor);
listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
skillingPlugins.add(listItem);
});
skillingPlugins.sort(Comparator.comparing(PluginListItem::getName));
pluginList.addAll(skillingPlugins);
List<PluginListItem> pvpPlugins = new ArrayList<>();
// populate pluginList with all PVP Plugins
pluginManager.getPlugins().stream()
@@ -290,6 +309,7 @@ public class ConfigPanel extends PluginPanel
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PVM))
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PVP))
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.SKILLING))
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.UTILITY))
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.PLUGIN_ORGANIZER))
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals(PluginType.EXTERNAL))

View File

@@ -57,7 +57,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapAdmire",
name = "Admire",
description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes."
description = "Swap Admire with Teleport, Spellbook and Perks (max cape) for mounted skill capes.",
group = "Swap Teleport"
)
default boolean swapAdmire()
{
@@ -67,7 +68,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapAssignment",
name = "Assignment",
description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade."
description = "Swap Talk-to with Assignment for Slayer Masters. This will take priority over swapping Trade.",
group = "Swap Talk-To"
)
default boolean swapAssignment()
{
@@ -77,7 +79,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapBanker",
name = "Bank",
description = "Swap Talk-to with Bank on Bank NPC<br>Example: Banker"
description = "Swap Talk-to with Bank on Bank NPC<br>Example: Banker",
group = "Swap Talk-To"
)
default boolean swapBank()
{
@@ -107,7 +110,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapContract",
name = "Contract",
description = "Swap Talk-to with Contract on Guildmaster Jane"
description = "Swap Talk-to with Contract on Guildmaster Jane",
group = "Swap Talk-To"
)
default boolean swapContract()
{
@@ -124,10 +128,22 @@ public interface MenuEntrySwapperConfig extends Config
return true;
}
@ConfigItem(
keyName = "claimDynamite",
name = "Claim Dynamite",
description = "Swap Talk-to with Claim Dynamite on Thirus",
group = "Swap Talk-To"
)
default boolean claimDynamite()
{
return true;
}
@ConfigItem(
keyName = "claimSlime",
name = "Claim Slime",
description = "Swap Talk-to with Claim Slime from Morytania diaries"
description = "Swap Talk-to with Claim Slime from Morytania diaries",
group = "Swap Talk-To"
)
default boolean claimSlime()
{
@@ -137,7 +153,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapDarkMage",
name = "Repairs",
description = "Swap Talk-to with Repairs for Dark Mage"
description = "Swap Talk-to with Repairs for Dark Mage",
group = "Swap Talk-To"
)
default boolean swapDarkMage()
{
@@ -147,7 +164,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapDecant",
name = "Decant",
description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange."
description = "Swap Talk-to with Decant for Bob Barter and Murky Matt at the Grand Exchange.",
group = "Swap Talk-To"
)
default boolean swapDecant()
{
@@ -157,7 +175,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapExchange",
name = "Exchange",
description = "Swap Talk-to with Exchange on NPC<br>Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight"
description = "Swap Talk-to with Exchange on NPC<br>Example: Grand Exchange Clerk, Tool Leprechaun, Void Knight",
group = "Swap Talk-To"
)
default boolean swapExchange()
{
@@ -167,7 +186,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapFairyRing",
name = "Fairy ring",
description = "Swap Zanaris with Last-destination or Configure on Fairy rings"
description = "Swap Zanaris with Last-destination or Configure on Fairy rings",
group = "Swap Teleport"
)
default FairyRingMode swapFairyRing()
{
@@ -183,6 +203,27 @@ public interface MenuEntrySwapperConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "swapOccult",
name = "Occult Altar",
description = "Swap Venerate with Ancient, Lunar, or Arceuus on an Altar of the Occult"
)
default OccultAltarMode swapOccult()
{
return OccultAltarMode.VENERATE;
}
@ConfigItem(
keyName = "swapObelisk",
name = "Obelisk",
description = "Swap the options on wilderness obelisks between Activate, Set destination or Teleport to destination",
group = "Swap Teleport"
)
default ObeliskMode swapObelisk()
{
return ObeliskMode.ACTIVATE;
}
@ConfigItem(
keyName = "swapHomePortal",
@@ -197,7 +238,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapPickpocket",
name = "Pickpocket on H.A.M.",
description = "Swap Talk-to with Pickpocket on H.A.M members"
description = "Swap Talk-to with Pickpocket on H.A.M members",
group = "Swap Talk-To"
)
default boolean swapPickpocket()
{
@@ -207,7 +249,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapPay",
name = "Pay",
description = "Swap Talk-to with Pay on NPC<br>Example: Elstan, Heskel, Fayeth"
description = "Swap Talk-to with Pay on NPC<br>Example: Elstan, Heskel, Fayeth",
group = "Swap Talk-To"
)
default boolean swapPay()
{
@@ -267,7 +310,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapAbyssTeleport",
name = "Teleport to Abyss",
description = "Swap Talk-to with Teleport for the Mage of Zamorak"
description = "Swap Talk-to with Teleport for the Mage of Zamorak",
group = "Swap Talk-To"
)
default boolean swapAbyssTeleport()
{
@@ -277,7 +321,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapTrade",
name = "Trade",
description = "Swap Talk-to with Trade on NPC<br>Example: Shop keeper, Shop assistant"
description = "Swap Talk-to with Trade on NPC<br>Example: Shop keeper, Shop assistant",
group = "Swap Talk-To"
)
default boolean swapTrade()
{
@@ -287,7 +332,8 @@ public interface MenuEntrySwapperConfig extends Config
@ConfigItem(
keyName = "swapTravel",
name = "Travel",
description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC<br>Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember"
description = "Swap Talk-to with Travel, Take-boat, Pay-fare, Charter on NPC<br>Example: Squire, Monk of Entrana, Customs officer, Trader Crewmember",
group = "Swap Talk-To"
)
default boolean swapTravel()
{
@@ -315,9 +361,9 @@ public interface MenuEntrySwapperConfig extends Config
}
@ConfigItem(
keyName = "swapClimbUpDown",
name = "Climb",
description = "Swap Climb-Up/Down depending on Shift or Control key "
keyName = "swapClimbUpDown",
name = "Climb",
description = "Swap Climb-Up/Down depending on Shift or Control key "
)
default boolean swapClimbUpDown()
{
@@ -325,12 +371,109 @@ public interface MenuEntrySwapperConfig extends Config
}
@ConfigItem(
keyName = "swapDream",
name = "Dream",
description = "Swap Talk-to with Dream for Dominic Onion"
keyName = "swapDream",
name = "Dream",
description = "Swap Talk-to with Dream for Dominic Onion",
group = "Swap Talk-To"
)
default boolean swapDream()
{
return true;
}
@ConfigItem(
keyName = "swapStory",
name = "Story",
description = "Swap Talk-to with Story for Juna at Tears of Guthix",
group = "Swap Talk-To"
)
default boolean swapStory()
{
return true;
}
@ConfigItem(
keyName = "swapPlank",
name = "Buy Planks",
description = "Swap Talk-to with Buy-planks at the Lumber Yard.",
group = "Swap Talk-To"
)
default boolean swapPlank()
{
return true;
}
@ConfigItem(
keyName = "swapStun",
name = "Stun Hoop Snakes",
description = "Swap Attack with Stun"
)
default boolean swapStun()
{
return true;
}
@ConfigItem(
keyName = "swapMetamorphosis",
name = "Metamorphosis",
description = "Swap Talk-to with Metamorphosis for Baby Chinchompa pet.",
group = "Swap Talk-To"
)
default boolean swapMetamorphosis()
{
return false;
}
@ConfigItem(
keyName = "swapEscort",
name = "Escort",
description = "Swap Talk-to with Escort for the Temple Trekking mini-game.",
group = "Swap Talk-To"
)
default boolean swapEscort()
{
return true;
}
@ConfigItem(
keyName = "swapWildernessLever",
name = "Wilderness Lever",
description = "Swap wilderness lever left click to be Edgeville/Ardougne.",
group = "Swap Teleport"
)
default boolean swapWildernessLever()
{
return true;
}
@ConfigItem(
keyName = "swapNexus",
name = "Portal Nexus",
description = "Makes the teleport menu have priority over the left click destination on the portal nexus",
group = "Swap Teleport"
)
default boolean swapNexus()
{
return true;
}
@ConfigItem(
keyName = "swapSearch",
name = "Search",
description = "Swap Close, Shut with Search on chests, cupboards, etc."
)
default boolean swapSearch()
{
return true;
}
@ConfigItem(
keyName = "swapHardWoodGrove",
name = "Hardwood Grove",
description = "Swap Quick-Pay(100) and Send-Parcel at Hardwood Grove"
)
default boolean swapHardWoodGrove()
{
return true;
}
}

View File

@@ -404,6 +404,10 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "teleport", option, target, true);
}
if (config.swapHardWoodGrove() && target.contains("rionasta"))
{
swap(client, "send-parcel", option, target, true);
}
if (config.swapBank())
{
swap(client, "bank", option, target, true);
@@ -429,6 +433,11 @@ public class MenuEntrySwapperPlugin extends Plugin
{
swap(client, "assignment", option, target, true);
}
if (config.swapPlank())
{
swap(client, "buy-plank", option, target, true);
}
if (config.swapTrade())
{
@@ -440,6 +449,11 @@ public class MenuEntrySwapperPlugin extends Plugin
{
swap(client, "claim-slime", option, target, true);
}
if (config.claimDynamite() && target.contains("Thirus"))
{
swap(client, "claim-dynamite", option, target, true);
}
if (config.swapTravel())
{
@@ -475,8 +489,33 @@ public class MenuEntrySwapperPlugin extends Plugin
{
swap(client, "quick-travel", option, target, true);
}
if (config.swapStory())
{
swap(client, "story", option, target, true);
}
if (config.swapEscort())
{
swap(client, "escort", option, target, true);
}
}
else if (config.swapWildernessLever() && target.equals("lever") && option.equals("ardougne"))
{
swap(client, "edgeville", option, target, true);
}
else if (config.swapMetamorphosis() && target.contains("baby chinchompa"))
{
swap(client, "metamorphosis", option, target, true);
}
else if (config.swapStun() && target.contains("hoop snake"))
{
swap(client, "stun", option, target, true);
}
else if (config.swapTravel() && option.equals("pass") && target.equals("energy barrier"))
{
swap(client, "pay-toll(2-ecto)", option, target, true);
@@ -502,6 +541,41 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "harpoon", option, target, true);
}
else if (config.swapOccult() != OccultAltarMode.VENERATE && option.equals("venerate"))
{
switch (config.swapOccult())
{
case VENERATE:
swap(client, "Venerate", option, target, true);
break;
case ANCIENT:
swap(client, "Ancient", option, target, true);
break;
case LUNAR:
swap(client, "Lunar", option, target, true);
break;
case ARCEUUS:
swap(client, "Arceuus", option, target, true);
}
}
else if (config.swapObelisk() != ObeliskMode.ACTIVATE && option.equals("activate"))
{
switch (config.swapObelisk())
{
case ACTIVATE:
swap(client, "activate", option, target, true);
break;
case SET_DESTINATION:
swap(client, "set destination", option, target, true);
break;
case TELEPORT_TO_DESTINATION:
swap(client, "teleport to destination", option, target, true);
break;
}
}
else if (config.swapHomePortal() != HouseMode.ENTER && option.equals("enter"))
{
switch (config.swapHomePortal())
@@ -543,6 +617,7 @@ public class MenuEntrySwapperPlugin extends Plugin
else if (config.swapBoxTrap() && option.equals("take"))
{
swap(client, "lay", option, target, true);
swap(client, "activate", option, target, true);
}
else if (config.swapChase() && option.equals("pick-up"))
@@ -588,6 +663,11 @@ public class MenuEntrySwapperPlugin extends Plugin
swap(client, "pick-lots", option, target, true);
}
else if (config.swapSearch() && (option.equals("close") || option.equals("shut")))
{
swap(client, "search", option, target, true);
}
else if (config.swapRogueschests() && target.contains("chest"))
{
swap(client, "search for traps", option, target, true);
@@ -626,6 +706,10 @@ public class MenuEntrySwapperPlugin extends Plugin
{
swap(client, "use", option, target, true);
}
else if (config.swapNexus() && target.contains("portal nexus"))
{
swap(client, "teleport menu", option, target, true);
}
}
@Subscribe

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Snakk <http://github.com/SnakkSnokk>
* 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.menuentryswapper;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum ObeliskMode
{
ACTIVATE("Activate"),
SET_DESTINATION("Set destination"),
TELEPORT_TO_DESTINATION("Teleport to destination");
private final String name;
@Override
public String toString()
{
return name;
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019, Spedwards <https://github.com/Spedwards>
* 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.menuentryswapper;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum OccultAltarMode
{
ANCIENT("Ancient"),
LUNAR("Lunar"),
ARCEUUS("Arceuus"),
VENERATE("Venerate");
private final String name;
@Override
public String toString()
{
return name;
}
}

View File

@@ -60,7 +60,7 @@ import net.runelite.client.ui.overlay.OverlayManager;
name = "Mining",
description = "Show helpful information about Mining",
tags = {"mining", "skilling", "overlay"},
type = PluginType.UTILITY,
type = PluginType.SKILLING,
enabledByDefault = false
)
public class MiningPlugin extends Plugin

View File

@@ -77,12 +77,23 @@ public interface PluginSorterConfig extends Config
{
return Color.RED;
}
@ConfigItem(
position = 4,
keyName = "skillingColor",
name = "Skilling color",
description = "Configure the color of Skilling related plugins"
)
default Color skillingColor()
{
return Color.YELLOW;
}
@ConfigItem(
position = 5,
keyName = "utilityColor",
name = "Utility color",
description = "Configure the color of utility related plugins"
description = "Configure the color of Utility related plugins"
)
default Color utilityColor()
{

View File

@@ -120,6 +120,9 @@ public class PluginSorterPlugin extends Plugin
case PVP:
pli.nameLabel.setForeground(config.pvpColor());
break;
case SKILLING:
pli.nameLabel.setForeground(config.skillingColor());
break;
case UTILITY:
pli.nameLabel.setForeground(config.utilityColor());
break;
@@ -143,6 +146,7 @@ public class PluginSorterPlugin extends Plugin
{
case PVM:
case PVP:
case SKILLING:
case UTILITY:
case EXTERNAL:
iter.remove();

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2018, Joris K <kjorisje@gmail.com>
* Copyright (c) 2018, Lasse <cronick@zytex.dk>
* Copyright (c) 2019, ermalsh <github.com/ermalsh>
* 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.thieving;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("thieving")
public interface ThievingConfig extends Config
{
@ConfigItem
(
position = 1,
keyName = "statTimeout",
name = "Reset stats (minutes)",
description = "Change the time until the thieving session is reset and the overlay is hidden"
)
default int statTimeout()
{
return 5;
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2018, Joris K <kjorisje@gmail.com>
* Copyright (c) 2018, Lasse <cronick@zytex.dk>
* Copyright (c) 2019, ermalsh <github.com/ermalsh>
* 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.thieving;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.text.DecimalFormat;
import javax.inject.Inject;
import static net.runelite.api.AnimationID.THIEVING_STALL;
import static net.runelite.api.AnimationID.PICKPOCKET_SUCCESS;
import static net.runelite.api.AnimationID.BLOCK_UNARMED;
import net.runelite.api.Client;
import net.runelite.api.Skill;
import net.runelite.client.plugins.xptracker.XpTrackerService;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
import net.runelite.client.ui.overlay.components.TitleComponent;
public class ThievingOverlay extends Overlay
{
private static final DecimalFormat FORMAT = new DecimalFormat("#.#");
private final Client client;
private final ThievingPlugin plugin;
private final XpTrackerService xpTrackerService;
private final PanelComponent panelComponent = new PanelComponent();
@Inject
private ThievingOverlay(Client client, ThievingPlugin plugin, XpTrackerService xpTrackerService)
{
setPosition(OverlayPosition.TOP_LEFT);
this.client = client;
this.plugin = plugin;
this.xpTrackerService = xpTrackerService;
}
@Override
public Dimension render(Graphics2D graphics)
{
ThievingSession session = plugin.getSession();
if (session == null)
{
return null;
}
panelComponent.setPreferredSize(new Dimension(145, 0));
panelComponent.getChildren().clear();
if (isThieving())
{
panelComponent.getChildren().add(TitleComponent.builder()
.text("Thieving")
.color(Color.GREEN)
.build());
}
else if (isStunned())
{
panelComponent.getChildren().add(TitleComponent.builder()
.text("Stunned")
.color(Color.ORANGE)
.build());
}
else
{
panelComponent.getChildren().add(TitleComponent.builder()
.text("NOT thieving")
.color(Color.RED)
.build());
}
panelComponent.getChildren().add(LineComponent.builder()
.left("Succeeded:")
.right(session.getSuccessful() + (session.getSuccessful() >= 1 ? " (" + xpTrackerService.getActionsHr(Skill.THIEVING) + "/hr)" : ""))
.build());
panelComponent.getChildren().add(LineComponent.builder()
.left("Failed:")
.right(session.getFailed() + (session.getFailed() >= 1 ? " (" + FORMAT.format(session.getSuccessRate()) + "%)" : ""))
.build());
return panelComponent.render(graphics);
}
private boolean isThieving()
{
switch (client.getLocalPlayer().getAnimation())
{
case THIEVING_STALL:
case PICKPOCKET_SUCCESS:
return true;
default:
return false;
}
}
private boolean isStunned()
{
switch (client.getLocalPlayer().getAnimation())
{
case BLOCK_UNARMED:
return true;
default:
return false;
}
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2018, Joris K <kjorisje@gmail.com>
* Copyright (c) 2018, Lasse <cronick@zytex.dk>
* Copyright (c) 2019, ermalsh <github.com/ermalsh>
* 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.thieving;
import java.time.Duration;
import java.time.Instant;
import javax.inject.Inject;
import lombok.AccessLevel;
import lombok.Getter;
import com.google.inject.Provides;
import net.runelite.api.ChatMessageType;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameTick;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDependency;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.xptracker.XpTrackerPlugin;
import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor
(
name = "Thieving",
description = "Show thieving overlay",
tags = {"overlay", "skilling", "thieving", "pickpocketing"},
type = PluginType.SKILLING
)
@PluginDependency(XpTrackerPlugin.class)
public class ThievingPlugin extends Plugin
{
@Inject
private ThievingConfig config;
@Inject
private ThievingOverlay overlay;
@Inject
private OverlayManager overlayManager;
@Getter(AccessLevel.PACKAGE)
private ThievingSession session;
@Provides
ThievingConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(ThievingConfig.class);
}
@Override
protected void startUp() throws Exception
{
session = null;
overlayManager.add(overlay);
}
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(overlay);
session = null;
}
@Subscribe
public void onGameTick(GameTick gameTick)
{
if (session == null || config.statTimeout() == 0)
{
return;
}
Duration statTimeout = Duration.ofMinutes(config.statTimeout());
Duration sinceCut = Duration.between(session.getLastTheivingAction(), Instant.now());
if (sinceCut.compareTo(statTimeout) >= 0)
{
session = null;
}
}
@Subscribe
public void onChatMessage(ChatMessage event)
{
if (event.getType() != ChatMessageType.SPAM)
{
return;
}
final String message = event.getMessage();
if (message.startsWith("You pick") || message.startsWith("You steal"))
{
if (session == null)
{
session = new ThievingSession();
}
session.updateLastThevingAction();
session.hasSucceeded();
}
else if (message.startsWith("You fail to pick"))
{
if (session == null)
{
session = new ThievingSession();
}
session.updateLastThevingAction();
session.hasFailed();
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2018, Joris K <kjorisje@gmail.com>
* Copyright (c) 2018, Lasse <cronick@zytex.dk>
* Copyright (c) 2019, ermalsh <github.com/ermalsh>
* 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.thieving;
import java.time.Instant;
import lombok.AccessLevel;
import lombok.Getter;
public class ThievingSession
{
@Getter(AccessLevel.PACKAGE)
private Instant lastTheivingAction;
@Getter(AccessLevel.PACKAGE)
private int successful;
@Getter(AccessLevel.PACKAGE)
private int failed;
void updateLastThevingAction()
{
this.lastTheivingAction = Instant.now();
}
void hasSucceeded()
{
this.successful++;
}
void hasFailed()
{
this.failed++;
}
double getSuccessRate()
{
return ((double) getFailed() / (getSuccessful() + getFailed())) * 100;
}
}