additonal plugins

This commit is contained in:
Kyleeld
2019-04-20 18:51:11 +01:00
parent 8261532192
commit 22ca3f43e4
17 changed files with 5243 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
package net.runelite.client.plugins.groupitemlist;
import net.runelite.api.Client;
import net.runelite.api.MenuEntry;
import net.runelite.api.events.MenuOpened;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@PluginDescriptor(
name = "!Group Item List",
description = "Group the right click menu of a pile of items.",
tags = {"ground", "compress", "pile", "group"},
enabledByDefault = false
)
/**
* Main class of plugin - Groups duplicate right click menu options to singular entries with a quantity.
*
*/
public class GroupItemListPlugin extends Plugin {
@Inject
private Client client;
/**
* Fired on a right click menu opening. Count all menu entries and build a new list of entries
* displaying item quantities.
*
* @param menu Right click menu opened
*/
@Subscribe
public void onMenuOpened(MenuOpened menu) {
LinkedHashMap<MenuEntry, GroupedItem> entryCount = new LinkedHashMap<>();
ArrayList<MenuEntry> temp = new ArrayList<>();
MenuEntry[] updatedMenuEntries;
// Iterate over menu entries
for (MenuEntry e : menu.getMenuEntries()) {
// Increment the count if entry has been seen before
if (entryCount.containsKey(e)) {
entryCount.get(e).incrementCount();
}
// Store in map if entry has not been seen before
else {
entryCount.put(e, new GroupedItem(e));
}
}
// Create a list of updated menu entries from the map of GroupedItem
for (MenuEntry e : entryCount.keySet()) {
MenuEntry entry = entryCount.get(e).getEntry();
temp.add(entry);
}
// Parse to an array and set the new menu entries
updatedMenuEntries = temp.toArray(new MenuEntry[0]);
client.setMenuEntries(updatedMenuEntries);
}
}

View File

@@ -0,0 +1,61 @@
package net.runelite.client.plugins.groupitemlist;
import net.runelite.api.MenuEntry;
/**
* Object used to store a MenuEntry and the quantity. Updates the entry target if necessary
* e.g Shark to Shark [4].
*/
public class GroupedItem {
private int count;
private MenuEntry entry;
/**
* Constructor for GroupedItem.
*
* @param entry The menu entry to be tracked for duplicates
*/
public GroupedItem(MenuEntry entry) {
this.entry = entry;
this.count = 1;
}
/**
* Getter for the count.
*
* @return count
*/
public int getCount() {
return count;
}
/**
* Getter for the menu entry, updates the target to reflect the quantity if more than 1
* was found.
*
* @return Updated MenuEntry containing quantity
*/
public MenuEntry getEntry() {
if (count > 1) {
updateTarget();
}
return entry;
}
/**
* Updates the target of the menu entry to contain the quantity found.
*/
private void updateTarget() {
String target = entry.getTarget();
target = target + " [" + count + "]";
entry.setTarget(target);
}
/**
* Increment count when duplicate entries are found.
*/
public void incrementCount() {
count += 1;
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2018, Infinitay <https://github.com/Infinitay>
* Copyright (c) 2018, Shaun Dreclin <https://github.com/ShaunDreclin>
*
* 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.rememberclan;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("rememberclan")
public interface RememberClanConfig extends Config
{
@ConfigItem(
position = 1,
keyName = "clanname",
name = "Clan Name",
description = "Clanname to always remember"
)
default String clanname()
{
return "";
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018, Infinitay <https://github.com/Infinitay>
* Copyright (c) 2018, Shaun Dreclin <https://github.com/ShaunDreclin>
* 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.rememberclan;
import com.google.inject.Provides;
import javax.inject.Inject;
import net.runelite.api.*;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.vars.AccountType;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
@PluginDescriptor(
name = "!Remember Clan",
description = "Remember a specific clan!",
enabledByDefault = false
)
public class RememberClanPlugin extends Plugin
{
@Inject
private Client client;
@Inject
private RememberClanConfig config;
@Inject
private ChatMessageManager chatMessageManager;
private boolean loggingIn;
@Provides
RememberClanConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(RememberClanConfig.class);
}
@Subscribe
public void onGameTick(GameTick event)
{
client.setVar(VarClientStr.RECENT_CLAN_CHAT,config.clanname());
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2019, FlaxOnEm <flax.on.em@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.stronghold;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.runelite.api.widgets.Widget;
import java.util.HashMap;
import java.util.Map;
@Getter
@RequiredArgsConstructor
enum StrongholdAnswer {
PAIR_0("To pass you must answer me this: Hey adventurer!<br>You've been randomly selected for a prize of 1 year of<br>free membership! I'm just going to need some of your<br>account details so I can put it on your account!", "No way! I'm reporting you to Jagex!"),
PAIR_1("To pass you must answer me this: Can I leave my<br>account logged in while I'm out of the room?", "No."),
PAIR_2("To pass you must answer me this: How do I remove a<br>hijacker from my account?", "Use the Account Recovery System."),
PAIR_3("To pass you must answer me this: What do you do if<br>someone asks you for your password or bank PIN to<br>make you a player moderator?", "Don't give them the information and send an 'Abuse report'."),
PAIR_4("To pass you must answer me this: You're watching a<br>stream by someone claiming to be Jagex offering double<br>xp. What do you do?", "Report the stream as a scam. Real Jagex streams have a 'verified' mark."),
PAIR_5("To pass you must answer me this: My friend asks me<br>for my password so that he can do a difficult quest for<br>me. Do I give it to them?", "Don't give them my password."),
PAIR_6("To pass you must answer me this: Who can I give my<br>password to?", "Nobody."),
PAIR_7("To pass you must answer me this: How do I set up<br>two-factor authentication for my Old School RuneScape<br>account?", "Through account settings on oldschool.runescape.com."),
PAIR_8("To pass you must answer me this: What is an example<br>of a good bank PIN?", "The birthday of a famous person or event."),
PAIR_9("To pass you must answer me this: What should you do<br>if your real-life friend asks for your password so he<br>can check your stats?", "Don't give out your password to anyone. Not even close friends."),
PAIR_A("To pass you must answer me this: A player tells you to<br>search for a video online, click the link in the description<br>and comment on the forum post to win a cash prize.<br>What do you do?", "Report the player for phishing."),
PAIR_B("To pass you must answer me this: You have been<br>offered an opportunity to check out a free giveaway or<br>double XP signup via email or in game chat. What<br>should I do?", "Report the incident and do not click any links."),
PAIR_C("To pass you must answer me this: How do I set a<br>bank PIN?", "Talk to any banker."),
PAIR_D("To pass you must answer me this: What do I do if a<br>moderator asks me for my account details?", "Politely tell them no and then use the 'Report Abuse' button."),
PAIR_E("To pass you must answer me this: You are part way<br>through the Stronghold of Security when you have to<br>answer another question. After you answer the question,<br>you should...", "Read the text and follow the advice given."),
PAIR_F("To pass you must answer me this: Will Jagex prevent<br>me from saying my PIN in game?", "No."),
PAIR_G("that sound?", "No way! You'll just take my gold for your own! Reported!"),
PAIR_H("To pass you must answer me this: What should I do if<br>I receive an email asking me to verify my identity or<br>Account details due to suspicious activity?", "Don't click any links, forward the email to reportphishing@jagex.com."),
PAIR_I("To pass you must answer me this: A website claims that<br>they can make me a player moderator. What should I<br>do?", "Inform Jagex by emailing reportphishing@jagex.com."),
PAIR_J("react?", "Don't share your information and report the player."),
PAIR_K("To pass you must answer me this: What do you do if<br>someone asks you for your password or bank PIN to<br>make you a member for free?", "Don't tell them anything and click the 'Report Abuse' button."),
PAIR_L("To pass you must answer me this: Is it OK to buy an<br>Old School RuneScape account?", "No, you should never buy an account."),
PAIR_M("To pass you must answer me this: You have been<br>offered an opportunity to check out a free giveaway or<br>double XP signup via social media or stream. What<br>should I do?", "Report the incident and do not click any links."),
PAIR_N("To pass you must answer me this: Where is it safe to<br>use my Old School RuneScape password?", "Only on the Old School RuneScape website."),
PAIR_O("To pass you must answer me this: What is the best<br>way to secure your account?", "Authenticator and two-step login on my registered email."),
PAIR_P("To pass you must answer me this: Who is it ok to<br>share my account with?", "Nobody."),
PAIR_Q("To pass you must answer me this: What should you do<br>if another player messages you recommending a website<br>to purchase items and/or gold?", "Do not visit the website and report the player who messaged you."),
PAIR_R("To pass you must answer me this: Whose responsibility<br>is it to keep your account secure?", "Me."),
PAIR_S("To pass you must answer me this: Is it safe to pay<br>someone to level your account?", "No, you should never allow anyone to level your account."),
PAIR_T("To pass you must answer me this: What do I do if my<br>account is compromised?", "Secure my device and reset my password."),
PAIR_U("respond?", "Decline the offer and report that player."),
PAIR_V("To pass you must answer me this: A player says that<br>Jagex prevents you from saying your password<br>backwards in game. What do you do?", "Don't type in my password backwards and report the player."),
PAIR_W("To pass you must answer me this: What do I do if I<br>think I have a keylogger or virus?", "Virus scan my device then change my password."),
PAIR_X("To pass you must answer me this: What is the best<br>security step you can take to keep your registered<br>email secure?", "Set up 2 step authentication with my email provider.");
static final Map<String, String> MATCHES = new HashMap<>();
static {
for (StrongholdAnswer strongholdAnswer : StrongholdAnswer.values()) {
MATCHES.put(strongholdAnswer.question, strongholdAnswer.answer);
}
}
private final String question;
private final String answer;
static Widget findCorrect(final String question, final Widget[] widgets) {
final String s = MATCHES.get(question);
for (Widget widget: widgets) {
if (widget != null && widget.getText().equals(s))
return widget;
}
return null;
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2019, FlaxOnEm <flax.on.em@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.stronghold;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.ColorUtil;
import javax.inject.Inject;
import java.awt.Color;
@PluginDescriptor(
name = "!Stronghold",
description = "Highlights the correct answer to Stronghold of Security questions",
tags = {"stronghold", "security", "overlay", "answer", "highlight"}
)
@Slf4j
public class StrongholdPlugin extends Plugin {
private static final Color ANSWER_COLOR = new Color(230, 0, 230);
@Inject
private Client client;
private boolean queueNPCDialogue;
private boolean queueNPCOption;
private String questionCache;
@Subscribe
public void onWidgetLoaded(WidgetLoaded widgetLoaded) {
switch (widgetLoaded.getGroupId()) {
case WidgetID.DIALOG_NPC_GROUP_ID:
queueNPCDialogue = true;
break;
case WidgetID.DIALOG_OPTION_GROUP_ID:
queueNPCOption = true;
break;
}
}
@Subscribe
public void onClientTick(ClientTick t) {
if (queueNPCDialogue) {
queueNPCDialogue = false;
onNPCDialogue();
}
if (queueNPCOption) {
queueNPCOption = false;
onNPCOption();
}
}
private void onNPCDialogue() {
final Widget debugWidget = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT);
final String npcText = debugWidget.getText();
if (StrongholdAnswer.MATCHES.containsKey(npcText))
questionCache = npcText;
}
private void onNPCOption() {
if (questionCache == null)
return;
final Widget optionsWidget = client.getWidget(WidgetInfo.DIALOG_OPTION);
if (optionsWidget == null)
return;
final Widget[] widgets = optionsWidget.getParent().getChildren();
final Widget answerWidget = StrongholdAnswer.findCorrect(questionCache, widgets);
questionCache = null;
if (answerWidget == null)
return;
final String answerText = answerWidget.getText();
answerWidget.setText(ColorUtil.wrapWithColorTag(answerText, ANSWER_COLOR));
}
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* 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.warindicators;
import java.awt.Color;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("warIndicators")
public interface WarIndicatorConfig extends Config
{
@ConfigItem(
position = 0,
keyName = "highLightCallers",
name = "Highlight Callers",
description = "Highlight listed caller(s)"
)
default boolean highLightCallers()
{
return true;
}
@ConfigItem(
position = 1,
keyName = "callerColor",
name = "Caller(s) Color",
description = "Color to highlight caller's name"
)
default Color getCallerColor()
{
return new Color(36, 255, 237);
}
@ConfigItem(
position = 2,
keyName = "callerMinimap",
name = "Callers on Minimap",
description = "Show your caller(s) on the minimap"
)
default boolean callerMinimap()
{
return false;
}
@ConfigItem(
position = 3,
keyName = "callerTile",
name = "Show Caller's Tile",
description = "Show the tile your target is standing on"
)
default boolean callerTile()
{
return false;
}
@ConfigItem(
position = 4,
keyName = "activeCallers",
name = "Callers",
description = "Adds a user to your caller list. Format: (caller), (caller)"
)
default String getActiveCallers()
{
return "";
}
@ConfigItem(
position = 5,
keyName = "activeCallers",
name = "",
description = ""
)
void setActiveCallers(String key);
@ConfigItem(
position = 6,
keyName = "highlightSnipes",
name = "Highlight Targets",
description = "Highlight listed target(s)"
)
default boolean highlightSnipes()
{
return true;
}
@ConfigItem(
position = 7,
keyName = "snipeColor",
name = "Target(s) Color",
description = "Color to highlight target name"
)
default Color getSnipeColor()
{
return new Color(255, 0, 0);
}
@ConfigItem(
position = 8,
keyName = "snipeMinimap",
name = "Targets on Minimap",
description = "Show your target on the minimap"
)
default boolean snipeMinimap()
{
return false;
}
@ConfigItem(
position = 9,
keyName = "snipeTile",
name = "Show Target's Tile",
description = "Show the tile your target is standing on"
)
default boolean snipeTile()
{
return false;
}
@ConfigItem(
position = 10,
keyName = "targetedSnipes",
name = "Targets",
description = "Adds a user to your snipe list. Format: (target), (target)"
)
default String getTargetedSnipes()
{
return "";
}
@ConfigItem(
position = 11,
keyName = "targetedSnipes",
name = "",
description = ""
)
void setTargetedSnipe(String key);
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* 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.warindicators;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Player;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
import org.apache.commons.lang3.ArrayUtils;
@Singleton
public class WarIndicatorMiniMapOverlay extends Overlay
{
private final WarIndicatorService warIndicatorService;
private final WarIndicatorConfig config;
@Inject
private WarIndicatorMiniMapOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService)
{
this.config = config;
this.warIndicatorService = warIndicatorService;
setLayer(OverlayLayer.ABOVE_WIDGETS);
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.HIGH);
}
@Override
public Dimension render(Graphics2D graphics)
{
warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
return null;
}
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
{
final String name = actor.getName().replace('\u00A0', ' ');
final net.runelite.api.Point minimapLocation = actor.getMinimapLocation();
String[] callers = config.getActiveCallers().split(", ");
String[] targets = config.getTargetedSnipes().split(", ");
if (config.callerMinimap() && ArrayUtils.contains(callers, actor.getName()))
{
if (minimapLocation != null)
{
OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color);
}
}
if (config.snipeMinimap() && ArrayUtils.contains(targets, actor.getName()))
{
if (minimapLocation != null)
{
OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color);
}
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* 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.warindicators;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang3.ArrayUtils;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
@Singleton
public class WarIndicatorOverlay extends Overlay
{
private final WarIndicatorService warIndicatorService;
private final WarIndicatorConfig config;
@Inject
private WarIndicatorOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService)
{
this.config = config;
this.warIndicatorService = warIndicatorService;
setLayer(OverlayLayer.ABOVE_SCENE);
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.HIGH);
}
@Override
public Dimension render(Graphics2D graphics)
{
warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
return null;
}
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
{
if (!config.highlightSnipes() && !config.highLightCallers())
{
return;
}
Polygon poly = actor.getCanvasTilePoly();
String[] callers = config.getActiveCallers().split(", ");
String[] targets = config.getTargetedSnipes().split(", ");
if (config.callerTile() && ArrayUtils.contains(callers, actor.getName()))
{
if (poly != null)
{
OverlayUtil.renderPolygon(graphics, poly, color);
}
}
if (config.snipeTile() && ArrayUtils.contains(targets, actor.getName()))
{
if (poly != null)
{
OverlayUtil.renderPolygon(graphics, poly, color);
}
}
String name = actor.getName().replace('\u00A0', ' ');
int offset = actor.getLogicalHeight() + 40;
Point textLocation = actor.getCanvasTextLocation(graphics, name, offset);
if (textLocation != null)
{
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
}
}
}

View File

@@ -0,0 +1,170 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* 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.warindicators;
import com.google.common.collect.Sets;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides;
import java.awt.Color;
import java.util.Collection;
import javax.inject.Inject;
import org.apache.commons.lang3.ArrayUtils;
import net.runelite.api.Client;
import static net.runelite.api.MenuAction.FOLLOW;
import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER;
import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION;
import static net.runelite.api.MenuAction.PLAYER_FOURTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_SECOND_OPTION;
import static net.runelite.api.MenuAction.PLAYER_SEVENTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_SIXTH_OPTION;
import static net.runelite.api.MenuAction.PLAYER_THIRD_OPTION;
import static net.runelite.api.MenuAction.SPELL_CAST_ON_PLAYER;
import static net.runelite.api.MenuAction.TRADE;
import net.runelite.api.MenuEntry;
import net.runelite.api.Player;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor(
name = "<font color=\"aqua\">!War</font>",
description = "War War War.",
tags = {"skill", "total", "max", "PVP"},
enabledByDefault = false
)
public class WarIndicatorPlugin extends Plugin
{
@Inject
private OverlayManager overlayManager;
@Inject
private WarIndicatorConfig config;
@Inject
private WarIndicatorOverlay warIndicatorOverlay;
@Inject
private WarIndicatorMiniMapOverlay warIndicatorMiniMapOverlay;
@Inject
private Client client;
@Provides
WarIndicatorConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(WarIndicatorConfig.class);
}
@Override
protected void startUp() throws Exception
{
overlayManager.add(warIndicatorOverlay);
overlayManager.add(warIndicatorMiniMapOverlay);
}
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(warIndicatorOverlay);
overlayManager.remove(warIndicatorMiniMapOverlay);
}
@Subscribe
public void onMenuEntryAdd(MenuEntryAdded menuEntryAdded)
{
int type = menuEntryAdded.getType();
if (type >= 2000)
{
type -= 2000;
}
int identifier = menuEntryAdded.getIdentifier();
if (type == FOLLOW.getId() || type == TRADE.getId()
|| type == SPELL_CAST_ON_PLAYER.getId()
|| type == ITEM_USE_ON_PLAYER.getId()
|| type == PLAYER_FIRST_OPTION.getId()
|| type == PLAYER_SECOND_OPTION.getId()
|| type == PLAYER_THIRD_OPTION.getId()
|| type == PLAYER_FOURTH_OPTION.getId()
|| type == PLAYER_FIFTH_OPTION.getId()
|| type == PLAYER_SIXTH_OPTION.getId()
|| type == PLAYER_SEVENTH_OPTION.getId()
|| type == PLAYER_EIGTH_OPTION.getId())
{
Player[] players = client.getCachedPlayers();
Player player = null;
String player2 = null;
String[] callers = config.getActiveCallers().split(", ");
String[] targets = config.getTargetedSnipes().split(", ");
if (identifier >= 0 && identifier < players.length)
{
player = players[identifier];
player2 = players[identifier].getName();
}
if (player == null)
{
return;
}
Color color = null;
if (config.highLightCallers() && ArrayUtils.contains(callers, player2))
{
color = config.getCallerColor();
}
if (config.highlightSnipes() && ArrayUtils.contains(targets, player2))
{
color = config.getSnipeColor();
}
if (color != null)
{
MenuEntry[] menuEntries = client.getMenuEntries();
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
String target = lastEntry.getTarget();
int idx = target.indexOf('>');
if (idx != -1)
{
target = target.substring(idx + 1);
}
lastEntry.setTarget("<col=" + Integer.toHexString(color.getRGB() & 0xFFFFFF) + ">" + target);
client.setMenuEntries(menuEntries);
}
}
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2018, Andrew EP | ElPinche256 <https://github.com/ElPinche256>
* 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.warindicators;
import net.runelite.api.Client;
import net.runelite.api.Player;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.awt.*;
import java.util.function.BiConsumer;
@Singleton
public class WarIndicatorService
{
private final Client client;
private final WarIndicatorConfig config;
@Inject
private WarIndicatorService(Client client, WarIndicatorConfig config)
{
this.config = config;
this.client = client;
}
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
{
if (!config.highlightSnipes() && !config.highLightCallers())
{
return;
}
if (config.highlightSnipes())
{
for (Player player : client.getPlayers())
{
if (player == null || player.getName() == null)
{
continue;
}
String[] targets = config.getTargetedSnipes().split(", ");
if (targets == null)
{
return;
}
for (int i = 0; i < targets.length; i++)
{
if (player.getName().equalsIgnoreCase(targets[i]))
{
consumer.accept(player, config.getSnipeColor());
}
}
}
}
if (config.highLightCallers())
{
for (Player player : client.getPlayers())
{
if (player == null || player.getName() == null)
{
continue;
}
String[] callers = config.getActiveCallers().split(", ");
if (callers == null)
{
return;
}
for (int i = 0; i < callers.length; i++)
{
if (player.getName().equalsIgnoreCase(callers[i]))
{
consumer.accept(player, config.getCallerColor());
}
}
}
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* 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.zoneIndicators;
import java.awt.Color;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("zoneIndicators")
public interface ZoneIndicatorsConfig extends Config
{
@ConfigItem(
keyName = "multicombatZoneVisibility",
name = "Multicombat zones",
description = "Determine where multicombat zones should be shown",
position = 1
)
default ZoneVisibility multicombatZoneVisibility()
{
return ZoneVisibility.SHOW_IN_PVP;
}
@ConfigItem(
keyName = "pvpSafeZones",
name = "PvP safe zones",
description = "Show safe zones in PvP worlds",
position = 2
)
default boolean showPvpSafeZones()
{
return true;
}
@ConfigItem(
keyName = "deadmanSafeZones",
name = "Deadman safe zones",
description = "Show safe zones in Deadman worlds",
position = 3
)
default boolean showDeadmanSafeZones()
{
return true;
}
@ConfigItem(
keyName = "collisionDetection",
name = "Collision detection",
description = "Only show lines where they can be walked through",
position = 4
)
default boolean collisionDetection()
{
return false;
}
@ConfigItem(
keyName = "showMinimapLines",
name = "Show on minimap",
description = "Show multicombat and safe zones on the minimap",
position = 5
)
default boolean showMinimapLines()
{
return true;
}
@ConfigItem(
keyName = "multicombatColor",
name = "Multicombat zone color",
description = "Choose color to use for marking multicombat zones",
position = 6
)
default Color multicombatColor()
{
return Color.MAGENTA;
}
@ConfigItem(
keyName = "safeZoneColor",
name = "Safe zone color",
description = "Choose color to use for marking safe zones in PvP/Deadman",
position = 7
)
default Color safeZoneColor()
{
return Color.GREEN;
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* 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.zoneIndicators;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.geometry.Geometry;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
public class ZoneIndicatorsMinimapOverlay extends Overlay
{
private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE;
@Inject
private Client client;
@Inject
private ZoneIndicatorsPlugin plugin;
@Inject
private ZoneIndicatorsConfig config;
@Inject
public ZoneIndicatorsMinimapOverlay()
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ALWAYS_ON_TOP);
setPriority(OverlayPriority.LOW);
}
private Color getTransparentColorVersion(Color c)
{
return new Color(c.getRed(), c.getGreen(), c.getBlue(), 192);
}
private void renderPath(Graphics2D graphics, GeneralPath path, Color color)
{
LocalPoint playerLp = client.getLocalPlayer().getLocalLocation();
Rectangle viewArea = new Rectangle(
playerLp.getX() - MAX_LOCAL_DRAW_LENGTH,
playerLp.getY() - MAX_LOCAL_DRAW_LENGTH,
MAX_LOCAL_DRAW_LENGTH * 2,
MAX_LOCAL_DRAW_LENGTH * 2);
graphics.setColor(color);
path = Geometry.clipPath(path, viewArea);
path = Geometry.filterPath(path, (p1, p2) ->
Perspective.localToMinimap(client, new LocalPoint((int)p1[0], (int)p1[1])) != null &&
Perspective.localToMinimap(client, new LocalPoint((int)p2[0], (int)p2[1])) != null);
path = Geometry.transformPath(path, coords ->
{
Point point = Perspective.localToMinimap(client, new LocalPoint((int)coords[0], (int)coords[1]));
coords[0] = point.getX();
coords[1] = point.getY();
});
graphics.draw(path);
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!config.showMinimapLines())
{
return null;
}
GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()];
GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()];
if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null)
{
renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor()));
}
if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null)
{
renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor()));
}
return null;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* 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.zoneIndicators;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.geometry.Geometry;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
public class ZoneIndicatorsOverlay extends Overlay
{
private final static int MAX_LOCAL_DRAW_LENGTH = 20 * Perspective.LOCAL_TILE_SIZE;
@Inject
private Client client;
@Inject
private ZoneIndicatorsPlugin plugin;
@Inject
private ZoneIndicatorsConfig config;
@Inject
public ZoneIndicatorsOverlay()
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_SCENE);
setPriority(OverlayPriority.LOW);
}
private Color getTransparentColorVersion(Color c)
{
return new Color(c.getRed(), c.getGreen(), c.getBlue(), 92);
}
private void renderPath(Graphics2D graphics, GeneralPath path, Color color)
{
LocalPoint playerLp = client.getLocalPlayer().getLocalLocation();
Rectangle viewArea = new Rectangle(
playerLp.getX() - MAX_LOCAL_DRAW_LENGTH,
playerLp.getY() - MAX_LOCAL_DRAW_LENGTH,
MAX_LOCAL_DRAW_LENGTH * 2,
MAX_LOCAL_DRAW_LENGTH * 2);
graphics.setColor(color);
graphics.setStroke(new BasicStroke(2));
path = Geometry.clipPath(path, viewArea);
path = Geometry.filterPath(path, (p1, p2) ->
Perspective.localToCanvas(client, new LocalPoint((int)p1[0], (int)p1[1]), client.getPlane()) != null &&
Perspective.localToCanvas(client, new LocalPoint((int)p2[0], (int)p2[1]), client.getPlane()) != null);
path = Geometry.transformPath(path, coords ->
{
Point point = Perspective.localToCanvas(client, new LocalPoint((int)coords[0], (int)coords[1]), client.getPlane());
coords[0] = point.getX();
coords[1] = point.getY();
});
graphics.draw(path);
}
@Override
public Dimension render(Graphics2D graphics)
{
GeneralPath multicombatPath = plugin.getMulticombatPathToDisplay()[client.getPlane()];
GeneralPath pvpPath = plugin.getPvpPathToDisplay()[client.getPlane()];
if (config.multicombatZoneVisibility() != ZoneVisibility.HIDE && multicombatPath != null)
{
renderPath(graphics, multicombatPath, getTransparentColorVersion(config.multicombatColor()));
}
if ((config.showPvpSafeZones() || config.showDeadmanSafeZones()) && pvpPath != null)
{
renderPath(graphics, pvpPath, getTransparentColorVersion(config.safeZoneColor()));
}
return null;
}
}

View File

@@ -0,0 +1,297 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* 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.zoneIndicators;
import net.runelite.client.eventbus.Subscribe;
import com.google.inject.Provides;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
import java.util.Arrays;
import javax.inject.Inject;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.GameState;
import net.runelite.api.ObjectComposition;
import net.runelite.api.Perspective;
import net.runelite.api.Tile;
import net.runelite.api.WallObject;
import net.runelite.api.WorldType;
import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldArea;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.geometry.Geometry;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.OverlayManager;
@PluginDescriptor(
name = "<font color=\"aqua\">!MultiLines</font>",
description = "Show borders of multicombat and PvP safezones",
tags = {"multicombat", "lines", "pvp", "deadman", "safezones", "bogla"},
enabledByDefault = false
)
public class ZoneIndicatorsPlugin extends Plugin
{
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private ZoneIndicatorsConfig config;
@Inject
private ZoneIndicatorsOverlay overlay;
@Inject
private ZoneIndicatorsMinimapOverlay minimapOverlay;
@Inject
private OverlayManager overlayManager;
@Getter
private GeneralPath[] multicombatPathToDisplay;
@Getter
private GeneralPath[] pvpPathToDisplay;
@Getter
private boolean inPvp;
@Getter
private boolean inDeadman;
private int currentPlane;
@Provides
ZoneIndicatorsConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(ZoneIndicatorsConfig.class);
}
@Override
protected void startUp() throws Exception
{
overlayManager.add(overlay);
overlayManager.add(minimapOverlay);
multicombatPathToDisplay = new GeneralPath[Constants.MAX_Z];
pvpPathToDisplay = new GeneralPath[Constants.MAX_Z];
clientThread.invokeLater(() ->
{
if (client.getGameState() == GameState.LOGGED_IN)
{
findLinesInScene();
}
});
}
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(overlay);
overlayManager.remove(minimapOverlay);
multicombatPathToDisplay = null;
pvpPathToDisplay = null;
}
private void transformWorldToLocal(float[] coords)
{
LocalPoint lp = LocalPoint.fromWorld(client, (int)coords[0], (int)coords[1]);
coords[0] = lp.getX() - Perspective.LOCAL_TILE_SIZE / 2;
coords[1] = lp.getY() - Perspective.LOCAL_TILE_SIZE / 2;
}
private boolean isOpenableAt(WorldPoint wp)
{
int sceneX = wp.getX() - client.getBaseX();
int sceneY = wp.getY() - client.getBaseY();
Tile tile = client.getScene().getTiles()[wp.getPlane()][sceneX][sceneY];
if (tile == null)
{
return false;
}
WallObject wallObject = tile.getWallObject();
if (wallObject == null)
{
return false;
}
ObjectComposition objectComposition = client.getObjectDefinition(wallObject.getId());
if (objectComposition == null)
{
return false;
}
String[] actions = objectComposition.getActions();
if (actions == null)
{
return false;
}
return Arrays.stream(actions).anyMatch(x -> x != null && x.toLowerCase().equals("open"));
}
private boolean collisionFilter(float[] p1, float[] p2)
{
int x1 = (int)p1[0];
int y1 = (int)p1[1];
int x2 = (int)p2[0];
int y2 = (int)p2[1];
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
if (y1 > y2)
{
int temp = y1;
y1 = y2;
y2 = temp;
}
int dx = x2 - x1;
int dy = y2 - y1;
WorldArea wa1 = new WorldArea(new WorldPoint(
x1, y1, currentPlane), 1, 1);
WorldArea wa2 = new WorldArea(new WorldPoint(
x1 - dy, y1 - dx, currentPlane), 1, 1);
if (isOpenableAt(wa1.toWorldPoint()) || isOpenableAt(wa2.toWorldPoint()))
{
// When there's something with the open option (e.g. a door) on the tile,
// we assume it can be opened and walked through afterwards. Without this
// check, the line for that tile wouldn't render with collision detection
// because the collision check isn't done if collision data changes.
return true;
}
boolean b1 = wa1.canTravelInDirection(client, -dy, -dx);
boolean b2 = wa2.canTravelInDirection(client, dy, dx);
return b1 && b2;
}
private void findLinesInScene()
{
inDeadman = client.getWorldType().stream().anyMatch(x ->
x == WorldType.DEADMAN || x == WorldType.SEASONAL_DEADMAN);
inPvp = client.getWorldType().stream().anyMatch(x ->
x == WorldType.PVP || x == WorldType.PVP_HIGH_RISK);
Rectangle sceneRect = new Rectangle(
client.getBaseX() + 1, client.getBaseY() + 1,
Constants.SCENE_SIZE - 2, Constants.SCENE_SIZE - 2);
// Generate lines for multicombat zones
if (config.multicombatZoneVisibility() == ZoneVisibility.HIDE)
{
for (int i = 0; i < multicombatPathToDisplay.length; i++)
{
multicombatPathToDisplay[i] = null;
}
}
else
{
for (int i = 0; i < multicombatPathToDisplay.length; i++)
{
currentPlane = i;
GeneralPath lines = new GeneralPath(MapLocations.getMulticombat(sceneRect, i));
lines = Geometry.clipPath(lines, sceneRect);
if (config.multicombatZoneVisibility() == ZoneVisibility.SHOW_IN_PVP &&
!isInDeadman() && !isInPvp())
{
lines = Geometry.clipPath(lines, MapLocations.getRoughWilderness(i));
}
lines = Geometry.splitIntoSegments(lines, 1);
if (config.collisionDetection())
{
lines = Geometry.filterPath(lines, this::collisionFilter);
}
lines = Geometry.transformPath(lines, this::transformWorldToLocal);
multicombatPathToDisplay[i] = lines;
}
}
// Generate safezone lines for deadman/pvp worlds
for (int i = 0; i < pvpPathToDisplay.length; i++)
{
currentPlane = i;
GeneralPath safeZonePath = null;
if (config.showDeadmanSafeZones() && isInDeadman())
{
safeZonePath = new GeneralPath(MapLocations.getDeadmanSafeZones(sceneRect, i));
}
else if (config.showPvpSafeZones() && isInPvp())
{
safeZonePath = new GeneralPath(MapLocations.getPvpSafeZones(sceneRect, i));
}
if (safeZonePath != null)
{
safeZonePath = Geometry.clipPath(safeZonePath, sceneRect);
safeZonePath = Geometry.splitIntoSegments(safeZonePath, 1);
if (config.collisionDetection())
{
safeZonePath = Geometry.filterPath(safeZonePath, this::collisionFilter);
}
safeZonePath = Geometry.transformPath(safeZonePath, this::transformWorldToLocal);
}
pvpPathToDisplay[i] = safeZonePath;
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getKey().equals("collisionDetection") ||
event.getKey().equals("multicombatZoneVisibility") ||
event.getKey().equals("deadmanSafeZones") ||
event.getKey().equals("pvpSafeZones"))
{
findLinesInScene();
}
}
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
if (event.getGameState() == GameState.LOGGED_IN)
{
findLinesInScene();
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
* 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.zoneIndicators;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum ZoneVisibility
{
HIDE("Hide"),
SHOW_IN_PVP("Show in PvP"),
SHOW_EVERYWHERE("Show everywhere");
private final String visibility;
@Override
public String toString()
{
return visibility;
}
}