client: Remove all plugins
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* 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.account;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.account.AccountSession;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.SessionOpen;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Account",
|
||||
description = "Sync RuneLite config settings with your Google account",
|
||||
tags = {"external", "google", "integration"},
|
||||
loadWhenOutdated = true,
|
||||
hidden = true
|
||||
)
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class AccountPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Subscribe
|
||||
private void onSessionOpen(SessionOpen sessionOpen)
|
||||
{
|
||||
AccountSession session = sessionManager.getAccountSession();
|
||||
|
||||
if (session.getUsername() == null)
|
||||
{
|
||||
return; // No username yet
|
||||
}
|
||||
|
||||
log.debug("Session opened as {}", session.getUsername());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.achievementdiary;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class CombatLevelRequirement implements Requirement
|
||||
{
|
||||
private final int level;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return level + " " + "Combat";
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class DiaryRequirement
|
||||
{
|
||||
private final String task;
|
||||
private final List<Requirement> requirements;
|
||||
|
||||
DiaryRequirement(String task, Requirement[] requirements)
|
||||
{
|
||||
this.task = task;
|
||||
this.requirements = ImmutableList.copyOf(requirements);
|
||||
}
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.FontTypeFace;
|
||||
import net.runelite.api.QuestState;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.ArdougneDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.DesertDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.FaladorDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.FremennikDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.KandarinDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.KaramjaDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.KourendDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.LumbridgeDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.MorytaniaDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.VarrockDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.WesternDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.diaries.WildernessDiaryRequirement;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "Diary Requirements",
|
||||
description = "Display level requirements in Achievement Diary interface",
|
||||
tags = {"achievements", "tasks"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
@Singleton
|
||||
public class DiaryRequirementsPlugin extends Plugin
|
||||
{
|
||||
private static final String AND_JOINER = ", ";
|
||||
private static final Pattern AND_JOINER_PATTERN = Pattern.compile("(?<=, )");
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(final WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() == WidgetID.DIARY_QUEST_GROUP_ID)
|
||||
{
|
||||
String widgetTitle = Text.removeTags(
|
||||
client.getWidget(
|
||||
WidgetInfo.DIARY_QUEST_WIDGET_TITLE)
|
||||
.getText())
|
||||
.replace(' ', '_')
|
||||
.toUpperCase();
|
||||
if (widgetTitle.startsWith("ACHIEVEMENT_DIARY"))
|
||||
{
|
||||
showDiaryRequirements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showDiaryRequirements()
|
||||
{
|
||||
Widget widget = client.getWidget(WidgetInfo.DIARY_QUEST_WIDGET_TEXT);
|
||||
Widget[] children = widget.getStaticChildren();
|
||||
|
||||
Widget titleWidget = children[0];
|
||||
if (titleWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FontTypeFace font = titleWidget.getFont();
|
||||
int maxWidth = titleWidget.getWidth();
|
||||
|
||||
List<String> originalAchievements = getOriginalAchievements(children);
|
||||
|
||||
// new requirements starts out as a copy of the original
|
||||
List<String> newRequirements = new ArrayList<>(originalAchievements);
|
||||
|
||||
GenericDiaryRequirement requirements = getRequirementsForTitle(titleWidget.getText());
|
||||
if (requirements == null)
|
||||
{
|
||||
log.debug("Unknown achievement diary {}", titleWidget.getText());
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> skillRequirements = buildRequirements(requirements.getRequirements());
|
||||
|
||||
int offset = 0;
|
||||
String taskBuffer = "";
|
||||
for (int i = 0; i < originalAchievements.size(); i++)
|
||||
{
|
||||
String rowText = Text.removeTags(originalAchievements.get(i));
|
||||
if (skillRequirements.get(taskBuffer + " " + rowText) != null)
|
||||
{
|
||||
taskBuffer = taskBuffer + " " + rowText;
|
||||
}
|
||||
else
|
||||
{
|
||||
taskBuffer = rowText;
|
||||
}
|
||||
|
||||
if (skillRequirements.get(taskBuffer) != null)
|
||||
{
|
||||
String levelRequirement = skillRequirements.get(taskBuffer);
|
||||
String task = originalAchievements.get(i);
|
||||
|
||||
int taskWidth = font.getTextWidth(task);
|
||||
int ourWidth = font.getTextWidth(levelRequirement);
|
||||
String strike = task.startsWith("<str>") ? "<str>" : "";
|
||||
|
||||
if (ourWidth + taskWidth < maxWidth)
|
||||
{
|
||||
// Merge onto 1 line
|
||||
newRequirements.set(i + offset, task + levelRequirement);
|
||||
}
|
||||
else if (ourWidth < maxWidth)
|
||||
{
|
||||
// 2 line split
|
||||
newRequirements.add(i + (++offset), strike + levelRequirement);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full text layout
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(task);
|
||||
int runningWidth = font.getTextWidth(b.toString());
|
||||
for (String word : AND_JOINER_PATTERN.split(levelRequirement))
|
||||
{
|
||||
int wordWidth = font.getTextWidth(word);
|
||||
if (runningWidth == 0 || wordWidth + runningWidth < maxWidth)
|
||||
{
|
||||
runningWidth += wordWidth;
|
||||
b.append(word);
|
||||
}
|
||||
else
|
||||
{
|
||||
newRequirements.add(i + (offset++), b.toString());
|
||||
b.delete(0, b.length());
|
||||
runningWidth = wordWidth;
|
||||
b.append(strike);
|
||||
b.append(word);
|
||||
}
|
||||
}
|
||||
newRequirements.set(i + offset, b.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lastLine = 0;
|
||||
for (int i = 0; i < newRequirements.size() && i < children.length; i++)
|
||||
{
|
||||
Widget achievementWidget = children[i];
|
||||
String text = newRequirements.get(i);
|
||||
achievementWidget.setText(text);
|
||||
if (text != null && !text.isEmpty())
|
||||
{
|
||||
lastLine = i;
|
||||
}
|
||||
}
|
||||
|
||||
int numLines = lastLine;
|
||||
clientThread.invokeLater(() -> client.runScript(ScriptID.DIARY_QUEST_UPDATE_LINECOUNT, 1, numLines));
|
||||
}
|
||||
|
||||
private List<String> getOriginalAchievements(Widget[] children)
|
||||
{
|
||||
List<String> preloadedRequirements = new ArrayList<>(children.length);
|
||||
for (Widget requirementWidget : children)
|
||||
{
|
||||
preloadedRequirements.add(requirementWidget.getText());
|
||||
}
|
||||
return preloadedRequirements;
|
||||
}
|
||||
|
||||
private GenericDiaryRequirement getRequirementsForTitle(String title)
|
||||
{
|
||||
String diaryName = Text.removeTags(title
|
||||
.replaceAll(" ", "_")
|
||||
.toUpperCase());
|
||||
|
||||
GenericDiaryRequirement diaryRequirementContainer;
|
||||
switch (diaryName)
|
||||
{
|
||||
case "ARDOUGNE_AREA_TASKS":
|
||||
diaryRequirementContainer = new ArdougneDiaryRequirement();
|
||||
break;
|
||||
case "DESERT_TASKS":
|
||||
diaryRequirementContainer = new DesertDiaryRequirement();
|
||||
break;
|
||||
case "FALADOR_AREA_TASKS":
|
||||
diaryRequirementContainer = new FaladorDiaryRequirement();
|
||||
break;
|
||||
case "FREMENNIK_TASKS":
|
||||
diaryRequirementContainer = new FremennikDiaryRequirement();
|
||||
break;
|
||||
case "KANDARIN_TASKS":
|
||||
diaryRequirementContainer = new KandarinDiaryRequirement();
|
||||
break;
|
||||
case "KARAMJA_AREA_TASKS":
|
||||
diaryRequirementContainer = new KaramjaDiaryRequirement();
|
||||
break;
|
||||
case "KOUREND_&_KEBOS_TASKS":
|
||||
diaryRequirementContainer = new KourendDiaryRequirement();
|
||||
break;
|
||||
case "LUMBRIDGE_&_DRAYNOR_TASKS":
|
||||
diaryRequirementContainer = new LumbridgeDiaryRequirement();
|
||||
break;
|
||||
case "MORYTANIA_TASKS":
|
||||
diaryRequirementContainer = new MorytaniaDiaryRequirement();
|
||||
break;
|
||||
case "VARROCK_TASKS":
|
||||
diaryRequirementContainer = new VarrockDiaryRequirement();
|
||||
break;
|
||||
case "WESTERN_AREA_TASKS":
|
||||
diaryRequirementContainer = new WesternDiaryRequirement();
|
||||
break;
|
||||
case "WILDERNESS_AREA_TASKS":
|
||||
diaryRequirementContainer = new WildernessDiaryRequirement();
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return diaryRequirementContainer;
|
||||
}
|
||||
|
||||
// returns a map of task -> level requirements
|
||||
private Map<String, String> buildRequirements(Collection<DiaryRequirement> requirements)
|
||||
{
|
||||
Map<String, String> reqs = new HashMap<>();
|
||||
for (DiaryRequirement req : requirements)
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("<col=ffffff>(");
|
||||
|
||||
assert !req.getRequirements().isEmpty();
|
||||
for (Requirement ireq : req.getRequirements())
|
||||
{
|
||||
boolean satifisfied = satisfiesRequirement(ireq);
|
||||
b.append(satifisfied ? "<col=000080><str>" : "<col=800000>");
|
||||
b.append(ireq.toString());
|
||||
b.append(satifisfied ? "</str>" : "<col=000080>");
|
||||
b.append(AND_JOINER);
|
||||
}
|
||||
|
||||
b.delete(b.length() - AND_JOINER.length(), b.length());
|
||||
|
||||
b.append("<col=ffffff>)");
|
||||
|
||||
reqs.put(req.getTask(), b.toString());
|
||||
}
|
||||
return reqs;
|
||||
}
|
||||
|
||||
private boolean satisfiesRequirement(Requirement r)
|
||||
{
|
||||
if (r instanceof OrRequirement)
|
||||
{
|
||||
return ((OrRequirement) r).getRequirements()
|
||||
.stream()
|
||||
.anyMatch(this::satisfiesRequirement);
|
||||
}
|
||||
if (r instanceof SkillRequirement)
|
||||
{
|
||||
SkillRequirement s = (SkillRequirement) r;
|
||||
return client.getRealSkillLevel(s.getSkill()) >= s.getLevel();
|
||||
}
|
||||
if (r instanceof CombatLevelRequirement)
|
||||
{
|
||||
return client.getLocalPlayer().getCombatLevel() >= ((CombatLevelRequirement) r).getLevel();
|
||||
}
|
||||
if (r instanceof QuestRequirement)
|
||||
{
|
||||
QuestRequirement q = (QuestRequirement) r;
|
||||
QuestState state = q.getQuest().getState(client);
|
||||
if (q.isStarted())
|
||||
{
|
||||
return state != QuestState.NOT_STARTED;
|
||||
}
|
||||
return state == QuestState.FINISHED;
|
||||
}
|
||||
if (r instanceof QuestPointRequirement)
|
||||
{
|
||||
return client.getVar(VarPlayer.QUEST_POINTS) >= ((QuestPointRequirement) r).getQp();
|
||||
}
|
||||
if (r instanceof FavourRequirement)
|
||||
{
|
||||
FavourRequirement f = (FavourRequirement) r;
|
||||
int realFavour = client.getVar(f.getHouse().getVarbit());
|
||||
return (realFavour / 10) >= f.getPercent();
|
||||
}
|
||||
log.warn("Unknown requirement {}", r);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 William <https://github.com/monsterxsync>
|
||||
* 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.achievementdiary;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Favour;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class FavourRequirement implements Requirement
|
||||
{
|
||||
private final Favour house;
|
||||
private final int percent;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return percent + "% " + house.getName() + " favour";
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
public abstract class GenericDiaryRequirement
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Set<DiaryRequirement> requirements = new HashSet<>();
|
||||
|
||||
protected void add(String task, Requirement... requirements)
|
||||
{
|
||||
DiaryRequirement diaryRequirement = new DiaryRequirement(task, requirements);
|
||||
this.requirements.add(diaryRequirement);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.achievementdiary;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
public class OrRequirement implements Requirement
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<Requirement> requirements;
|
||||
|
||||
public OrRequirement(Requirement... reqs)
|
||||
{
|
||||
this.requirements = ImmutableList.copyOf(reqs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Joiner.on(" or ").join(requirements);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.achievementdiary;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class QuestPointRequirement implements Requirement
|
||||
{
|
||||
private final int qp;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return qp + " " + "Quest points";
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.achievementdiary;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Quest;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
public class QuestRequirement implements Requirement
|
||||
{
|
||||
private final Quest quest;
|
||||
private final boolean started;
|
||||
|
||||
public QuestRequirement(Quest quest)
|
||||
{
|
||||
this(quest, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
return "Started " + quest.getName();
|
||||
}
|
||||
|
||||
return quest.getName();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.achievementdiary;
|
||||
|
||||
public interface Requirement {}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* 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.achievementdiary;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Skill;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class SkillRequirement implements Requirement
|
||||
{
|
||||
private final Skill skill;
|
||||
private final int level;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return level + " " + skill.getName();
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class ArdougneDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public ArdougneDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Have Wizard Cromperty teleport you to the Rune Essence mine.",
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Steal a cake from the Ardougne market stalls.",
|
||||
new SkillRequirement(Skill.THIEVING, 5));
|
||||
add("Enter the Combat Training Camp north of W. Ardougne.",
|
||||
new QuestRequirement(Quest.BIOHAZARD));
|
||||
add("Go out fishing on the Fishing Trawler.",
|
||||
new SkillRequirement(Skill.FISHING, 15));
|
||||
|
||||
// MEDIUM
|
||||
add("Enter the Unicorn pen in Ardougne zoo using Fairy rings.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Grapple over Yanille's south wall.",
|
||||
new SkillRequirement(Skill.AGILITY, 39),
|
||||
new SkillRequirement(Skill.STRENGTH, 38),
|
||||
new SkillRequirement(Skill.RANGED, 21));
|
||||
add("Harvest some strawberries from the Ardougne farming patch.",
|
||||
new SkillRequirement(Skill.FARMING, 31));
|
||||
add("Cast the Ardougne Teleport spell.",
|
||||
new SkillRequirement(Skill.MAGIC, 51),
|
||||
new QuestRequirement(Quest.PLAGUE_CITY));
|
||||
add("Travel to Castlewars by Hot Air Balloon.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 50),
|
||||
new QuestRequirement(Quest.ENLIGHTENED_JOURNEY));
|
||||
add("Claim buckets of sand from Bert in Yanille.",
|
||||
new SkillRequirement(Skill.CRAFTING, 49),
|
||||
new QuestRequirement(Quest.THE_HAND_IN_THE_SAND));
|
||||
add("Catch any fish on the Fishing Platform.",
|
||||
new QuestRequirement(Quest.SEA_SLUG, true));
|
||||
add("Pickpocket the master farmer north of Ardougne.",
|
||||
new SkillRequirement(Skill.THIEVING, 38));
|
||||
add("Collect some Nightshade from the Skavid Caves.",
|
||||
new QuestRequirement(Quest.WATCHTOWER, true));
|
||||
add("Kill a swordchick in the Tower of Life.",
|
||||
new QuestRequirement(Quest.TOWER_OF_LIFE));
|
||||
add("Equip Iban's upgraded staff or upgrade an Iban staff.",
|
||||
new SkillRequirement(Skill.MAGIC, 50),
|
||||
new SkillRequirement(Skill.ATTACK, 50),
|
||||
new QuestRequirement(Quest.UNDERGROUND_PASS));
|
||||
add("Visit the Island East of the Necromancer's tower.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
|
||||
// HARD
|
||||
// When the task is completed "the Totem" changes to "Totem" - so we add
|
||||
// both variations.
|
||||
add("Recharge some Jewellery at the Totem in the Legends Guild.",
|
||||
new QuestRequirement(Quest.LEGENDS_QUEST));
|
||||
add("Recharge some Jewellery at Totem in the Legends Guild.",
|
||||
new QuestRequirement(Quest.LEGENDS_QUEST));
|
||||
add("Enter the Magic Guild.",
|
||||
new SkillRequirement(Skill.MAGIC, 66));
|
||||
add("Attempt to steal from King Lathas' chest.",
|
||||
new SkillRequirement(Skill.THIEVING, 72));
|
||||
add("Have a zookeeper put you in Ardougne Zoo's monkey cage.",
|
||||
new QuestRequirement(Quest.MONKEY_MADNESS_I, true));
|
||||
add("Teleport to the Watchtower.",
|
||||
new SkillRequirement(Skill.MAGIC, 58),
|
||||
new QuestRequirement(Quest.WATCHTOWER));
|
||||
add("Catch a Red Salamander.",
|
||||
new SkillRequirement(Skill.HUNTER, 59));
|
||||
add("Check the health of a Palm tree near tree gnome village.",
|
||||
new SkillRequirement(Skill.FARMING, 68));
|
||||
add("Pick some Poison Ivy berries from the patch south of Ardougne.",
|
||||
new SkillRequirement(Skill.FARMING, 70));
|
||||
add("Smith a Mithril platebody near Ardougne.",
|
||||
new SkillRequirement(Skill.SMITHING, 68));
|
||||
add("Enter your POH from Yanille.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 50));
|
||||
add("Smith a Dragon sq shield in West Ardougne.",
|
||||
new SkillRequirement(Skill.SMITHING, 60),
|
||||
new QuestRequirement(Quest.LEGENDS_QUEST));
|
||||
add("Craft some Death runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 65),
|
||||
new QuestRequirement(Quest.MOURNINGS_END_PART_II));
|
||||
|
||||
// ELITE
|
||||
add("Catch a Manta ray in the Fishing Trawler and cook it in Port Khazard.",
|
||||
new SkillRequirement(Skill.FISHING, 81),
|
||||
new SkillRequirement(Skill.COOKING, 91)
|
||||
);
|
||||
add("Attempt to picklock the door to the basement of Yanille Agility Dungeon.",
|
||||
new SkillRequirement(Skill.THIEVING, 82));
|
||||
add("Pickpocket a Hero.",
|
||||
new SkillRequirement(Skill.THIEVING, 80));
|
||||
add("Make a rune crossbow yourself from scratch within Witchaven or Yanille.",
|
||||
new SkillRequirement(Skill.CRAFTING, 10),
|
||||
new SkillRequirement(Skill.SMITHING, 91),
|
||||
new SkillRequirement(Skill.FLETCHING, 69));
|
||||
add("Imbue a salve amulet at Nightmare Zone or equip an imbued salve amulet.",
|
||||
new QuestRequirement(Quest.HAUNTED_MINE));
|
||||
add("Pick some Torstol from the patch north of Ardougne.",
|
||||
new SkillRequirement(Skill.FARMING, 85));
|
||||
add("Complete a lap of Ardougne's rooftop agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 90));
|
||||
add("Cast Ice Barrage on another player within Castlewars.",
|
||||
new SkillRequirement(Skill.MAGIC, 94),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE));
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class DesertDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public DesertDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Catch a Golden Warbler.",
|
||||
new SkillRequirement(Skill.HUNTER, 5));
|
||||
add("Mine 5 clay in the north-eastern desert.",
|
||||
new SkillRequirement(Skill.MINING, 5));
|
||||
add("Open the Sarcophagus in the first room of Pyramid Plunder.",
|
||||
new SkillRequirement(Skill.THIEVING, 21),
|
||||
new QuestRequirement(Quest.ICTHLARINS_LITTLE_HELPER, true));
|
||||
|
||||
// MEDIUM
|
||||
add("Climb to the summit of the Agility Pyramid.",
|
||||
new SkillRequirement(Skill.AGILITY, 30));
|
||||
add("Slay a desert lizard.",
|
||||
new SkillRequirement(Skill.SLAYER, 22));
|
||||
add("Catch an Orange Salamander.",
|
||||
new SkillRequirement(Skill.HUNTER, 47));
|
||||
add("Steal a feather from the Desert Phoenix.",
|
||||
new SkillRequirement(Skill.THIEVING, 25));
|
||||
add("Travel to Uzer via Magic Carpet.",
|
||||
new QuestRequirement(Quest.THE_GOLEM));
|
||||
add("Travel to the Desert via Eagle.",
|
||||
new QuestRequirement(Quest.EAGLES_PEAK));
|
||||
add("Pray at the Elidinis statuette in Nardah.",
|
||||
new QuestRequirement(Quest.SPIRITS_OF_THE_ELID));
|
||||
add("Create a combat potion in the desert.",
|
||||
new SkillRequirement(Skill.HERBLORE, 36));
|
||||
add("Teleport to Enakhra's Temple with the Camulet.",
|
||||
new QuestRequirement(Quest.ENAKHRAS_LAMENT));
|
||||
add("Visit the Genie.",
|
||||
new QuestRequirement(Quest.SPIRITS_OF_THE_ELID));
|
||||
add("Teleport to Pollnivneach with a redirected teleport to house tablet.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 20));
|
||||
add("Chop some Teak logs near Uzer.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 35));
|
||||
|
||||
// HARD
|
||||
add("Knock out and pickpocket a Menaphite Thug.",
|
||||
new SkillRequirement(Skill.THIEVING, 65),
|
||||
new QuestRequirement(Quest.THE_FEUD));
|
||||
add("Mine some Granite.",
|
||||
new SkillRequirement(Skill.MINING, 45));
|
||||
add("Refill your waterskins in the Desert using Lunar magic.",
|
||||
new SkillRequirement(Skill.MAGIC, 68),
|
||||
new QuestRequirement(Quest.DREAM_MENTOR));
|
||||
add("Complete a lap of the Pollnivneach agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 70));
|
||||
add("Slay a Dust Devil with a Slayer helmet equipped.",
|
||||
new SkillRequirement(Skill.SLAYER, 65),
|
||||
new SkillRequirement(Skill.DEFENCE, 10),
|
||||
new SkillRequirement(Skill.CRAFTING, 55),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE, true));
|
||||
add("Activate Ancient Magicks at the altar in the Jaldraocht Pyramid.",
|
||||
new QuestRequirement(Quest.DESERT_TREASURE));
|
||||
add("Defeat a Locust Rider with Keris.",
|
||||
new SkillRequirement(Skill.ATTACK, 50),
|
||||
new QuestRequirement(Quest.CONTACT));
|
||||
add("Burn some yew logs on the Nardah Mayor's balcony.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 60));
|
||||
add("Create a Mithril Platebody in Nardah.",
|
||||
new SkillRequirement(Skill.SMITHING, 68));
|
||||
|
||||
// ELITE
|
||||
add("Bake a wild pie at the Nardah Clay Oven.",
|
||||
new SkillRequirement(Skill.COOKING, 85));
|
||||
add("Cast Ice Barrage against a foe in the Desert.",
|
||||
new SkillRequirement(Skill.MAGIC, 94),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE));
|
||||
add("Fletch some Dragon darts at the Bedabin Camp.",
|
||||
new SkillRequirement(Skill.FLETCHING, 95),
|
||||
new QuestRequirement(Quest.THE_TOURIST_TRAP));
|
||||
add("Speak to the KQ head in your POH.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 78),
|
||||
new QuestRequirement(Quest.PRIEST_IN_PERIL));
|
||||
add("Steal from the Grand Gold Chest in the final room of Pyramid Plunder.",
|
||||
new SkillRequirement(Skill.THIEVING, 91),
|
||||
new QuestRequirement(Quest.ICTHLARINS_LITTLE_HELPER, true));
|
||||
add("Restore at least 85 Prayer points when praying at the Altar in Sophanem.",
|
||||
new SkillRequirement(Skill.PRAYER, 85),
|
||||
new QuestRequirement(Quest.ICTHLARINS_LITTLE_HELPER, true));
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class FaladorDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public FaladorDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Find out what your family crest is from Sir Renitee.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 16));
|
||||
add("Climb over the western Falador wall.",
|
||||
new SkillRequirement(Skill.AGILITY, 5));
|
||||
add("Make a mind tiara.",
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Smith some Blurite Limbs on Doric's Anvil.",
|
||||
new SkillRequirement(Skill.MINING, 10),
|
||||
new SkillRequirement(Skill.SMITHING, 13),
|
||||
new QuestRequirement(Quest.THE_KNIGHTS_SWORD),
|
||||
new QuestRequirement(Quest.DORICS_QUEST));
|
||||
|
||||
// MEDIUM
|
||||
add("Light a Bullseye lantern at the Chemist's in Rimmington.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 49));
|
||||
add("Telegrab some Wine of Zamorak at the Chaos Temple by the Wilderness.",
|
||||
new SkillRequirement(Skill.MAGIC, 33));
|
||||
add("Place a Scarecrow in the Falador farming patch.",
|
||||
new SkillRequirement(Skill.FARMING, 23));
|
||||
add("Kill a Mogre at Mudskipper Point.",
|
||||
new SkillRequirement(Skill.SLAYER, 32),
|
||||
new QuestRequirement(Quest.SKIPPY_AND_THE_MOGRES));
|
||||
add("Visit the Port Sarim Rat Pits.",
|
||||
new QuestRequirement(Quest.RATCATCHERS, true));
|
||||
add("Grapple up and then jump off the north Falador wall.",
|
||||
new SkillRequirement(Skill.AGILITY, 11),
|
||||
new SkillRequirement(Skill.STRENGTH, 37),
|
||||
new SkillRequirement(Skill.RANGED, 19));
|
||||
add("Pickpocket a Falador guard.",
|
||||
new SkillRequirement(Skill.THIEVING, 40));
|
||||
add("Pray at the Altar of Guthix in Taverley whilst wearing full Initiate.",
|
||||
new SkillRequirement(Skill.PRAYER, 10),
|
||||
new SkillRequirement(Skill.DEFENCE, 20),
|
||||
new QuestRequirement(Quest.RECRUITMENT_DRIVE));
|
||||
add("Mine some Gold ore at the Crafting Guild.",
|
||||
new SkillRequirement(Skill.CRAFTING, 40),
|
||||
new SkillRequirement(Skill.MINING, 40));
|
||||
add("Squeeze through the crevice in the Dwarven mines.",
|
||||
new SkillRequirement(Skill.AGILITY, 42));
|
||||
add("Chop and burn some Willow logs in Taverley",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 30),
|
||||
new SkillRequirement(Skill.FIREMAKING, 30));
|
||||
add("Craft a fruit basket on the Falador Farm loom.",
|
||||
new SkillRequirement(Skill.CRAFTING, 36));
|
||||
add("Teleport to Falador.",
|
||||
new SkillRequirement(Skill.MAGIC, 37));
|
||||
|
||||
// HARD
|
||||
add("Craft 140 Mind runes simultaneously.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 56));
|
||||
add("Change your family crest to the Saradomin symbol.",
|
||||
new SkillRequirement(Skill.PRAYER, 70));
|
||||
add("Kill a Skeletal Wyvern in the Asgarnia Ice Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 72));
|
||||
add("Complete a lap of the Falador rooftop agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 50));
|
||||
add("Enter the mining guild wearing full prospector.",
|
||||
new SkillRequirement(Skill.MINING, 60));
|
||||
add("Kill the Blue Dragon under the Heroes' Guild.",
|
||||
new QuestRequirement(Quest.HEROES_QUEST));
|
||||
add("Crack a wall safe within Rogues Den.",
|
||||
new SkillRequirement(Skill.THIEVING, 50));
|
||||
add("Recharge your prayer in the Port Sarim church while wearing full Proselyte.",
|
||||
new SkillRequirement(Skill.DEFENCE, 30),
|
||||
new QuestRequirement(Quest.THE_SLUG_MENACE));
|
||||
add("Equip a dwarven helmet within the dwarven mines.",
|
||||
new SkillRequirement(Skill.DEFENCE, 50),
|
||||
new QuestRequirement(Quest.GRIM_TALES));
|
||||
|
||||
// ELITE
|
||||
add("Craft 252 Air Runes simultaneously.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 88));
|
||||
add("Purchase a White 2h Sword from Sir Vyvin.",
|
||||
new QuestRequirement(Quest.WANTED));
|
||||
add("Find at least 3 magic roots at once when digging up your magic tree in Falador.",
|
||||
new SkillRequirement(Skill.FARMING, 91),
|
||||
new SkillRequirement(Skill.WOODCUTTING, 75));
|
||||
add("Jump over the strange floor in Taverley dungeon.",
|
||||
new SkillRequirement(Skill.AGILITY, 80));
|
||||
add("Mix a Saradomin brew in Falador east bank.",
|
||||
new SkillRequirement(Skill.HERBLORE, 81));
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class FremennikDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public FremennikDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Catch a Cerulean twitch.",
|
||||
new SkillRequirement(Skill.HUNTER, 11));
|
||||
add("Change your boots at Yrsa's Shoe Store.",
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS));
|
||||
add("Craft a tiara from scratch in Rellekka.",
|
||||
new SkillRequirement(Skill.CRAFTING, 23),
|
||||
new SkillRequirement(Skill.MINING, 20),
|
||||
new SkillRequirement(Skill.SMITHING, 20),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS));
|
||||
add("Browse the Stonemasons shop.",
|
||||
new QuestRequirement(Quest.THE_GIANT_DWARF, true));
|
||||
add("Steal from the Keldagrim crafting or baker's stall.",
|
||||
new SkillRequirement(Skill.THIEVING, 5),
|
||||
new QuestRequirement(Quest.THE_GIANT_DWARF, true));
|
||||
add("Enter the Troll Stronghold.",
|
||||
new QuestRequirement(Quest.DEATH_PLATEAU),
|
||||
new QuestRequirement(Quest.TROLL_STRONGHOLD, true));
|
||||
add("Chop and burn some oak logs in the Fremennik Province.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 15),
|
||||
new SkillRequirement(Skill.FIREMAKING, 15));
|
||||
|
||||
// MEDIUM
|
||||
add("Slay a Brine rat.",
|
||||
new SkillRequirement(Skill.SLAYER, 47),
|
||||
new QuestRequirement(Quest.OLAFS_QUEST, true));
|
||||
add("Travel to the Snowy Hunter Area via Eagle.",
|
||||
new QuestRequirement(Quest.EAGLES_PEAK));
|
||||
add("Mine some coal in Rellekka.",
|
||||
new SkillRequirement(Skill.MINING, 30),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS));
|
||||
add("Steal from the Rellekka Fish stalls.",
|
||||
new SkillRequirement(Skill.THIEVING, 42),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS));
|
||||
add("Travel to Miscellania by Fairy ring.",
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS),
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Catch a Snowy knight.",
|
||||
new SkillRequirement(Skill.HUNTER, 35));
|
||||
add("Pick up your Pet Rock from your POH Menagerie.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 37),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS));
|
||||
add("Visit the Lighthouse from Waterbirth island.",
|
||||
new QuestRequirement(Quest.HORROR_FROM_THE_DEEP),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_TRIALS, true));
|
||||
add("Mine some gold at the Arzinian mine.",
|
||||
new SkillRequirement(Skill.MINING, 40),
|
||||
new QuestRequirement(Quest.BETWEEN_A_ROCK, true));
|
||||
|
||||
// HARD
|
||||
add("Teleport to Trollheim.",
|
||||
new SkillRequirement(Skill.MAGIC, 61),
|
||||
new QuestRequirement(Quest.EADGARS_RUSE));
|
||||
add("Catch a Sabre-toothed Kyatt.",
|
||||
new SkillRequirement(Skill.HUNTER, 55));
|
||||
add("Mix a super defence potion in the Fremennik province.",
|
||||
new SkillRequirement(Skill.HERBLORE, 66));
|
||||
add("Steal from the Keldagrim Gem Stall.",
|
||||
new SkillRequirement(Skill.THIEVING, 75),
|
||||
new QuestRequirement(Quest.THE_GIANT_DWARF, true));
|
||||
add("Craft a Fremennik shield on Neitiznot.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 56),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_ISLES));
|
||||
add("Mine 5 Adamantite ores on Jatizso.",
|
||||
new SkillRequirement(Skill.MINING, 70),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_ISLES));
|
||||
add("Obtain 100% support from your kingdom subjects.",
|
||||
new QuestRequirement(Quest.THRONE_OF_MISCELLANIA));
|
||||
add("Teleport to Waterbirth Island.",
|
||||
new SkillRequirement(Skill.MAGIC, 72),
|
||||
new QuestRequirement(Quest.LUNAR_DIPLOMACY));
|
||||
add("Obtain the Blast Furnace Foreman's permission to use the Blast Furnace for free.",
|
||||
new SkillRequirement(Skill.SMITHING, 60),
|
||||
new QuestRequirement(Quest.THE_GIANT_DWARF, true));
|
||||
|
||||
// ELITE
|
||||
add("Craft 56 astral runes at once.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 82),
|
||||
new QuestRequirement(Quest.LUNAR_DIPLOMACY));
|
||||
add("Create a dragonstone amulet in the Neitiznot furnace.",
|
||||
new SkillRequirement(Skill.CRAFTING, 80),
|
||||
new QuestRequirement(Quest.THE_FREMENNIK_ISLES, true));
|
||||
add("Complete a lap of the Rellekka agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 80));
|
||||
add("Kill each of the Godwars generals.",
|
||||
new SkillRequirement(Skill.AGILITY, 70),
|
||||
new SkillRequirement(Skill.STRENGTH, 70),
|
||||
new SkillRequirement(Skill.HITPOINTS, 70),
|
||||
new SkillRequirement(Skill.RANGED, 70),
|
||||
new QuestRequirement(Quest.TROLL_STRONGHOLD));
|
||||
add("Slay a Spiritual mage within the Godwars Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 83),
|
||||
new QuestRequirement(Quest.TROLL_STRONGHOLD));
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class KandarinDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public KandarinDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Catch a Mackerel at Catherby.",
|
||||
new SkillRequirement(Skill.FISHING, 16));
|
||||
add("Plant some Jute seeds in the patch north of McGrubor's Wood.",
|
||||
new SkillRequirement(Skill.FARMING, 13));
|
||||
add("Defeat one of each elemental in the workshop.",
|
||||
new QuestRequirement(Quest.ELEMENTAL_WORKSHOP_I, true));
|
||||
add("Cross the Coal truck log shortcut.",
|
||||
new SkillRequirement(Skill.AGILITY, 20));
|
||||
|
||||
// MEDIUM
|
||||
add("Complete a lap of the Barbarian agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 35),
|
||||
new QuestRequirement(Quest.ALFRED_GRIMHANDS_BARCRAWL));
|
||||
add("Create a Super Antipoison potion from scratch in the Seers/Catherby Area.",
|
||||
new SkillRequirement(Skill.HERBLORE, 48));
|
||||
add("Enter the Ranging guild.",
|
||||
new SkillRequirement(Skill.RANGED, 40));
|
||||
add("Use the grapple shortcut to get from the water obelisk to Catherby shore.",
|
||||
new SkillRequirement(Skill.AGILITY, 36),
|
||||
new SkillRequirement(Skill.STRENGTH, 22),
|
||||
new SkillRequirement(Skill.RANGED, 39));
|
||||
add("Catch and cook a Bass in Catherby.",
|
||||
new SkillRequirement(Skill.FISHING, 46),
|
||||
new SkillRequirement(Skill.COOKING, 43));
|
||||
add("Teleport to Camelot.",
|
||||
new SkillRequirement(Skill.MAGIC, 45));
|
||||
add("String a Maple shortbow in Seers' Village bank.",
|
||||
new SkillRequirement(Skill.FLETCHING, 50));
|
||||
add("Pick some Limpwurt root from the farming patch in Catherby.",
|
||||
new SkillRequirement(Skill.FARMING, 26));
|
||||
add("Create a Mind helmet.",
|
||||
new QuestRequirement(Quest.ELEMENTAL_WORKSHOP_II));
|
||||
add("Kill a Fire Giant inside Baxtorian Waterfall.",
|
||||
new QuestRequirement(Quest.WATERFALL_QUEST, true));
|
||||
add("Steal from the chest in Hemenster.",
|
||||
new SkillRequirement(Skill.THIEVING, 47));
|
||||
add("Travel to McGrubor's Wood by Fairy Ring.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Mine some coal near the coal trucks.",
|
||||
new SkillRequirement(Skill.MINING, 30));
|
||||
|
||||
// HARD
|
||||
add("Catch a Leaping Sturgeon.",
|
||||
new SkillRequirement(Skill.FISHING, 70),
|
||||
new SkillRequirement(Skill.AGILITY, 45),
|
||||
new SkillRequirement(Skill.STRENGTH, 45));
|
||||
add("Complete a lap of the Seers' Village agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 60));
|
||||
add("Create a Yew Longbow from scratch around Seers' Village.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 60),
|
||||
new SkillRequirement(Skill.FLETCHING, 70),
|
||||
new SkillRequirement(Skill.CRAFTING, 10));
|
||||
add("Enter the Seers' Village courthouse with piety turned on.",
|
||||
new SkillRequirement(Skill.PRAYER, 70),
|
||||
new SkillRequirement(Skill.DEFENCE, 70),
|
||||
new QuestRequirement(Quest.KINGS_RANSOM));
|
||||
add("Charge a Water Orb.",
|
||||
new SkillRequirement(Skill.MAGIC, 56));
|
||||
add("Burn some Maple logs with a bow in Seers' Village.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 65));
|
||||
add("Kill a Shadow Hound in the Shadow dungeon.",
|
||||
new SkillRequirement(Skill.THIEVING, 53),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE, true));
|
||||
add("Purchase and equip a granite body from Barbarian Assault.",
|
||||
new SkillRequirement(Skill.STRENGTH, 50),
|
||||
new SkillRequirement(Skill.DEFENCE, 50));
|
||||
add("Have the Seers' estate agent decorate your house with Fancy Stone.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 50));
|
||||
add("Smith an Adamant spear at Otto's Grotto.",
|
||||
new SkillRequirement(Skill.SMITHING, 75),
|
||||
new QuestRequirement(Quest.TAI_BWO_WANNAI_TRIO));
|
||||
|
||||
// ELITE
|
||||
add("Pick some Dwarf weed from the herb patch at Catherby.",
|
||||
new SkillRequirement(Skill.FARMING, 79));
|
||||
add("Fish and Cook 5 Sharks in Catherby using the Cooking gauntlets.",
|
||||
new SkillRequirement(Skill.FISHING, 76),
|
||||
new SkillRequirement(Skill.COOKING, 80),
|
||||
new QuestRequirement(Quest.FAMILY_CREST));
|
||||
add("Mix a Stamina Mix on top of the Seers' Village bank.",
|
||||
new SkillRequirement(Skill.HERBLORE, 86),
|
||||
new SkillRequirement(Skill.AGILITY, 60));
|
||||
add("Smith a Rune Hasta at Otto's Grotto.",
|
||||
new SkillRequirement(Skill.SMITHING, 90));
|
||||
add("Construct a Pyre ship from Magic Logs.(Requires Chewed Bones.)",
|
||||
new SkillRequirement(Skill.FIREMAKING, 85),
|
||||
new SkillRequirement(Skill.CRAFTING, 85));
|
||||
add("Teleport to Catherby.",
|
||||
new SkillRequirement(Skill.MAGIC, 87),
|
||||
new QuestRequirement(Quest.LUNAR_DIPLOMACY));
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.CombatLevelRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.OrRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class KaramjaDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public KaramjaDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Use the rope swing to travel to the small island north-west of Karamja, where the " +
|
||||
"moss giants are.",
|
||||
new SkillRequirement(Skill.AGILITY, 10));
|
||||
add("Mine some gold from the rocks on the north-west peninsula of Karamja.",
|
||||
new SkillRequirement(Skill.MINING, 40));
|
||||
add("Explore Cairn Island to the west of Karamja.",
|
||||
new SkillRequirement(Skill.AGILITY, 15));
|
||||
|
||||
// MEDIUM
|
||||
add("Claim a ticket from the Agility Arena in Brimhaven.",
|
||||
new SkillRequirement(Skill.AGILITY, 30));
|
||||
add("Discover hidden wall in the dungeon below the volcano.",
|
||||
new QuestRequirement(Quest.DRAGON_SLAYER, true));
|
||||
add("Visit the Isle of Crandor via the dungeon below the volcano.",
|
||||
new QuestRequirement(Quest.DRAGON_SLAYER, true));
|
||||
add("Use Vigroy and Hajedy's cart service.",
|
||||
new QuestRequirement(Quest.SHILO_VILLAGE));
|
||||
add("Earn 100% favour in the village of Tai Bwo Wannai.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 10),
|
||||
new QuestRequirement(Quest.JUNGLE_POTION));
|
||||
add("Cook a spider on a stick.",
|
||||
new SkillRequirement(Skill.COOKING, 16));
|
||||
add("Charter the Lady of the Waves from Cairn Isle to Port Khazard.",
|
||||
new QuestRequirement(Quest.SHILO_VILLAGE));
|
||||
add("Cut a log from a teak tree.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 35),
|
||||
new QuestRequirement(Quest.JUNGLE_POTION));
|
||||
add("Cut a log from a mahogany tree.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 50),
|
||||
new QuestRequirement(Quest.JUNGLE_POTION));
|
||||
add("Catch a karambwan.",
|
||||
new SkillRequirement(Skill.FISHING, 65),
|
||||
new QuestRequirement(Quest.TAI_BWO_WANNAI_TRIO, true));
|
||||
add("Exchange gems for a machete.",
|
||||
new QuestRequirement(Quest.JUNGLE_POTION));
|
||||
add("Use the gnome glider to travel to Karamja.",
|
||||
new QuestRequirement(Quest.THE_GRAND_TREE));
|
||||
add("Grow a healthy fruit tree in the patch near Brimhaven.",
|
||||
new SkillRequirement(Skill.FARMING, 27));
|
||||
add("Trap a horned graahk.",
|
||||
new SkillRequirement(Skill.HUNTER, 41));
|
||||
add("Chop the vines to gain deeper access to Brimhaven Dungeon.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 10));
|
||||
add("Cross the lava using the stepping stones within Brimhaven Dungeon.",
|
||||
new SkillRequirement(Skill.AGILITY, 12));
|
||||
add("Climb the stairs within Brimhaven Dungeon.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 10));
|
||||
add("Charter a ship from the shipyard in the far east of Karamja.",
|
||||
new QuestRequirement(Quest.THE_GRAND_TREE));
|
||||
add("Mine a red topaz from a gem rock.",
|
||||
new SkillRequirement(Skill.MINING, 40),
|
||||
new OrRequirement(
|
||||
new QuestRequirement(Quest.SHILO_VILLAGE),
|
||||
new QuestRequirement(Quest.JUNGLE_POTION)
|
||||
)
|
||||
);
|
||||
|
||||
// HARD
|
||||
add("Craft some nature runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 44),
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Cook a karambwan thoroughly.",
|
||||
new SkillRequirement(Skill.COOKING, 30),
|
||||
new QuestRequirement(Quest.TAI_BWO_WANNAI_TRIO));
|
||||
add("Kill a deathwing in the dungeon under the Kharazi Jungle.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 15),
|
||||
new SkillRequirement(Skill.STRENGTH, 50),
|
||||
new SkillRequirement(Skill.AGILITY, 50),
|
||||
new SkillRequirement(Skill.THIEVING, 50),
|
||||
new SkillRequirement(Skill.MINING, 52),
|
||||
new QuestRequirement(Quest.LEGENDS_QUEST));
|
||||
add("Use the crossbow short cut south of the volcano.",
|
||||
new SkillRequirement(Skill.AGILITY, 53),
|
||||
new SkillRequirement(Skill.RANGED, 42),
|
||||
new SkillRequirement(Skill.STRENGTH, 21));
|
||||
add("Collect 5 palm leaves.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 15),
|
||||
new QuestRequirement(Quest.LEGENDS_QUEST));
|
||||
add("Be assigned a Slayer task by Duradel north of Shilo Village.",
|
||||
new CombatLevelRequirement(100),
|
||||
new SkillRequirement(Skill.SLAYER, 50),
|
||||
new QuestRequirement(Quest.SHILO_VILLAGE));
|
||||
|
||||
// ELITE
|
||||
add("Craft 56 Nature runes at once.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 91));
|
||||
add("Check the health of a palm tree in Brimhaven.",
|
||||
new SkillRequirement(Skill.FARMING, 68));
|
||||
add("Create an antivenom potion whilst standing in the horse shoe mine.",
|
||||
new SkillRequirement(Skill.HERBLORE, 87));
|
||||
add("Check the health of your Calquat tree patch.",
|
||||
new SkillRequirement(Skill.FARMING, 72));
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 William <https://github.com/monsterxsync>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Favour;
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.FavourRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class KourendDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public KourendDiaryRequirement()
|
||||
{
|
||||
//EASY
|
||||
add("Mine some Iron at the Mount Karuulm mine.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
add("Steal from a Hosidius Food Stall.",
|
||||
new SkillRequirement(Skill.THIEVING, 25),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 15));
|
||||
add("Browse the Warrens General Store.",
|
||||
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES, true));
|
||||
add("Enter your Player Owned House from Hosidius.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 25));
|
||||
add("Create a Strength potion in the Lovakengj Pub.",
|
||||
new SkillRequirement(Skill.HERBLORE, 12));
|
||||
add("Fish a Trout from the River Molch.",
|
||||
new SkillRequirement(Skill.FISHING, 20));
|
||||
|
||||
//MEDIUM
|
||||
add("Travel to the Fairy Ring south of Mount Karuulm.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Use Kharedst's memoirs to teleport to all five cities in Great Kourend.",
|
||||
new QuestRequirement(Quest.THE_DEPTHS_OF_DESPAIR),
|
||||
new QuestRequirement(Quest.THE_QUEEN_OF_THIEVES),
|
||||
new QuestRequirement(Quest.TALE_OF_THE_RIGHTEOUS),
|
||||
new QuestRequirement(Quest.THE_FORSAKEN_TOWER),
|
||||
new QuestRequirement(Quest.THE_ASCENT_OF_ARCEUUS));
|
||||
add("Mine some Volcanic sulphur.",
|
||||
new SkillRequirement(Skill.MINING, 42));
|
||||
add("Enter the Farming Guild.",
|
||||
new SkillRequirement(Skill.FARMING, 45));
|
||||
add("Switch to the Necromancy Spellbook at Tyss.",
|
||||
new FavourRequirement(Favour.ARCEUUS, 60));
|
||||
add("Repair a Piscarilius crane.",
|
||||
new SkillRequirement(Skill.CRAFTING, 30));
|
||||
add("Deliver some intelligence to Captain Ginea.",
|
||||
new FavourRequirement(Favour.SHAYZIEN, 40));
|
||||
add("Catch a Bluegill on Molch Island.",
|
||||
new SkillRequirement(Skill.FISHING, 43),
|
||||
new SkillRequirement(Skill.HUNTER, 35));
|
||||
add("Use the boulder leap in the Arceuus essence mine.",
|
||||
new SkillRequirement(Skill.AGILITY, 49));
|
||||
add("Subdue the Wintertodt.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 50));
|
||||
add("Catch a Chinchompa in the Kourend Woodland.",
|
||||
new SkillRequirement(Skill.HUNTER, 53),
|
||||
new QuestRequirement(Quest.EAGLES_PEAK));
|
||||
add("Chop some Mahogany logs north of the Farming Guild.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 50));
|
||||
|
||||
//HARD
|
||||
add("Enter the Woodcutting Guild.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 60),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 75));
|
||||
add("Smelt an Adamantite bar in The Forsaken Tower.",
|
||||
new SkillRequirement(Skill.SMITHING, 70),
|
||||
new QuestRequirement(Quest.THE_FORSAKEN_TOWER, true));
|
||||
add("Kill a Lizardman Shaman in Molch.",
|
||||
new FavourRequirement(Favour.SHAYZIEN, 100));
|
||||
add("Mine some Lovakite.",
|
||||
new SkillRequirement(Skill.MINING, 65),
|
||||
new FavourRequirement(Favour.LOVAKENGJ, 30));
|
||||
add("Plant some Logavano seeds at the Tithe Farm.",
|
||||
new SkillRequirement(Skill.FARMING, 74),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 100));
|
||||
add("Teleport to Xeric's Heart using Xeric's Talisman.",
|
||||
new QuestRequirement(Quest.ARCHITECTURAL_ALLIANCE));
|
||||
add("Deliver an artefact to Captain Khaled.",
|
||||
new SkillRequirement(Skill.THIEVING, 49),
|
||||
new FavourRequirement(Favour.PISCARILIUS, 75));
|
||||
add("Kill a Wyrm in the Karuulm Slayer Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 62));
|
||||
add("Cast Monster Examine on a Troll south of Mount Quidamortem.",
|
||||
new SkillRequirement(Skill.MAGIC, 66),
|
||||
new QuestRequirement(Quest.DREAM_MENTOR));
|
||||
|
||||
//ELITE
|
||||
add("Craft one or more Blood runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 77),
|
||||
new SkillRequirement(Skill.MINING, 38),
|
||||
new SkillRequirement(Skill.CRAFTING, 38),
|
||||
new FavourRequirement(Favour.ARCEUUS, 100));
|
||||
add("Chop some Redwood logs.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 90),
|
||||
new FavourRequirement(Favour.HOSIDIUS, 75));
|
||||
add("Catch an Anglerfish and cook it whilst in Great Kourend.",
|
||||
new SkillRequirement(Skill.FISHING, 82),
|
||||
new SkillRequirement(Skill.COOKING, 84),
|
||||
new FavourRequirement(Favour.PISCARILIUS, 100));
|
||||
add("Kill a Hydra in the Karuulm Slayer Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 95));
|
||||
add("Create an Ape Atoll teleport tablet.",
|
||||
new SkillRequirement(Skill.MAGIC, 90),
|
||||
new SkillRequirement(Skill.MINING, 38),
|
||||
new SkillRequirement(Skill.CRAFTING, 38),
|
||||
new FavourRequirement(Favour.ARCEUUS, 100));
|
||||
add("Create your own Battlestaff from scratch within the Farming Guild.",
|
||||
new SkillRequirement(Skill.FARMING, 85),
|
||||
new SkillRequirement(Skill.FLETCHING, 40));
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.CombatLevelRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class LumbridgeDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public LumbridgeDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Complete a lap of the Draynor Village agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 10));
|
||||
add("Slay a Cave bug beneath Lumbridge Swamp.",
|
||||
new SkillRequirement(Skill.SLAYER, 7));
|
||||
add("Have Sedridor teleport you to the Essence Mine.",
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Craft some water runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 5),
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Chop and burn some oak logs in Lumbridge.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 15),
|
||||
new SkillRequirement(Skill.FIREMAKING, 15));
|
||||
add("Catch some Anchovies in Al Kharid.",
|
||||
new SkillRequirement(Skill.FISHING, 15));
|
||||
add("Bake some Bread on the Lumbridge kitchen range.",
|
||||
new QuestRequirement(Quest.COOKS_ASSISTANT));
|
||||
add("Mine some Iron ore at the Al Kharid mine.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
|
||||
// MEDIUM
|
||||
add("Complete a lap of the Al Kharid agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 20));
|
||||
add("Grapple across the River Lum.",
|
||||
new SkillRequirement(Skill.AGILITY, 8),
|
||||
new SkillRequirement(Skill.STRENGTH, 19),
|
||||
new SkillRequirement(Skill.RANGED, 37));
|
||||
add("Purchase an upgraded device from Ava.",
|
||||
new SkillRequirement(Skill.RANGED, 50),
|
||||
new QuestRequirement(Quest.ANIMAL_MAGNETISM));
|
||||
add("Travel to the Wizards' Tower by Fairy ring.",
|
||||
new QuestRequirement(Quest.FAIRYTALE_II__CURE_A_QUEEN, true));
|
||||
add("Cast the teleport to Lumbridge spell.",
|
||||
new SkillRequirement(Skill.MAGIC, 31));
|
||||
add("Catch some Salmon in Lumbridge.",
|
||||
new SkillRequirement(Skill.FISHING, 30));
|
||||
add("Craft a coif in the Lumbridge cow pen.",
|
||||
new SkillRequirement(Skill.CRAFTING, 38));
|
||||
add("Chop some willow logs in Draynor Village.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 30));
|
||||
add("Pickpocket Martin the Master Gardener.",
|
||||
new SkillRequirement(Skill.THIEVING, 38));
|
||||
add("Get a slayer task from Chaeldar.",
|
||||
new CombatLevelRequirement(70),
|
||||
new QuestRequirement(Quest.LOST_CITY));
|
||||
add("Catch an Essence or Eclectic impling in Puro-Puro.",
|
||||
new SkillRequirement(Skill.HUNTER, 42),
|
||||
new QuestRequirement(Quest.LOST_CITY));
|
||||
add("Craft some Lava runes at the fire altar in Al Kharid.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 23),
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
|
||||
// HARD
|
||||
add("Cast Bones to Peaches in Al Kharid palace.",
|
||||
new SkillRequirement(Skill.MAGIC, 60));
|
||||
add("Squeeze past the jutting wall on your way to the cosmic altar.",
|
||||
new SkillRequirement(Skill.AGILITY, 46),
|
||||
new QuestRequirement(Quest.LOST_CITY));
|
||||
add("Craft 56 Cosmic runes simultaneously.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 59),
|
||||
new QuestRequirement(Quest.LOST_CITY));
|
||||
add("Travel from Lumbridge to Edgeville on a Waka Canoe.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 57));
|
||||
add("Collect at least 100 Tears of Guthix in one visit.",
|
||||
new QuestRequirement(Quest.TEARS_OF_GUTHIX));
|
||||
add("Take the train from Dorgesh-Kaan to Keldagrim.",
|
||||
new QuestRequirement(Quest.ANOTHER_SLICE_OF_HAM));
|
||||
add("Purchase some Barrows gloves from the Lumbridge bank chest.",
|
||||
new QuestRequirement(Quest.RECIPE_FOR_DISASTER));
|
||||
add("Pick some Belladonna from the farming patch at Draynor Manor.",
|
||||
new SkillRequirement(Skill.FARMING, 63));
|
||||
add("Light your mining helmet in the Lumbridge castle basement.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 65));
|
||||
add("Recharge your prayer at Clan Wars with Smite activated.",
|
||||
new SkillRequirement(Skill.PRAYER, 52));
|
||||
add("Craft, string and enchant an Amulet of Power in Lumbridge.",
|
||||
new SkillRequirement(Skill.CRAFTING, 70),
|
||||
new SkillRequirement(Skill.MAGIC, 57));
|
||||
|
||||
// ELITE
|
||||
add("Steal from a Dorgesh-Kaan rich chest.",
|
||||
new SkillRequirement(Skill.THIEVING, 78),
|
||||
new QuestRequirement(Quest.DEATH_TO_THE_DORGESHUUN));
|
||||
add("Pickpocket Movario on the Dorgesh-Kaan Agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 70),
|
||||
new SkillRequirement(Skill.RANGED, 70),
|
||||
new SkillRequirement(Skill.STRENGTH, 70),
|
||||
new QuestRequirement(Quest.DEATH_TO_THE_DORGESHUUN));
|
||||
add("Chop some magic logs at the Mage Training Arena.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 75));
|
||||
add("Smith an Adamant platebody down Draynor sewer.",
|
||||
new SkillRequirement(Skill.SMITHING, 88));
|
||||
add("Craft 140 or more Water runes at once.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 76),
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.CombatLevelRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.OrRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class MorytaniaDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public MorytaniaDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Craft any Snelm from scratch in Morytania.",
|
||||
new SkillRequirement(Skill.CRAFTING, 15));
|
||||
add("Cook a thin Snail on the Port Phasmatys range.",
|
||||
new SkillRequirement(Skill.COOKING, 12));
|
||||
add("Get a slayer task from Mazchna.",
|
||||
new CombatLevelRequirement(20));
|
||||
add("Kill a Banshee in the Slayer Tower.",
|
||||
new SkillRequirement(Skill.SLAYER, 15));
|
||||
add("Place a Scarecrow in the Morytania flower patch.",
|
||||
new SkillRequirement(Skill.FARMING, 23));
|
||||
add("Kill a werewolf in its human form using the Wolfbane Dagger.",
|
||||
new QuestRequirement(Quest.PRIEST_IN_PERIL));
|
||||
add("Restore your prayer points at the nature altar.",
|
||||
new QuestRequirement(Quest.NATURE_SPIRIT));
|
||||
|
||||
// MEDIUM
|
||||
add("Catch a swamp lizard.",
|
||||
new SkillRequirement(Skill.HUNTER, 29));
|
||||
add("Complete a lap of the Canifis agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 40));
|
||||
add("Obtain some Bark from a Hollow tree.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 45));
|
||||
add("Kill a Terror Dog.",
|
||||
new SkillRequirement(Skill.SLAYER, 40),
|
||||
new QuestRequirement(Quest.LAIR_OF_TARN_RAZORLOR));
|
||||
add("Complete a game of trouble brewing.",
|
||||
new SkillRequirement(Skill.COOKING, 40),
|
||||
new QuestRequirement(Quest.CABIN_FEVER));
|
||||
add("Make a batch of cannonballs at the Port Phasmatys furnace.",
|
||||
new SkillRequirement(Skill.SMITHING, 35),
|
||||
new QuestRequirement(Quest.DWARF_CANNON),
|
||||
new QuestRequirement(Quest.GHOSTS_AHOY, true));
|
||||
add("Kill a Fever Spider on Braindeath Island.",
|
||||
new SkillRequirement(Skill.SLAYER, 42),
|
||||
new QuestRequirement(Quest.RUM_DEAL));
|
||||
add("Use an ectophial to return to Port Phasmatys.",
|
||||
new QuestRequirement(Quest.GHOSTS_AHOY));
|
||||
add("Mix a Guthix Balance potion while in Morytania.",
|
||||
new SkillRequirement(Skill.HERBLORE, 22),
|
||||
new QuestRequirement(Quest.IN_AID_OF_THE_MYREQUE, true));
|
||||
|
||||
// HARD
|
||||
add("Enter the Kharyrll portal in your POH.",
|
||||
new SkillRequirement(Skill.MAGIC, 66),
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 50),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE));
|
||||
add("Climb the advanced spike chain within Slayer Tower.",
|
||||
new SkillRequirement(Skill.AGILITY, 71));
|
||||
add("Harvest some Watermelon from the Allotment patch on Harmony Island.",
|
||||
new SkillRequirement(Skill.FARMING, 47),
|
||||
new QuestRequirement(Quest.THE_GREAT_BRAIN_ROBBERY, true));
|
||||
add("Chop and burn some mahogany logs on Mos Le'Harmless.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 50),
|
||||
new SkillRequirement(Skill.FIREMAKING, 50),
|
||||
new QuestRequirement(Quest.CABIN_FEVER));
|
||||
add("Complete a temple trek with a hard companion.",
|
||||
new QuestRequirement(Quest.IN_AID_OF_THE_MYREQUE));
|
||||
add("Kill a Cave Horror.",
|
||||
new SkillRequirement(Skill.SLAYER, 58),
|
||||
new QuestRequirement(Quest.CABIN_FEVER));
|
||||
add("Harvest some Bittercap Mushrooms from the patch in Canifis.",
|
||||
new SkillRequirement(Skill.FARMING, 53));
|
||||
add("Pray at the Altar of Nature with Piety activated.",
|
||||
new SkillRequirement(Skill.PRAYER, 70),
|
||||
new SkillRequirement(Skill.DEFENCE, 70),
|
||||
new QuestRequirement(Quest.NATURE_SPIRIT),
|
||||
new QuestRequirement(Quest.KINGS_RANSOM));
|
||||
add("Use the shortcut to get to the bridge over the Salve.",
|
||||
new SkillRequirement(Skill.AGILITY, 65));
|
||||
add("Mine some Mithril ore in the Abandoned Mine.",
|
||||
new SkillRequirement(Skill.MINING, 55),
|
||||
new QuestRequirement(Quest.HAUNTED_MINE));
|
||||
|
||||
// ELITE
|
||||
add("Catch a shark in Burgh de Rott with your bare hands.",
|
||||
new SkillRequirement(Skill.FISHING, 96),
|
||||
new SkillRequirement(Skill.STRENGTH, 76),
|
||||
new QuestRequirement(Quest.IN_AID_OF_THE_MYREQUE));
|
||||
add("Cremate any Shade remains on a Magic or Redwood pyre.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 80),
|
||||
new QuestRequirement(Quest.SHADES_OF_MORTTON));
|
||||
add("Fertilize the Morytania herb patch using Lunar Magic.",
|
||||
new SkillRequirement(Skill.MAGIC, 83),
|
||||
new QuestRequirement(Quest.LUNAR_DIPLOMACY));
|
||||
add("Craft a Black dragonhide body in Canifis bank.",
|
||||
new SkillRequirement(Skill.CRAFTING, 84));
|
||||
add("Kill an Abyssal demon in the Slayer Tower.",
|
||||
new SkillRequirement(Skill.SLAYER, 85));
|
||||
add("Loot the Barrows chest while wearing any complete barrows set.",
|
||||
new SkillRequirement(Skill.DEFENCE, 70),
|
||||
new OrRequirement(
|
||||
new SkillRequirement(Skill.ATTACK, 70),
|
||||
new SkillRequirement(Skill.STRENGTH, 70),
|
||||
new SkillRequirement(Skill.RANGED, 70),
|
||||
new SkillRequirement(Skill.MAGIC, 70)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.CombatLevelRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestPointRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class VarrockDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public VarrockDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Have Aubury teleport you to the Essence mine.",
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Mine some Iron in the south east mining patch near Varrock.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
add("Jump over the fence south of Varrock.",
|
||||
new SkillRequirement(Skill.AGILITY, 13));
|
||||
add("Spin a bowl on the pottery wheel and fire it in the oven in Barb Village.",
|
||||
new SkillRequirement(Skill.CRAFTING, 8));
|
||||
add("Craft some Earth runes.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 9));
|
||||
add("Catch some trout in the River Lum at Barbarian Village.",
|
||||
new SkillRequirement(Skill.FISHING, 20));
|
||||
add("Steal from the Tea stall in Varrock.",
|
||||
new SkillRequirement(Skill.THIEVING, 5));
|
||||
|
||||
// MEDIUM
|
||||
add("Enter the Champions' Guild.",
|
||||
new QuestPointRequirement(32));
|
||||
add("Select a colour for your kitten.",
|
||||
new QuestRequirement(Quest.GARDEN_OF_TRANQUILLITY, true),
|
||||
new QuestRequirement(Quest.GERTRUDES_CAT));
|
||||
add("Use the spirit tree north of Varrock.",
|
||||
new QuestRequirement(Quest.TREE_GNOME_VILLAGE));
|
||||
add("Enter the Tolna dungeon after completing A Soul's Bane.",
|
||||
new QuestRequirement(Quest.A_SOULS_BANE));
|
||||
add("Teleport to the digsite using a Digsite pendant.",
|
||||
new QuestRequirement(Quest.THE_DIG_SITE));
|
||||
add("Cast the teleport to Varrock spell.",
|
||||
new SkillRequirement(Skill.MAGIC, 25));
|
||||
add("Get a Slayer task from Vannaka.",
|
||||
new CombatLevelRequirement(40));
|
||||
add("Pick a White tree fruit.",
|
||||
new SkillRequirement(Skill.FARMING, 25),
|
||||
new QuestRequirement(Quest.GARDEN_OF_TRANQUILLITY));
|
||||
add("Use the balloon to travel from Varrock.",
|
||||
new SkillRequirement(Skill.FIREMAKING, 40),
|
||||
new QuestRequirement(Quest.ENLIGHTENED_JOURNEY));
|
||||
add("Complete a lap of the Varrock Agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 30));
|
||||
|
||||
// HARD
|
||||
add("Trade furs with the Fancy Dress Seller for a spottier cape and equip it.",
|
||||
new SkillRequirement(Skill.HUNTER, 66));
|
||||
add("Make a Waka Canoe near Edgeville.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 57));
|
||||
add("Teleport to Paddewwa.",
|
||||
new SkillRequirement(Skill.MAGIC, 54),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE));
|
||||
add("Chop some yew logs in Varrock and burn them at the top of the Varrock church.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 60),
|
||||
new SkillRequirement(Skill.FIREMAKING, 60));
|
||||
add("Have the Varrock estate agent decorate your house with Fancy Stone.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 50));
|
||||
add("Collect at least 2 yew roots from the Tree patch in Varrock Palace.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 60),
|
||||
new SkillRequirement(Skill.FARMING, 68));
|
||||
add("Pray at the altar in Varrock palace with Smite active.",
|
||||
new SkillRequirement(Skill.PRAYER, 52));
|
||||
add("Squeeze through the obstacle pipe in Edgeville dungeon.",
|
||||
new SkillRequirement(Skill.AGILITY, 51));
|
||||
|
||||
// ELITE
|
||||
add("Create a super combat potion in Varrock west bank.",
|
||||
new SkillRequirement(Skill.HERBLORE, 90),
|
||||
new QuestRequirement(Quest.DRUIDIC_RITUAL));
|
||||
add("Use Lunar magic to make 20 mahogany planks at the Lumberyard.",
|
||||
new SkillRequirement(Skill.MAGIC, 86),
|
||||
new QuestRequirement(Quest.DREAM_MENTOR));
|
||||
add("Bake a summer pie in the Cooking Guild.",
|
||||
new SkillRequirement(Skill.COOKING, 95));
|
||||
add("Smith and fletch ten rune darts within Varrock.",
|
||||
new SkillRequirement(Skill.SMITHING, 89),
|
||||
new SkillRequirement(Skill.FLETCHING, 81),
|
||||
new QuestRequirement(Quest.THE_TOURIST_TRAP));
|
||||
add("Craft 100 or more earth runes simultaneously.",
|
||||
new SkillRequirement(Skill.RUNECRAFT, 78),
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.CombatLevelRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class WesternDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public WesternDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Catch a Copper Longtail.",
|
||||
new SkillRequirement(Skill.HUNTER, 9));
|
||||
add("Complete a novice game of Pest Control.",
|
||||
new CombatLevelRequirement(40));
|
||||
add("Mine some Iron Ore near Piscatoris.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
add("Claim any Chompy bird hat from Rantz.",
|
||||
new QuestRequirement(Quest.BIG_CHOMPY_BIRD_HUNTING));
|
||||
add("Have Brimstail teleport you to the Essence mine.",
|
||||
new QuestRequirement(Quest.RUNE_MYSTERIES));
|
||||
add("Fletch an Oak shortbow from the Gnome Stronghold.",
|
||||
new SkillRequirement(Skill.FLETCHING, 20));
|
||||
|
||||
// MEDIUM
|
||||
add("Take the agility shortcut from the Grand Tree to Otto's Grotto.",
|
||||
new SkillRequirement(Skill.AGILITY, 37),
|
||||
new QuestRequirement(Quest.TREE_GNOME_VILLAGE),
|
||||
new QuestRequirement(Quest.THE_GRAND_TREE));
|
||||
add("Travel to the Gnome Stronghold by Spirit Tree.",
|
||||
new QuestRequirement(Quest.TREE_GNOME_VILLAGE));
|
||||
add("Trap a Spined Larupia.",
|
||||
new SkillRequirement(Skill.HUNTER, 31));
|
||||
add("Fish some Bass on Ape Atoll.",
|
||||
new SkillRequirement(Skill.FISHING, 46),
|
||||
new QuestRequirement(Quest.MONKEY_MADNESS_I, true));
|
||||
add("Chop and burn some teak logs on Ape Atoll.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 35),
|
||||
new SkillRequirement(Skill.FIREMAKING, 35),
|
||||
new QuestRequirement(Quest.MONKEY_MADNESS_I));
|
||||
add("Complete an intermediate game of Pest Control.",
|
||||
new CombatLevelRequirement(70));
|
||||
add("Travel to the Feldip Hills by Gnome Glider.",
|
||||
new QuestRequirement(Quest.ONE_SMALL_FAVOUR),
|
||||
new QuestRequirement(Quest.THE_GRAND_TREE));
|
||||
add("Claim a Chompy bird hat from Rantz after registering at least 125 kills.",
|
||||
new QuestRequirement(Quest.BIG_CHOMPY_BIRD_HUNTING));
|
||||
add("Travel from Eagles' Peak to the Feldip Hills by Eagle.",
|
||||
new QuestRequirement(Quest.EAGLES_PEAK));
|
||||
add("Make a Chocolate Bomb at the Grand Tree.",
|
||||
new SkillRequirement(Skill.COOKING, 42));
|
||||
add("Complete a delivery for the Gnome Restaurant.",
|
||||
new SkillRequirement(Skill.COOKING, 29));
|
||||
add("Turn your small crystal seed into a Crystal saw.",
|
||||
new QuestRequirement(Quest.THE_EYES_OF_GLOUPHRIE));
|
||||
add("Mine some Gold ore underneath the Grand Tree.",
|
||||
new SkillRequirement(Skill.MINING, 40),
|
||||
new QuestRequirement(Quest.THE_GRAND_TREE));
|
||||
|
||||
// HARD
|
||||
add("Kill an Elf with a Crystal bow.",
|
||||
new SkillRequirement(Skill.RANGED, 70),
|
||||
new SkillRequirement(Skill.AGILITY, 56),
|
||||
new QuestRequirement(Quest.ROVING_ELVES));
|
||||
add("Catch and cook a Monkfish in Piscatoris.",
|
||||
new SkillRequirement(Skill.FISHING, 62),
|
||||
new SkillRequirement(Skill.COOKING, 62),
|
||||
new QuestRequirement(Quest.SWAN_SONG));
|
||||
add("Complete a Veteran game of Pest Control.",
|
||||
new CombatLevelRequirement(100));
|
||||
add("Catch a Dashing Kebbit.",
|
||||
new SkillRequirement(Skill.HUNTER, 69));
|
||||
add("Complete a lap of the Ape Atoll agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 48),
|
||||
new QuestRequirement(Quest.MONKEY_MADNESS_I));
|
||||
add("Chop and burn some Mahogany logs on Ape Atoll.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 50),
|
||||
new SkillRequirement(Skill.FIREMAKING, 50),
|
||||
new QuestRequirement(Quest.MONKEY_MADNESS_I));
|
||||
add("Mine some Adamantite ore in Tirannwn.",
|
||||
new SkillRequirement(Skill.MINING, 70),
|
||||
new QuestRequirement(Quest.REGICIDE));
|
||||
add("Check the health of your Palm tree in Lletya.",
|
||||
new SkillRequirement(Skill.FARMING, 68),
|
||||
new QuestRequirement(Quest.MOURNINGS_END_PART_I, true));
|
||||
add("Claim a Chompy bird hat from Rantz after registering at least 300 kills.",
|
||||
new QuestRequirement(Quest.BIG_CHOMPY_BIRD_HUNTING));
|
||||
add("Build an Isafdar painting in your POH Quest hall.",
|
||||
new SkillRequirement(Skill.CONSTRUCTION, 65),
|
||||
new QuestRequirement(Quest.ROVING_ELVES));
|
||||
add("Kill Zulrah.",
|
||||
new QuestRequirement(Quest.REGICIDE, true));
|
||||
add("Teleport to Ape Atoll.",
|
||||
new SkillRequirement(Skill.MAGIC, 64),
|
||||
new QuestRequirement(Quest.RECIPE_FOR_DISASTER, true));
|
||||
add("Pickpocket a Gnome.",
|
||||
new SkillRequirement(Skill.THIEVING, 75),
|
||||
new QuestRequirement(Quest.TREE_GNOME_VILLAGE));
|
||||
|
||||
// ELITE
|
||||
add("Fletch a Magic Longbow in Tirannwn.",
|
||||
new SkillRequirement(Skill.FLETCHING, 85),
|
||||
new QuestRequirement(Quest.MOURNINGS_END_PART_I));
|
||||
add("Kill the Thermonuclear Smoke devil (Does not require task).",
|
||||
new SkillRequirement(Skill.SLAYER, 93));
|
||||
add("Have Prissy Scilla protect your Magic tree.",
|
||||
new SkillRequirement(Skill.FARMING, 75));
|
||||
add("Use the Elven overpass advanced cliffside shortcut.",
|
||||
new SkillRequirement(Skill.AGILITY, 85),
|
||||
new QuestRequirement(Quest.UNDERGROUND_PASS));
|
||||
add("Claim a Chompy bird hat from Rantz after registering at least 1000 kills.",
|
||||
new QuestRequirement(Quest.BIG_CHOMPY_BIRD_HUNTING));
|
||||
add("Pickpocket an Elf.",
|
||||
new SkillRequirement(Skill.THIEVING, 85),
|
||||
new QuestRequirement(Quest.MOURNINGS_END_PART_I, true));
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Marshall <https://github.com/marshdevs>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.achievementdiary.diaries;
|
||||
|
||||
import net.runelite.api.Quest;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.plugins.achievementdiary.GenericDiaryRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.OrRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.QuestRequirement;
|
||||
import net.runelite.client.plugins.achievementdiary.SkillRequirement;
|
||||
|
||||
public class WildernessDiaryRequirement extends GenericDiaryRequirement
|
||||
{
|
||||
public WildernessDiaryRequirement()
|
||||
{
|
||||
// EASY
|
||||
add("Cast Low Alchemy at the Fountain of Rune.",
|
||||
new SkillRequirement(Skill.MAGIC, 21));
|
||||
add("Kill an Earth Warrior in the Wilderness beneath Edgeville.",
|
||||
new SkillRequirement(Skill.AGILITY, 15));
|
||||
add("Mine some Iron ore in the Wilderness.",
|
||||
new SkillRequirement(Skill.MINING, 15));
|
||||
add("Have the Mage of Zamorak teleport you to the Abyss.",
|
||||
new QuestRequirement(Quest.ENTER_THE_ABYSS));
|
||||
|
||||
// MEDIUM
|
||||
add("Mine some Mithril ore in the wilderness.",
|
||||
new SkillRequirement(Skill.MINING, 55));
|
||||
add("Chop some yew logs from a fallen Ent.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 61));
|
||||
add("Enter the Wilderness Godwars Dungeon.",
|
||||
new OrRequirement(
|
||||
new SkillRequirement(Skill.AGILITY, 60),
|
||||
new SkillRequirement(Skill.STRENGTH, 60)
|
||||
)
|
||||
);
|
||||
add("Complete a lap of the Wilderness Agility course.",
|
||||
new SkillRequirement(Skill.AGILITY, 52));
|
||||
add("Charge an Earth Orb.",
|
||||
new SkillRequirement(Skill.MAGIC, 60));
|
||||
add("Kill a Bloodveld in the Wilderness Godwars Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 50));
|
||||
add("Smith a Golden helmet in the Resource Area.",
|
||||
new SkillRequirement(Skill.SMITHING, 50),
|
||||
new QuestRequirement(Quest.BETWEEN_A_ROCK, true));
|
||||
|
||||
// HARD
|
||||
add("Cast one of the 3 God spells against another player in the Wilderness.",
|
||||
new SkillRequirement(Skill.MAGIC, 60),
|
||||
new QuestRequirement(Quest.THE_MAGE_ARENA));
|
||||
add("Charge an Air Orb.",
|
||||
new SkillRequirement(Skill.MAGIC, 66));
|
||||
add("Catch a Black Salamander in the Wilderness.",
|
||||
new SkillRequirement(Skill.HUNTER, 67));
|
||||
add("Smith an Adamant scimitar in the Resource Area.",
|
||||
new SkillRequirement(Skill.SMITHING, 75));
|
||||
add("Take the agility shortcut from Trollheim into the Wilderness.",
|
||||
new SkillRequirement(Skill.AGILITY, 64),
|
||||
new QuestRequirement(Quest.DEATH_PLATEAU));
|
||||
add("Kill a Spiritual warrior in the Wilderness Godwars Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 68));
|
||||
add("Fish some Raw Lava Eel in the Wilderness.",
|
||||
new SkillRequirement(Skill.FISHING, 53));
|
||||
|
||||
// ELITE
|
||||
add("Teleport to Ghorrock.",
|
||||
new SkillRequirement(Skill.MAGIC, 96),
|
||||
new QuestRequirement(Quest.DESERT_TREASURE));
|
||||
add("Fish and Cook a Dark Crab in the Resource Area.",
|
||||
new SkillRequirement(Skill.FISHING, 85),
|
||||
new SkillRequirement(Skill.COOKING, 90));
|
||||
add("Smith a rune scimitar from scratch in the Resource Area.",
|
||||
new SkillRequirement(Skill.MINING, 85),
|
||||
new SkillRequirement(Skill.SMITHING, 90));
|
||||
add("Steal from the Rogues' chest.",
|
||||
new SkillRequirement(Skill.THIEVING, 84));
|
||||
add("Slay a spiritual mage inside the wilderness Godwars Dungeon.",
|
||||
new SkillRequirement(Skill.SLAYER, 83),
|
||||
new OrRequirement(
|
||||
new SkillRequirement(Skill.AGILITY, 60),
|
||||
new SkillRequirement(Skill.STRENGTH, 60)
|
||||
)
|
||||
);
|
||||
add("Cut and burn some magic logs in the Resource Area.",
|
||||
new SkillRequirement(Skill.WOODCUTTING, 75),
|
||||
new SkillRequirement(Skill.FIREMAKING, 75));
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Alex Kolpa <https://github.com/AlexKolpa>
|
||||
* 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.agility;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.Timer;
|
||||
|
||||
class AgilityArenaTimer extends Timer
|
||||
{
|
||||
AgilityArenaTimer(Plugin plugin, BufferedImage image)
|
||||
{
|
||||
super(1, ChronoUnit.MINUTES, image, plugin);
|
||||
setTooltip("Time left until location changes");
|
||||
}
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cas <https://github.com/casvandongen>
|
||||
* 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.agility;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigTitleSection;
|
||||
import net.runelite.client.config.Title;
|
||||
|
||||
@ConfigGroup("agility")
|
||||
public interface AgilityConfig extends Config
|
||||
{
|
||||
@ConfigTitleSection(
|
||||
keyName = "mainConfig",
|
||||
position = 0,
|
||||
name = "Main Config",
|
||||
description = ""
|
||||
)
|
||||
default Title mainConfig()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeDistanceCap",
|
||||
name = "Remove Distance Cap",
|
||||
description = "This will remove the distance cap on rendering overlays for agility.",
|
||||
warning = "<html><center>Enabling this setting on a low end machine may severely affect your fps." +
|
||||
"<br>Click yes to enable this setting, knowing it might affect performance.</center></html>",
|
||||
position = 0,
|
||||
titleSection = "mainConfig"
|
||||
)
|
||||
default boolean removeDistanceCap()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showCourseClickboxes",
|
||||
name = "Show course Clickboxes",
|
||||
description = "Show agility course obstacle clickboxes",
|
||||
position = 1
|
||||
)
|
||||
default boolean showCourseClickboxes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showLapCount",
|
||||
name = "Show Lap Count",
|
||||
description = "Enable/disable the lap counter",
|
||||
position = 2,
|
||||
titleSection = "mainConfig"
|
||||
)
|
||||
default boolean showLapCount()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lapTimeout",
|
||||
name = "Hide Lap Count",
|
||||
description = "Time in minutes until the lap counter hides/resets",
|
||||
position = 3,
|
||||
titleSection = "mainConfig",
|
||||
hidden = true,
|
||||
unhide = "showLapCount"
|
||||
)
|
||||
default int lapTimeout()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lapsToLevel",
|
||||
name = "Show Laps Until Level",
|
||||
description = "Show number of laps remaining until next level is reached.",
|
||||
position = 4,
|
||||
titleSection = "mainConfig",
|
||||
hidden = true,
|
||||
unhide = "showLapCount"
|
||||
)
|
||||
default boolean lapsToLevel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lapsToGoal",
|
||||
name = "Show Laps Until Goal",
|
||||
description = "Show number of laps remaining until experience tracker goal is reached",
|
||||
position = 5,
|
||||
titleSection = "mainConfig",
|
||||
hidden = true,
|
||||
unhide = "showLapCount"
|
||||
)
|
||||
default boolean lapsToGoal()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "agilityArenaTimer",
|
||||
name = "Agility Arena timer",
|
||||
description = "Configures whether Agility Arena timer is displayed",
|
||||
position = 6,
|
||||
titleSection = "mainConfig"
|
||||
)
|
||||
default boolean showAgilityArenaTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "addLevelsToShortcutOptions",
|
||||
name = "Show Shortcut Agility Reqs",
|
||||
description = "Enable/disable showing shortcut agility level requirements in right-click options",
|
||||
position = 7,
|
||||
titleSection = "mainConfig"
|
||||
)
|
||||
default boolean showShortcutLevel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "miscConfig",
|
||||
position = 8,
|
||||
name = "Misc Config",
|
||||
description = ""
|
||||
)
|
||||
default Title miscConfig()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightMarks",
|
||||
name = "Highlight Marks of Grace",
|
||||
description = "Enable/disable the highlighting of retrievable Marks of Grace",
|
||||
position = 9,
|
||||
titleSection = "miscConfig"
|
||||
)
|
||||
default boolean highlightMarks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightShortcuts",
|
||||
name = "Highlight Agility Shortcuts",
|
||||
description = "Enable/disable the highlighting of Agility shortcuts",
|
||||
position = 10,
|
||||
titleSection = "miscConfig"
|
||||
)
|
||||
default boolean highlightShortcuts()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTrapOverlay",
|
||||
name = "Highlight Traps",
|
||||
description = "Enable/disable the highlighting of traps on Agility courses",
|
||||
position = 11,
|
||||
titleSection = "miscConfig"
|
||||
)
|
||||
default boolean showTrapOverlay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "agilityArenaNotifier",
|
||||
name = "Agility Arena notifier",
|
||||
description = "Notify on ticket location change in Agility Arena",
|
||||
position = 12,
|
||||
titleSection = "miscConfig"
|
||||
)
|
||||
default boolean notifyAgilityArena()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "overlayColor",
|
||||
name = "Global Overlay Color",
|
||||
description = "Color of Agility overlay",
|
||||
position = 13,
|
||||
titleSection = "miscConfig"
|
||||
)
|
||||
default Color getOverlayColor()
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "trapHighlight",
|
||||
name = "Trap Overlay Color",
|
||||
description = "Color of Agility trap overlay",
|
||||
position = 14,
|
||||
titleSection = "miscConfig",
|
||||
hidden = true,
|
||||
unhide = "showTrapOverlay"
|
||||
)
|
||||
default Color getTrapColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "markHighlight",
|
||||
name = "Mark Highlight Color",
|
||||
description = "Color of highlighted Marks of Grace",
|
||||
position = 15,
|
||||
titleSection = "miscConfig",
|
||||
hidden = true,
|
||||
unhide = "highlightMarks"
|
||||
)
|
||||
default Color getMarkColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Cas <https://github.com/casvandongen>
|
||||
* 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.agility;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
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.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
class AgilityOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
private static final Color SHORTCUT_HIGH_LEVEL_COLOR = Color.ORANGE;
|
||||
|
||||
private final Client client;
|
||||
private final AgilityPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private AgilityOverlay(final Client client, final AgilityPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
|
||||
Point mousePosition = client.getMouseCanvasPosition();
|
||||
final List<Tile> marksOfGrace = plugin.getMarksOfGrace();
|
||||
plugin.getObstacles().forEach((object, obstacle) ->
|
||||
{
|
||||
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !plugin.isHighlightShortcuts() ||
|
||||
Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !plugin.isShowTrapOverlay() ||
|
||||
Obstacles.COURSE_OBSTACLE_IDS.contains(object.getId()) && !plugin.isShowCourseClickboxes())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = obstacle.getTile();
|
||||
|
||||
if (tile.getPlane() == client.getPlane() && checkDistance(object.getLocalLocation(), playerLocation))
|
||||
{
|
||||
// This assumes that the obstacle is not clickable.
|
||||
if (Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()))
|
||||
{
|
||||
Polygon polygon = object.getCanvasTilePoly();
|
||||
if (polygon != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, polygon, plugin.getTrapColor());
|
||||
}
|
||||
return;
|
||||
}
|
||||
Shape objectClickbox = object.getClickbox();
|
||||
if (objectClickbox != null)
|
||||
{
|
||||
AgilityShortcut agilityShortcut = obstacle.getShortcut();
|
||||
Color configColor = agilityShortcut == null || agilityShortcut.getLevel() <= plugin.getAgilityLevel() ? plugin.getOverlayColor() : SHORTCUT_HIGH_LEVEL_COLOR;
|
||||
if (plugin.isHighlightMarks() && !marksOfGrace.isEmpty())
|
||||
{
|
||||
configColor = plugin.getMarkColor();
|
||||
}
|
||||
|
||||
OverlayUtil.renderClickBox(graphics, mousePosition, objectClickbox, configColor);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (plugin.isHighlightMarks() && !marksOfGrace.isEmpty())
|
||||
{
|
||||
for (Tile markOfGraceTile : marksOfGrace)
|
||||
{
|
||||
if (markOfGraceTile.getPlane() == client.getPlane() && markOfGraceTile.getItemLayer() != null
|
||||
&& checkDistance(markOfGraceTile.getLocalLocation(), playerLocation))
|
||||
{
|
||||
final Polygon poly = markOfGraceTile.getItemLayer().getCanvasTilePoly();
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OverlayUtil.renderPolygon(graphics, poly, plugin.getMarkColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean checkDistance(LocalPoint localPoint, LocalPoint playerPoint)
|
||||
{
|
||||
if (plugin.isRemoveDistanceCap())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return localPoint.distanceTo(playerPoint) < MAX_DISTANCE;
|
||||
}
|
||||
}
|
||||
@@ -1,569 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.agility;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemID;
|
||||
import static net.runelite.api.ItemID.AGILITY_ARENA_TICKET;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Skill;
|
||||
import static net.runelite.api.Skill.AGILITY;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileItem;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.BeforeRender;
|
||||
import net.runelite.api.events.DecorativeObjectChanged;
|
||||
import net.runelite.api.events.DecorativeObjectDespawned;
|
||||
import net.runelite.api.events.DecorativeObjectSpawned;
|
||||
import net.runelite.api.events.GameObjectChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GroundObjectChanged;
|
||||
import net.runelite.api.events.GroundObjectDespawned;
|
||||
import net.runelite.api.events.GroundObjectSpawned;
|
||||
import net.runelite.api.events.ItemDespawned;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.api.events.MenuOpened;
|
||||
import net.runelite.api.events.StatChanged;
|
||||
import net.runelite.api.events.WallObjectChanged;
|
||||
import net.runelite.api.events.WallObjectDespawned;
|
||||
import net.runelite.api.events.WallObjectSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Agility",
|
||||
description = "Show helpful information about agility courses and obstacles",
|
||||
tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"},
|
||||
type = PluginType.SKILLING
|
||||
)
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class AgilityPlugin extends Plugin
|
||||
{
|
||||
private static final int AGILITY_ARENA_REGION_ID = 11157;
|
||||
private static final Object MENU_SUBS = new Object();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Map<TileObject, Obstacle> obstacles = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<Tile> marksOfGrace = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AgilityOverlay agilityOverlay;
|
||||
|
||||
@Inject
|
||||
private LapCounterOverlay lapCounterOverlay;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private AgilityConfig config;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private AgilitySession session;
|
||||
|
||||
private int lastAgilityXp;
|
||||
private WorldPoint lastArenaTicketPosition;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int agilityLevel;
|
||||
|
||||
// Config values
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean removeDistanceCap;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showCourseClickboxes;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showLapCount;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int lapTimeout;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean lapsToLevel;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean lapsToGoal;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color overlayColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean highlightMarks;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color markColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean highlightShortcuts;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showTrapOverlay;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color trapColor;
|
||||
private boolean notifyAgilityArena;
|
||||
private boolean showAgilityArenaTimer;
|
||||
|
||||
@Provides
|
||||
AgilityConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AgilityConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
if (config.showShortcutLevel())
|
||||
{
|
||||
addMenuSubscriptions();
|
||||
}
|
||||
|
||||
overlayManager.add(agilityOverlay);
|
||||
overlayManager.add(lapCounterOverlay);
|
||||
agilityLevel = client.getBoostedSkillLevel(Skill.AGILITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
eventBus.unregister(MENU_SUBS);
|
||||
|
||||
overlayManager.remove(agilityOverlay);
|
||||
overlayManager.remove(lapCounterOverlay);
|
||||
marksOfGrace.clear();
|
||||
obstacles.clear();
|
||||
session = null;
|
||||
agilityLevel = 0;
|
||||
}
|
||||
|
||||
private void addMenuSubscriptions()
|
||||
{
|
||||
eventBus.subscribe(BeforeRender.class, MENU_SUBS, this::onBeforeRender);
|
||||
eventBus.subscribe(MenuOpened.class, MENU_SUBS, this::onMenuOpened);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
switch (event.getGameState())
|
||||
{
|
||||
case HOPPING:
|
||||
case LOGIN_SCREEN:
|
||||
session = null;
|
||||
lastArenaTicketPosition = null;
|
||||
removeAgilityArenaTimer();
|
||||
break;
|
||||
case LOADING:
|
||||
marksOfGrace.clear();
|
||||
obstacles.clear();
|
||||
break;
|
||||
case LOGGED_IN:
|
||||
if (!isInAgilityArena())
|
||||
{
|
||||
lastArenaTicketPosition = null;
|
||||
removeAgilityArenaTimer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("agility"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ("addLevelsToShortcutOptions".equals(event.getKey()))
|
||||
{
|
||||
if (config.showShortcutLevel())
|
||||
{
|
||||
addMenuSubscriptions();
|
||||
}
|
||||
else
|
||||
{
|
||||
eventBus.unregister(MENU_SUBS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
updateConfig();
|
||||
|
||||
if (!this.showAgilityArenaTimer)
|
||||
{
|
||||
removeAgilityArenaTimer();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.removeDistanceCap = config.removeDistanceCap();
|
||||
this.showCourseClickboxes = config.showCourseClickboxes();
|
||||
this.showLapCount = config.showLapCount();
|
||||
this.lapTimeout = config.lapTimeout();
|
||||
this.lapsToLevel = config.lapsToLevel();
|
||||
this.lapsToGoal = config.lapsToGoal();
|
||||
this.overlayColor = config.getOverlayColor();
|
||||
this.highlightMarks = config.highlightMarks();
|
||||
this.markColor = config.getMarkColor();
|
||||
this.highlightShortcuts = config.highlightShortcuts();
|
||||
this.showTrapOverlay = config.showTrapOverlay();
|
||||
this.trapColor = config.getTrapColor();
|
||||
this.notifyAgilityArena = config.notifyAgilityArena();
|
||||
this.showAgilityArenaTimer = config.showAgilityArenaTimer();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatChanged(StatChanged statChanged)
|
||||
{
|
||||
if (statChanged.getSkill() != AGILITY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
agilityLevel = statChanged.getBoostedLevel();
|
||||
|
||||
if (!this.showLapCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine how much EXP was actually gained
|
||||
int agilityXp = client.getSkillExperience(AGILITY);
|
||||
int skillGained = agilityXp - lastAgilityXp;
|
||||
lastAgilityXp = agilityXp;
|
||||
|
||||
// Get course
|
||||
Courses course = Courses.getCourse(client.getLocalPlayer().getWorldLocation().getRegionID());
|
||||
if (course == null
|
||||
|| (course.getCourseEndWorldPoints().length == 0
|
||||
? Math.abs(course.getLastObstacleXp() - skillGained) > 1
|
||||
: Arrays.stream(course.getCourseEndWorldPoints()).noneMatch(wp -> wp.equals(client.getLocalPlayer().getWorldLocation()))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (session != null && session.getCourse() == course)
|
||||
{
|
||||
session.incrementLapCount(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
session = new AgilitySession(course);
|
||||
// New course found, reset lap count and set new course
|
||||
session.resetLapCount();
|
||||
session.incrementLapCount(client);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
if (obstacles.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final TileItem item = itemSpawned.getItem();
|
||||
final Tile tile = itemSpawned.getTile();
|
||||
|
||||
if (item.getId() == ItemID.MARK_OF_GRACE)
|
||||
{
|
||||
marksOfGrace.add(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onItemDespawned(ItemDespawned itemDespawned)
|
||||
{
|
||||
final Tile tile = itemDespawned.getTile();
|
||||
marksOfGrace.remove(tile);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameTick(GameTick tick)
|
||||
{
|
||||
if (isInAgilityArena())
|
||||
{
|
||||
// Hint arrow has no plane, and always returns the current plane
|
||||
WorldPoint newTicketPosition = client.getHintArrowPoint();
|
||||
WorldPoint oldTickPosition = lastArenaTicketPosition;
|
||||
|
||||
lastArenaTicketPosition = newTicketPosition;
|
||||
|
||||
if (oldTickPosition != null && newTicketPosition != null
|
||||
&& (oldTickPosition.getX() != newTicketPosition.getX() || oldTickPosition.getY() != newTicketPosition.getY()))
|
||||
{
|
||||
log.debug("Ticked position moved from {} to {}", oldTickPosition, newTicketPosition);
|
||||
|
||||
if (this.notifyAgilityArena)
|
||||
{
|
||||
notifier.notify("Ticket location changed");
|
||||
}
|
||||
|
||||
if (this.showAgilityArenaTimer)
|
||||
{
|
||||
showNewAgilityArenaTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInAgilityArena()
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
if (local == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldPoint location = local.getWorldLocation();
|
||||
return location.getRegionID() == AGILITY_ARENA_REGION_ID;
|
||||
}
|
||||
|
||||
private void removeAgilityArenaTimer()
|
||||
{
|
||||
infoBoxManager.removeIf(infoBox -> infoBox instanceof AgilityArenaTimer);
|
||||
}
|
||||
|
||||
private void showNewAgilityArenaTimer()
|
||||
{
|
||||
removeAgilityArenaTimer();
|
||||
infoBoxManager.addInfoBox(new AgilityArenaTimer(this, itemManager.getImage(AGILITY_ARENA_TICKET)));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getGameObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectChanged(GameObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getGameObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getGameObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGroundObjectSpawned(GroundObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getGroundObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGroundObjectChanged(GroundObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getGroundObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGroundObjectDespawned(GroundObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getGroundObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWallObjectSpawned(WallObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getWallObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWallObjectChanged(WallObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getWallObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWallObjectDespawned(WallObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getWallObject(), null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onDecorativeObjectSpawned(DecorativeObjectSpawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), null, event.getDecorativeObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onDecorativeObjectChanged(DecorativeObjectChanged event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getPrevious(), event.getDecorativeObject());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onDecorativeObjectDespawned(DecorativeObjectDespawned event)
|
||||
{
|
||||
onTileObject(event.getTile(), event.getDecorativeObject(), null);
|
||||
}
|
||||
|
||||
private void onTileObject(Tile tile, TileObject oldObject, TileObject newObject)
|
||||
{
|
||||
obstacles.remove(oldObject);
|
||||
|
||||
if (newObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) ||
|
||||
(Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId())
|
||||
&& Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID())))
|
||||
{
|
||||
obstacles.put(newObject, new Obstacle(tile, null));
|
||||
}
|
||||
|
||||
if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(newObject.getId()))
|
||||
{
|
||||
AgilityShortcut closestShortcut = null;
|
||||
int distance = -1;
|
||||
|
||||
// Find the closest shortcut to this object
|
||||
for (AgilityShortcut shortcut : Obstacles.SHORTCUT_OBSTACLE_IDS.get(newObject.getId()))
|
||||
{
|
||||
if (shortcut.getWorldLocation() == null)
|
||||
{
|
||||
closestShortcut = shortcut;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int newDistance = shortcut.getWorldLocation().distanceTo2D(newObject.getWorldLocation());
|
||||
if (closestShortcut == null || newDistance < distance)
|
||||
{
|
||||
closestShortcut = shortcut;
|
||||
distance = newDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestShortcut != null)
|
||||
{
|
||||
obstacles.put(newObject, new Obstacle(tile, closestShortcut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onBeforeRender(BeforeRender event)
|
||||
{
|
||||
if (client.isMenuOpen() || client.getMenuOptionCount() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final MenuEntry entry = client.getLeftClickMenuEntry();
|
||||
if (checkAndModify(entry))
|
||||
{
|
||||
client.setLeftClickMenuEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMenuOpened(MenuOpened event)
|
||||
{
|
||||
boolean changed = false;
|
||||
for (MenuEntry entry : event.getMenuEntries())
|
||||
{
|
||||
changed |= checkAndModify(entry);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
event.setModified();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAndModify(MenuEntry old)
|
||||
{
|
||||
//Guarding against non-first option because agility shortcuts are always that type of event.
|
||||
if (old.getOpcode() != MenuOpcode.GAME_OBJECT_FIRST_OPTION.getId())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Obstacle nearbyObstacle : getObstacles().values())
|
||||
{
|
||||
AgilityShortcut shortcut = nearbyObstacle.getShortcut();
|
||||
if (shortcut != null && Ints.contains(shortcut.getObstacleIds(), old.getIdentifier()))
|
||||
{
|
||||
final int reqLevel = shortcut.getLevel();
|
||||
final String requirementText = ColorUtil.getLevelColorString(reqLevel, getAgilityLevel()) + " (level-" + reqLevel + ")";
|
||||
|
||||
old.setTarget(old.getTarget() + requirementText);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* 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.agility;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.VarPlayer;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
class AgilitySession
|
||||
{
|
||||
private final Courses course;
|
||||
private Instant lastLapCompleted;
|
||||
private int totalLaps;
|
||||
private int lapsTillLevel;
|
||||
private int lapsTillGoal;
|
||||
|
||||
AgilitySession(final Courses course)
|
||||
{
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
void incrementLapCount(Client client)
|
||||
{
|
||||
lastLapCompleted = Instant.now();
|
||||
++totalLaps;
|
||||
|
||||
int currentExp = client.getSkillExperience(Skill.AGILITY);
|
||||
int nextLevel = client.getRealSkillLevel(Skill.AGILITY) + 1;
|
||||
|
||||
int remainingXp;
|
||||
do
|
||||
{
|
||||
remainingXp = nextLevel <= Experience.MAX_VIRT_LEVEL ? Experience.getXpForLevel(nextLevel) - currentExp : 0;
|
||||
nextLevel++;
|
||||
} while (remainingXp < 0);
|
||||
|
||||
lapsTillLevel = remainingXp > 0 ? (int) Math.ceil(remainingXp / course.getTotalXp()) : 0;
|
||||
int goalRemainingXp = client.getVar(VarPlayer.AGILITY_GOAL_END) - currentExp;
|
||||
lapsTillGoal = goalRemainingXp > 0 ? (int) Math.ceil(goalRemainingXp / course.getTotalXp()) : 0;
|
||||
}
|
||||
|
||||
void resetLapCount()
|
||||
{
|
||||
totalLaps = 0;
|
||||
lapsTillLevel = 0;
|
||||
lapsTillGoal = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* 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.agility;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
enum Courses
|
||||
{
|
||||
GNOME(86.5, 46, 9781),
|
||||
DRAYNOR(120.0, 79, 12338),
|
||||
AL_KHARID(180.0, 30, 13105, new WorldPoint(3299, 3194, 0)),
|
||||
PYRAMID(722.0, 300, 13356, new WorldPoint(3364, 2830, 0)),
|
||||
VARROCK(238.0, 125, 12853),
|
||||
PENGUIN(540.0, 65, 10559),
|
||||
BARBARIAN(139.5, 60, 10039),
|
||||
CANIFIS(240.0, 175, 13878),
|
||||
APE_ATOLL(580.0, 300, 11050),
|
||||
FALADOR(440, 180, 12084),
|
||||
WILDERNESS(571.0, 499, 11837),
|
||||
WEREWOLF(730.0, 380, 14234),
|
||||
SEERS(570.0, 435, 10806),
|
||||
POLLNIVNEACH(890.0, 540, 13358),
|
||||
RELLEKA(780.0, 475, 10553),
|
||||
PRIFDDINAS(1337.0, 1037, 12895),
|
||||
ARDOUGNE(793.0, 529, 10547);
|
||||
|
||||
private final static Map<Integer, Courses> coursesByRegion;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final double totalXp;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final int lastObstacleXp;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final int regionId;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WorldPoint[] courseEndWorldPoints;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, Courses> builder = new ImmutableMap.Builder<>();
|
||||
|
||||
for (Courses course : values())
|
||||
{
|
||||
builder.put(course.regionId, course);
|
||||
}
|
||||
|
||||
coursesByRegion = builder.build();
|
||||
}
|
||||
|
||||
Courses(double totalXp, int lastObstacleXp, int regionId, WorldPoint... courseEndWorldPoints)
|
||||
{
|
||||
this.totalXp = totalXp;
|
||||
this.lastObstacleXp = lastObstacleXp;
|
||||
this.regionId = regionId;
|
||||
this.courseEndWorldPoints = courseEndWorldPoints;
|
||||
}
|
||||
|
||||
static Courses getCourse(int regionId)
|
||||
{
|
||||
return coursesByRegion.get(regionId);
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* 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.agility;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
|
||||
@Singleton
|
||||
class LapCounterOverlay extends Overlay
|
||||
{
|
||||
private final AgilityPlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private LapCounterOverlay(final AgilityPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
this.plugin = plugin;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Agility overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
AgilitySession session = plugin.getSession();
|
||||
|
||||
if (!plugin.isShowLapCount() ||
|
||||
session == null ||
|
||||
session.getLastLapCompleted() == null ||
|
||||
session.getCourse() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Duration lapTimeout = Duration.ofMinutes(plugin.getLapTimeout());
|
||||
Duration sinceLap = Duration.between(session.getLastLapCompleted(), Instant.now());
|
||||
|
||||
if (sinceLap.compareTo(lapTimeout) >= 0)
|
||||
{
|
||||
// timeout session
|
||||
session.setLastLapCompleted(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
tableComponent.addRow("Total Laps:", Integer.toString(session.getTotalLaps()));
|
||||
|
||||
if (plugin.isLapsToLevel() && session.getLapsTillLevel() > 0)
|
||||
{
|
||||
tableComponent.addRow("Laps until level:", Integer.toString(session.getLapsTillLevel()));
|
||||
}
|
||||
|
||||
if (plugin.isLapsToGoal() && session.getLapsTillGoal() > 0)
|
||||
{
|
||||
tableComponent.addRow("Laps until goal:", Integer.toString(session.getLapsTillGoal()));
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, MrGroggle
|
||||
* 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 HOLDER 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.agility;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Value;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
|
||||
@Value
|
||||
@AllArgsConstructor
|
||||
class Obstacle
|
||||
{
|
||||
private final Tile tile;
|
||||
@Nullable
|
||||
private final AgilityShortcut shortcut;
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* 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.agility;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import static net.runelite.api.NullObjectID.*;
|
||||
import static net.runelite.api.ObjectID.*;
|
||||
import net.runelite.client.game.AgilityShortcut;
|
||||
|
||||
class Obstacles
|
||||
{
|
||||
static final Set<Integer> COURSE_OBSTACLE_IDS = ImmutableSet.of(
|
||||
// Gnome
|
||||
OBSTACLE_NET_23134, TREE_BRANCH_23559, TREE_BRANCH_23560, OBSTACLE_NET_23135, OBSTACLE_PIPE_23138,
|
||||
OBSTACLE_PIPE_23139, LOG_BALANCE_23145, BALANCING_ROPE_23557,
|
||||
// Brimhaven
|
||||
PLANK_3572, PLANK_3571, PLANK_3570, ROPE_SWING, PILLAR_3578, LOW_WALL, LOG_BALANCE, LOG_BALANCE_3557,
|
||||
BALANCING_LEDGE_3561, BALANCING_LEDGE, MONKEY_BARS_3564, BALANCING_ROPE, HAND_HOLDS_3583,
|
||||
// Draynor
|
||||
ROUGH_WALL, TIGHTROPE, TIGHTROPE_11406, NARROW_WALL, WALL_11630, GAP_11631, CRATE_11632, STILE_7527,
|
||||
// Al-Kharid
|
||||
ROUGH_WALL_11633, TIGHTROPE_14398, CABLE, ZIP_LINE_14403, TROPICAL_TREE_14404, ROOF_TOP_BEAMS,
|
||||
TIGHTROPE_14409, GAP_14399,
|
||||
// Pyramid
|
||||
STAIRS_10857, LOW_WALL_10865, LEDGE_10860, PLANK_10868, GAP_10882, LEDGE_10886, STAIRS_10857, GAP_10884,
|
||||
GAP_10859, GAP_10861, LOW_WALL_10865, GAP_10859, LEDGE_10888, PLANK_10868, CLIMBING_ROCKS_10851, DOORWAY_10855,
|
||||
// Varrock
|
||||
ROUGH_WALL_14412, CLOTHES_LINE, GAP_14414, WALL_14832, GAP_14833, GAP_14834, GAP_14835, LEDGE_14836, EDGE,
|
||||
// Penguin
|
||||
STEPPING_STONE_21120, STEPPING_STONE_21126, STEPPING_STONE_21128, STEPPING_STONE_21129,
|
||||
STEPPING_STONE_21130, STEPPING_STONE_21131, STEPPING_STONE_21132, STEPPING_STONE_21133,
|
||||
ICICLES, ICE, ICE_21149, ICE_21150, ICE_21151, ICE_21152, ICE_21153, ICE_21154, ICE_21155, ICE_21156,
|
||||
// Barbarian
|
||||
ROPESWING_23131, LOG_BALANCE_23144, OBSTACLE_NET_20211, BALANCING_LEDGE_23547, LADDER_16682, CRUMBLING_WALL_1948,
|
||||
// Canifis
|
||||
TALL_TREE_14843, GAP_14844, GAP_14845, GAP_14848, GAP_14846, POLEVAULT, GAP_14847, GAP_14897,
|
||||
// Ape atoll
|
||||
STEPPING_STONE_15412, TROPICAL_TREE_15414, MONKEYBARS_15417, SKULL_SLOPE_15483, ROPE_15487, TROPICAL_TREE_16062,
|
||||
// Falador
|
||||
ROUGH_WALL_14898, TIGHTROPE_14899, HAND_HOLDS_14901, GAP_14903, GAP_14904, TIGHTROPE_14905,
|
||||
TIGHTROPE_14911, GAP_14919, LEDGE_14920, LEDGE_14921, LEDGE_14922, LEDGE_14923, LEDGE_14924, EDGE_14925,
|
||||
// Wilderness
|
||||
OBSTACLE_PIPE_23137, ROPESWING_23132, STEPPING_STONE_23556, LOG_BALANCE_23542, ROCKS_23640,
|
||||
// Seers
|
||||
WALL_14927, GAP_14928, TIGHTROPE_14932, GAP_14929, GAP_14930, EDGE_14931,
|
||||
// Dorgesh-Kaan
|
||||
CABLE_22569, CABLE_22572, LADDER_22564, JUTTING_WALL_22552, TUNNEL_22557, PYLON_22664,
|
||||
CONSOLE, BOILER_22635, STAIRS_22650, STAIRS_22651, STAIRS_22609, STAIRS_22608,
|
||||
// Pollniveach
|
||||
BASKET_14935, MARKET_STALL_14936, BANNER_14937, GAP_14938, TREE_14939, ROUGH_WALL_14940,
|
||||
MONKEYBARS, TREE_14944, DRYING_LINE,
|
||||
// Rellaka
|
||||
ROUGH_WALL_14946, GAP_14947, TIGHTROPE_14987, GAP_14990, GAP_14991, TIGHTROPE_14992, PILE_OF_FISH,
|
||||
// Ardougne
|
||||
WOODEN_BEAMS, GAP_15609, PLANK_26635, GAP_15610, GAP_15611, STEEP_ROOF, GAP_15612,
|
||||
// Meiyerditch
|
||||
NULL_12945, ROCK_17958, ROCK_17959, ROCK_17960, BOAT_17961, NULL_18122, NULL_18124, WALL_RUBBLE,
|
||||
WALL_RUBBLE_18038, FLOORBOARDS, FLOORBOARDS_18071, FLOORBOARDS_18072, FLOORBOARDS_18073, NULL_18129, NULL_18130,
|
||||
WALL_18078, NULL_18132, NULL_18133, NULL_18083, TUNNEL_18085, SHELF_18086, SHELF_18087, WALL_18088,
|
||||
FLOORBOARDS_18089, FLOORBOARDS_18090, DOOR_18091, FLOORBOARDS_18093, FLOORBOARDS_18094, SHELF_18095,
|
||||
SHELF_18096, FLOORBOARDS_18097, FLOORBOARDS_18098, WASHING_LINE_18099, WASHING_LINE_18100,
|
||||
NULL_18135, NULL_18136, SHELF_18105, SHELF_18106, SHELF_18107, SHELF_18108, FLOORBOARDS_18109,
|
||||
FLOORBOARDS_18110, FLOORBOARDS_18112, FLOORBOARDS_18111, FLOORBOARDS_18114, FLOORBOARDS_18113,
|
||||
NULL_18116, FLOORBOARDS_18117, FLOORBOARDS_18118, STAIRS_DOWN, WALL_17980,
|
||||
// Werewolf
|
||||
STEPPING_STONE_11643, HURDLE, HURDLE_11639, HURDLE_11640, PIPE_11657, SKULL_SLOPE, ZIP_LINE,
|
||||
ZIP_LINE_11645, ZIP_LINE_11646,
|
||||
// Prifddinas
|
||||
LADDER_36221, TIGHTROPE_36225, CHIMNEY_36227, ROOF_EDGE, DARK_HOLE_36229, LADDER_36231, LADDER_36232,
|
||||
ROPE_BRIDGE_36233, TIGHTROPE_36234, ROPE_BRIDGE_36235, TIGHTROPE_36236, TIGHTROPE_36237, DARK_HOLE_36238,
|
||||
// Prifddinas portals
|
||||
NULL_36241, NULL_36242, NULL_36243, NULL_36244, NULL_36245, NULL_36246
|
||||
);
|
||||
|
||||
static final Multimap<Integer, AgilityShortcut> SHORTCUT_OBSTACLE_IDS;
|
||||
|
||||
static final Set<Integer> TRAP_OBSTACLE_IDS = ImmutableSet.of(
|
||||
// Agility pyramid
|
||||
NULL_3550, NULL_10872, NULL_10873
|
||||
);
|
||||
|
||||
static final List<Integer> TRAP_OBSTACLE_REGIONS = ImmutableList.of(12105, 13356);
|
||||
|
||||
static
|
||||
{
|
||||
final ImmutableMultimap.Builder<Integer, AgilityShortcut> builder = ImmutableMultimap.builder();
|
||||
for (final AgilityShortcut item : AgilityShortcut.values())
|
||||
{
|
||||
for (int obstacle : item.getObstacleIds())
|
||||
{
|
||||
builder.put(obstacle, item);
|
||||
}
|
||||
}
|
||||
SHORTCUT_OBSTACLE_IDS = builder.build();
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
@Singleton
|
||||
class AlchemicalHydra
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
enum AttackStyle
|
||||
{
|
||||
MAGIC(ProjectileID.HYDRA_MAGIC, Prayer.PROTECT_FROM_MAGIC, SpriteID.PRAYER_PROTECT_FROM_MAGIC),
|
||||
RANGED(ProjectileID.HYDRA_RANGED, Prayer.PROTECT_FROM_MISSILES, SpriteID.PRAYER_PROTECT_FROM_MISSILES);
|
||||
|
||||
private final int projectileID;
|
||||
private final Prayer prayer;
|
||||
private final int spriteID;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private BufferedImage image;
|
||||
|
||||
BufferedImage getImage(SpriteManager spriteManager)
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
BufferedImage tmp = spriteManager.getSprite(spriteID, 0);
|
||||
image = tmp == null ? null : ImageUtil.resizeImage(tmp, AlchemicalHydraOverlay.IMGSIZE, AlchemicalHydraOverlay.IMGSIZE);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
private final NPC npc;
|
||||
|
||||
private AlchemicalHydraPhase phase = AlchemicalHydraPhase.ONE;
|
||||
|
||||
private int attackCount = 0;
|
||||
private int nextSwitch = phase.getAttacksPerSwitch();
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private int nextSpecial = 3;
|
||||
|
||||
private AttackStyle nextAttack = AttackStyle.MAGIC;
|
||||
private AttackStyle lastAttack = AttackStyle.MAGIC;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean weakened = false;
|
||||
|
||||
void changePhase(AlchemicalHydraPhase newPhase)
|
||||
{
|
||||
phase = newPhase;
|
||||
nextSpecial = 3;
|
||||
attackCount = 0;
|
||||
weakened = false;
|
||||
|
||||
if (newPhase == AlchemicalHydraPhase.FOUR)
|
||||
{
|
||||
weakened = true;
|
||||
switchStyles();
|
||||
nextSwitch = phase.getAttacksPerSwitch();
|
||||
}
|
||||
}
|
||||
|
||||
private void switchStyles()
|
||||
{
|
||||
nextAttack = lastAttack == AlchemicalHydra.AttackStyle.MAGIC
|
||||
? AlchemicalHydra.AttackStyle.RANGED
|
||||
: AlchemicalHydra.AttackStyle.MAGIC;
|
||||
}
|
||||
|
||||
void handleAttack(int id)
|
||||
{
|
||||
if (id != nextAttack.getProjectileID())
|
||||
{
|
||||
if (id == lastAttack.getProjectileID())
|
||||
{
|
||||
// If the current attack isn't what was expected and we accidentally counted 1 too much
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current attack isn't what was expected and we should have switched prayers
|
||||
switchStyles();
|
||||
nextSwitch = phase.getAttacksPerSwitch() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextSwitch--;
|
||||
}
|
||||
|
||||
lastAttack = nextAttack;
|
||||
attackCount++;
|
||||
|
||||
if (nextSwitch <= 0)
|
||||
{
|
||||
switchStyles();
|
||||
nextSwitch = phase.getAttacksPerSwitch();
|
||||
}
|
||||
}
|
||||
|
||||
int getNextSpecialRelative()
|
||||
{
|
||||
return nextSpecial - attackCount;
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Alpha;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigSection;
|
||||
|
||||
@ConfigGroup("betterHydra")
|
||||
public interface AlchemicalHydraConfig extends Config
|
||||
{
|
||||
@ConfigSection(
|
||||
keyName = "features",
|
||||
name = "Features",
|
||||
description = "Feathers. Jk, features",
|
||||
position = 0
|
||||
)
|
||||
default boolean features()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "counting",
|
||||
name = "Prayer helper",
|
||||
description = "Basically everything this plugin is known for. Also has attacks between specs and poison overlay. Shouldn't NOT use this tbh",
|
||||
position = 1,
|
||||
section = "features"
|
||||
)
|
||||
default boolean counting()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fountain",
|
||||
name = "Fountain helper",
|
||||
description = "Indicates if hydra is on a fountain",
|
||||
position = 2,
|
||||
section = "features"
|
||||
)
|
||||
default boolean fountain()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "stun",
|
||||
name = "Stun timer",
|
||||
description = "Shows when you can walk in fire phase",
|
||||
position = 3,
|
||||
section = "features"
|
||||
)
|
||||
default boolean stun()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigSection(
|
||||
keyName = "colours",
|
||||
name = "Colours",
|
||||
description = "colours...",
|
||||
position = 2
|
||||
)
|
||||
default boolean colours()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "safeCol",
|
||||
name = "Safe colour",
|
||||
description = "Colour overlay will be when there's >2 attacks left",
|
||||
position = 1,
|
||||
section = "colours"
|
||||
)
|
||||
default Color safeCol()
|
||||
{
|
||||
return new Color(0, 156, 0, 156);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "medCol",
|
||||
name = "Medium colour",
|
||||
description = "Colour overlay will be when a input is coming up",
|
||||
position = 2,
|
||||
section = "colours"
|
||||
)
|
||||
default Color medCol()
|
||||
{
|
||||
return new Color(200, 156, 0, 156);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "badCol",
|
||||
name = "Bad colour",
|
||||
description = "Colour overlay will be when you have to do something NOW",
|
||||
position = 3,
|
||||
section = "colours"
|
||||
)
|
||||
default Color badCol()
|
||||
{
|
||||
return new Color(156, 0, 0, 156);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "poisonBorderCol",
|
||||
name = "Poison border colour",
|
||||
description = "Colour the edges of the area highlighted by poison special will be",
|
||||
position = 4,
|
||||
section = "colours"
|
||||
)
|
||||
default Color poisonBorderCol()
|
||||
{
|
||||
return new Color(255, 0, 0, 100);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "poisonCol",
|
||||
name = "Poison colour",
|
||||
description = "Colour the fill of the area highlighted by poison special will be",
|
||||
position = 5,
|
||||
section = "colours"
|
||||
)
|
||||
default Color poisonCol()
|
||||
{
|
||||
return new Color(255, 0, 0, 50);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "fountainColA",
|
||||
name = "Fountain colour (not on top)",
|
||||
description = "Fountain colour (not on top)",
|
||||
position = 6,
|
||||
section = "colours"
|
||||
)
|
||||
default Color fountainColA()
|
||||
{
|
||||
return new Color(255, 0, 0, 100);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "fountainColB",
|
||||
name = "Fountain colour (on top)",
|
||||
description = "Fountain colour (on top)",
|
||||
position = 7,
|
||||
section = "colours"
|
||||
)
|
||||
default Color fountainColB()
|
||||
{
|
||||
return new Color(0, 255, 0, 100);
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.IndexDataBase;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.Sprite;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Singleton
|
||||
class AlchemicalHydraOverlay extends Overlay
|
||||
{
|
||||
static final int IMGSIZE = 36;
|
||||
|
||||
private final AlchemicalHydraPlugin plugin;
|
||||
private final Client client;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
private BufferedImage stunImg;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color safeCol;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color medCol;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color badCol;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private int stunTicks;
|
||||
|
||||
@Inject
|
||||
AlchemicalHydraOverlay(final AlchemicalHydraPlugin plugin, final Client client, final SpriteManager spriteManager)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
this.spriteManager = spriteManager;
|
||||
this.setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
panelComponent.setOrientation(ComponentOrientation.VERTICAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics2D)
|
||||
{
|
||||
final AlchemicalHydra hydra = plugin.getHydra();
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (hydra == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// First add stunned thing if needed
|
||||
if (stunTicks > 0)
|
||||
{
|
||||
addStunOverlay();
|
||||
}
|
||||
|
||||
|
||||
if (plugin.isCounting())
|
||||
{
|
||||
// Add spec box second, to keep it above pray
|
||||
addSpecOverlay(hydra);
|
||||
|
||||
// Finally add prayer box
|
||||
addPrayOverlay(hydra);
|
||||
}
|
||||
|
||||
panelComponent.setPreferredSize(new Dimension(40, 0));
|
||||
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
|
||||
|
||||
return panelComponent.render(graphics2D);
|
||||
}
|
||||
|
||||
private void addStunOverlay()
|
||||
{
|
||||
final InfoBoxComponent stunComponent = new InfoBoxComponent();
|
||||
|
||||
stunComponent.setBackgroundColor(badCol);
|
||||
stunComponent.setImage(getStunImg());
|
||||
stunComponent.setText(" " + stunTicks);
|
||||
stunComponent.setPreferredSize(new Dimension(40, 40));
|
||||
|
||||
panelComponent.getChildren().add(stunComponent);
|
||||
}
|
||||
|
||||
private void addSpecOverlay(final AlchemicalHydra hydra)
|
||||
{
|
||||
final AlchemicalHydraPhase phase = hydra.getPhase();
|
||||
final int nextSpec = hydra.getNextSpecialRelative();
|
||||
|
||||
if (nextSpec > 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final InfoBoxComponent specComponent = new InfoBoxComponent();
|
||||
|
||||
if (nextSpec == 0)
|
||||
{
|
||||
specComponent.setBackgroundColor(badCol);
|
||||
}
|
||||
else if (nextSpec == 1)
|
||||
{
|
||||
specComponent.setBackgroundColor(medCol);
|
||||
}
|
||||
|
||||
specComponent.setImage(phase.getSpecImage(spriteManager));
|
||||
specComponent.setText(" " + nextSpec); // hacky way to not have to figure out how to move text
|
||||
specComponent.setPreferredSize(new Dimension(40, 40));
|
||||
|
||||
panelComponent.getChildren().add(specComponent);
|
||||
}
|
||||
|
||||
private void addPrayOverlay(final AlchemicalHydra hydra)
|
||||
{
|
||||
final Prayer nextPrayer = hydra.getNextAttack().getPrayer();
|
||||
final int nextSwitch = hydra.getNextSwitch();
|
||||
|
||||
InfoBoxComponent prayComponent = new InfoBoxComponent();
|
||||
|
||||
if (nextSwitch == 1)
|
||||
{
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? medCol : badCol);
|
||||
}
|
||||
else
|
||||
{
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(nextPrayer) ? safeCol : badCol);
|
||||
}
|
||||
|
||||
prayComponent.setImage(hydra.getNextAttack().getImage(spriteManager));
|
||||
prayComponent.setText(" " + nextSwitch);
|
||||
prayComponent.setColor(Color.white);
|
||||
prayComponent.setPreferredSize(new Dimension(40, 40));
|
||||
|
||||
panelComponent.getChildren().add(prayComponent);
|
||||
}
|
||||
|
||||
boolean onGameTick()
|
||||
{
|
||||
return --stunTicks <= 0;
|
||||
}
|
||||
|
||||
private BufferedImage getStunImg()
|
||||
{
|
||||
if (stunImg == null)
|
||||
{
|
||||
stunImg = createStunImage(client);
|
||||
}
|
||||
|
||||
return stunImg;
|
||||
}
|
||||
|
||||
private static BufferedImage createStunImage(Client client)
|
||||
{
|
||||
final Sprite root = getSprite(client, SpriteID.BIG_ASS_GREY_ENTANGLE);
|
||||
final Sprite mark = getSprite(client, SpriteID.TRADE_EXCLAMATION_MARK_ITEM_REMOVAL_WARNING);
|
||||
|
||||
if (mark == null || root == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Sprite sprite = ImageUtil.mergeSprites(client, ImageUtil.resizeSprite(client, root, IMGSIZE, IMGSIZE), mark);
|
||||
|
||||
return sprite.toBufferedImage();
|
||||
}
|
||||
|
||||
private static Sprite getSprite(Client client, int id)
|
||||
{
|
||||
final IndexDataBase spriteDb = client.getIndexSprites();
|
||||
if (spriteDb == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Sprite[] sprites = client.getSprites(spriteDb, id, 0);
|
||||
if (sprites == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return sprites[0];
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@RequiredArgsConstructor
|
||||
enum AlchemicalHydraPhase
|
||||
{
|
||||
ONE(3, AnimationID.HYDRA_1_1, AnimationID.HYDRA_1_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, new WorldPoint(1371, 10263, 0)),
|
||||
TWO(3, AnimationID.HYDRA_2_1, AnimationID.HYDRA_2_2, 0, AnimationID.HYDRA_LIGHTNING, SpriteID.BIG_SPEC_TRANSFER, new WorldPoint(1371, 10272, 0)),
|
||||
THREE(3, AnimationID.HYDRA_3_1, AnimationID.HYDRA_3_2, 0, AnimationID.HYDRA_FIRE, SpriteID.BIG_SUPERHEAT, new WorldPoint(1362, 10272, 0)),
|
||||
FOUR(1, AnimationID.HYDRA_4_1, AnimationID.HYDRA_4_2, ProjectileID.HYDRA_POISON, 0, SpriteID.BIG_ASS_GUTHIX_SPELL, null);
|
||||
|
||||
private final int attacksPerSwitch;
|
||||
private final int deathAnim1;
|
||||
private final int deathAnim2;
|
||||
private final int specProjectileId;
|
||||
private final int specAnimationId;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private final int specImageID;
|
||||
private final WorldPoint fountain;
|
||||
|
||||
private BufferedImage specImage;
|
||||
|
||||
BufferedImage getSpecImage(SpriteManager spriteManager)
|
||||
{
|
||||
if (specImage == null)
|
||||
{
|
||||
BufferedImage tmp = spriteManager.getSprite(specImageID, 0);
|
||||
specImage = tmp == null ? null : ImageUtil.resizeImage(tmp, AlchemicalHydraOverlay.IMGSIZE, AlchemicalHydraOverlay.IMGSIZE);
|
||||
}
|
||||
|
||||
return specImage;
|
||||
}
|
||||
}
|
||||
@@ -1,401 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.plugins.alchemicalhydra.AlchemicalHydra.AttackStyle;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Alchemical Hydra",
|
||||
description = "Show what to pray against hydra",
|
||||
tags = {"Hydra", "Lazy", "4 headed asshole"},
|
||||
type = PluginType.PVM,
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class AlchemicalHydraPlugin extends Plugin
|
||||
{
|
||||
private static final int[] HYDRA_REGIONS = {
|
||||
5279, 5280,
|
||||
5535, 5536
|
||||
};
|
||||
private static final int STUN_LENGTH = 7;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<LocalPoint, Projectile> poisonProjectiles = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private AlchemicalHydra hydra;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean counting;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean fountain;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean stun;
|
||||
|
||||
private boolean inHydraInstance;
|
||||
private int lastAttackTick;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
private AlchemicalHydraConfig config;
|
||||
|
||||
@Inject
|
||||
private AlchemicalHydraOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private AlchemicalHydraSceneOverlay sceneOverlay;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Provides
|
||||
AlchemicalHydraConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AlchemicalHydraConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
initConfig();
|
||||
|
||||
inHydraInstance = checkArea();
|
||||
lastAttackTick = -1;
|
||||
poisonProjectiles.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
eventBus.unregister("fight");
|
||||
eventBus.unregister("npcSpawned");
|
||||
|
||||
inHydraInstance = false;
|
||||
hydra = null;
|
||||
poisonProjectiles.clear();
|
||||
removeOverlays();
|
||||
lastAttackTick = -1;
|
||||
}
|
||||
|
||||
private void initConfig()
|
||||
{
|
||||
this.counting = config.counting();
|
||||
this.fountain = config.fountain();
|
||||
this.stun = config.stun();
|
||||
this.overlay.setSafeCol(config.safeCol());
|
||||
this.overlay.setMedCol(config.medCol());
|
||||
this.overlay.setBadCol(config.badCol());
|
||||
this.sceneOverlay.setPoisonBorder(config.poisonBorderCol());
|
||||
this.sceneOverlay.setPoisonFill(config.poisonCol());
|
||||
this.sceneOverlay.setBadFountain(config.fountainColA());
|
||||
this.sceneOverlay.setGoodFountain(config.fountainColB());
|
||||
}
|
||||
|
||||
private void addFightSubscriptions()
|
||||
{
|
||||
eventBus.subscribe(AnimationChanged.class, "fight", this::onAnimationChanged);
|
||||
eventBus.subscribe(ProjectileMoved.class, "fight", this::onProjectileMoved);
|
||||
eventBus.subscribe(ChatMessage.class, "fight", this::onChatMessage);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("betterHydra"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.getKey())
|
||||
{
|
||||
case "counting":
|
||||
this.counting = config.counting();
|
||||
break;
|
||||
case "fountain":
|
||||
this.fountain = config.fountain();
|
||||
break;
|
||||
case "stun":
|
||||
this.stun = config.stun();
|
||||
break;
|
||||
case "safeCol":
|
||||
overlay.setSafeCol(config.safeCol());
|
||||
return;
|
||||
case "medCol":
|
||||
overlay.setMedCol(config.medCol());
|
||||
return;
|
||||
case "badCol":
|
||||
overlay.setBadCol(config.badCol());
|
||||
return;
|
||||
case "poisonBorderCol":
|
||||
sceneOverlay.setPoisonBorder(config.poisonBorderCol());
|
||||
break;
|
||||
case "poisonCol":
|
||||
sceneOverlay.setPoisonFill(config.poisonCol());
|
||||
break;
|
||||
case "fountainColA":
|
||||
sceneOverlay.setBadFountain(config.fountainColA());
|
||||
break;
|
||||
case "fountainColB":
|
||||
sceneOverlay.setGoodFountain(config.fountainColB());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged state)
|
||||
{
|
||||
if (state.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inHydraInstance = checkArea();
|
||||
|
||||
if (!inHydraInstance)
|
||||
{
|
||||
|
||||
if (hydra != null)
|
||||
{
|
||||
removeOverlays();
|
||||
hydra = null;
|
||||
}
|
||||
|
||||
eventBus.unregister("npcSpawned");
|
||||
eventBus.unregister("fight");
|
||||
return;
|
||||
}
|
||||
|
||||
eventBus.subscribe(NpcSpawned.class, "npcSpawned", this::onNpcSpawned);
|
||||
|
||||
for (NPC npc : client.getNpcs())
|
||||
{
|
||||
if (npc.getId() == NpcID.ALCHEMICAL_HYDRA)
|
||||
{
|
||||
hydra = new AlchemicalHydra(npc);
|
||||
addFightSubscriptions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addOverlays();
|
||||
}
|
||||
|
||||
private void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
if (event.getNpc().getId() != NpcID.ALCHEMICAL_HYDRA)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
eventBus.unregister("npcSpawned");
|
||||
hydra = new AlchemicalHydra(event.getNpc());
|
||||
addFightSubscriptions();
|
||||
addOverlays();
|
||||
}
|
||||
|
||||
private void onAnimationChanged(AnimationChanged animationChanged)
|
||||
{
|
||||
Actor actor = animationChanged.getActor();
|
||||
|
||||
if (!inHydraInstance || hydra == null || actor == client.getLocalPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AlchemicalHydraPhase phase = hydra.getPhase();
|
||||
|
||||
if (actor.getAnimation() == phase.getDeathAnim2() &&
|
||||
phase != AlchemicalHydraPhase.THREE // Else log's gonna say "Tried some weird shit"
|
||||
|| actor.getAnimation() == phase.getDeathAnim1() &&
|
||||
phase == AlchemicalHydraPhase.THREE) // We want the pray to switch ye ok ty
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case ONE:
|
||||
hydra.changePhase(AlchemicalHydraPhase.TWO);
|
||||
return;
|
||||
case TWO:
|
||||
hydra.changePhase(AlchemicalHydraPhase.THREE);
|
||||
return;
|
||||
case THREE:
|
||||
hydra.changePhase(AlchemicalHydraPhase.FOUR);
|
||||
return;
|
||||
case FOUR:
|
||||
hydra = null;
|
||||
poisonProjectiles.clear();
|
||||
eventBus.unregister("fight");
|
||||
eventBus.subscribe(NpcSpawned.class, "npcSpawned", this::onNpcSpawned);
|
||||
removeOverlays();
|
||||
return;
|
||||
default:
|
||||
log.debug("Tried some weird shit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (actor.getAnimation() == phase.getSpecAnimationId() && phase.getSpecAnimationId() != 0)
|
||||
{
|
||||
hydra.setNextSpecial(hydra.getNextSpecial() + 9);
|
||||
}
|
||||
|
||||
if (poisonProjectiles.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Set<LocalPoint> exPoisonProjectiles = new HashSet<>();
|
||||
for (Entry<LocalPoint, Projectile> entry : poisonProjectiles.entrySet())
|
||||
{
|
||||
if (entry.getValue().getEndCycle() < client.getGameCycle())
|
||||
{
|
||||
exPoisonProjectiles.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
for (LocalPoint toRemove : exPoisonProjectiles)
|
||||
{
|
||||
poisonProjectiles.remove(toRemove);
|
||||
}
|
||||
}
|
||||
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
{
|
||||
if (!inHydraInstance || hydra == null
|
||||
|| client.getGameCycle() >= event.getProjectile().getStartMovementCycle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Projectile projectile = event.getProjectile();
|
||||
int id = projectile.getId();
|
||||
|
||||
if (hydra.getPhase().getSpecProjectileId() != 0 && hydra.getPhase().getSpecProjectileId() == id)
|
||||
{
|
||||
if (hydra.getAttackCount() == hydra.getNextSpecial())
|
||||
{
|
||||
// Only add 9 to next special on the first poison projectile (whoops)
|
||||
hydra.setNextSpecial(hydra.getNextSpecial() + 9);
|
||||
}
|
||||
|
||||
poisonProjectiles.put(event.getPosition(), projectile);
|
||||
}
|
||||
else if (client.getTickCount() != lastAttackTick
|
||||
&& (id == AttackStyle.MAGIC.getProjectileID() || id == AttackStyle.RANGED.getProjectileID()))
|
||||
{
|
||||
hydra.handleAttack(id);
|
||||
lastAttackTick = client.getTickCount();
|
||||
}
|
||||
}
|
||||
|
||||
private void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (event.getMessage().equals("The chemicals neutralise the Alchemical Hydra's defences!"))
|
||||
{
|
||||
hydra.setWeakened(true);
|
||||
}
|
||||
else if (event.getMessage().equals("The Alchemical Hydra temporarily stuns you."))
|
||||
{
|
||||
if (isStun())
|
||||
{
|
||||
overlay.setStunTicks(STUN_LENGTH);
|
||||
eventBus.subscribe(GameTick.class, "hydraStun", this::onGameTick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameTick(GameTick tick)
|
||||
{
|
||||
if (overlay.onGameTick())
|
||||
{
|
||||
// unregister self when 7 ticks have passed
|
||||
eventBus.unregister("hydraStun");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkArea()
|
||||
{
|
||||
return Arrays.equals(client.getMapRegions(), HYDRA_REGIONS) && client.isInInstancedRegion();
|
||||
}
|
||||
|
||||
private void addOverlays()
|
||||
{
|
||||
if (counting || stun)
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
if (counting || fountain)
|
||||
{
|
||||
overlayManager.add(sceneOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeOverlays()
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(sceneOverlay);
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* 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.alchemicalhydra;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Perspective.getCanvasTileAreaPoly;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldArea;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@Singleton
|
||||
class AlchemicalHydraSceneOverlay extends Overlay
|
||||
{
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color poisonBorder;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color poisonFill;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color goodFountain;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color badFountain;
|
||||
|
||||
private final AlchemicalHydraPlugin plugin;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public AlchemicalHydraSceneOverlay(final Client client, final AlchemicalHydraPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
AlchemicalHydra hydra = plugin.getHydra();
|
||||
final Map<LocalPoint, Projectile> poisonProjectiles = plugin.getPoisonProjectiles();
|
||||
|
||||
if (plugin.isCounting() && !poisonProjectiles.isEmpty())
|
||||
{
|
||||
drawPoisonArea(graphics, poisonProjectiles);
|
||||
}
|
||||
|
||||
if (plugin.isFountain() && hydra.getPhase().getFountain() != null)
|
||||
{
|
||||
drawFountain(graphics, hydra);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawPoisonArea(Graphics2D graphics, Map<LocalPoint, Projectile> poisonProjectiles)
|
||||
{
|
||||
Area poisonTiles = new Area();
|
||||
|
||||
for (Map.Entry<LocalPoint, Projectile> entry : poisonProjectiles.entrySet())
|
||||
{
|
||||
if (entry.getValue().getEndCycle() < client.getGameCycle())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint point = entry.getKey();
|
||||
Polygon poly = getCanvasTileAreaPoly(client, point, 3);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
poisonTiles.add(new Area(poly));
|
||||
}
|
||||
}
|
||||
|
||||
graphics.setPaintMode();
|
||||
graphics.setColor(poisonBorder);
|
||||
graphics.draw(poisonTiles);
|
||||
graphics.setColor(poisonFill);
|
||||
graphics.fill(poisonTiles);
|
||||
}
|
||||
|
||||
private void drawFountain(Graphics2D graphics, AlchemicalHydra hydra)
|
||||
{
|
||||
Collection<WorldPoint> fountainWorldPoint = WorldPoint.toLocalInstance(client, hydra.getPhase().getFountain()); // thanks
|
||||
if (fountainWorldPoint.size() > 1) // for
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPoint wp = null;
|
||||
for (WorldPoint p : fountainWorldPoint) // this
|
||||
{
|
||||
wp = p;
|
||||
}
|
||||
|
||||
LocalPoint fountainPoint = wp == null ? null : LocalPoint.fromWorld(client, wp); // trash
|
||||
|
||||
if (fountainPoint == null || hydra.isWeakened()) // I
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Polygon poly = getCanvasTileAreaPoly(client, fountainPoint, 3); // don't
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color color; // like
|
||||
|
||||
if (hydra.getNpc().getWorldArea().intersectsWith(new WorldArea(wp, 1, 1))) // coords
|
||||
{ // WHICH FUCKING RETARD DID X, Y, dX, dY, Z???? IT'S XYZdXdY REEEEEEEEEE
|
||||
color = goodFountain;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = badFountain;
|
||||
}
|
||||
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(3));
|
||||
graphics.draw(poly);
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
|
||||
* 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.ammo;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
|
||||
class AmmoCounter extends Counter
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int itemID;
|
||||
private final String name;
|
||||
private final int total;
|
||||
private final Instant time;
|
||||
private BigDecimal ammoPerHour;
|
||||
|
||||
AmmoCounter(Plugin plugin, int itemID, int count, String name, BufferedImage image)
|
||||
{
|
||||
super(image, plugin, count);
|
||||
this.total = count;
|
||||
this.itemID = itemID;
|
||||
this.name = name;
|
||||
this.time = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
return QuantityFormatter.quantityToRSDecimalStack(getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip()
|
||||
{
|
||||
if (lossRate() >= 1)
|
||||
{
|
||||
return String.format("%s</br>Loss Rate: %s/h", name, lossRate());
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Need more data";
|
||||
}
|
||||
}
|
||||
|
||||
private int lossRate()
|
||||
{
|
||||
BigDecimal diff = BigDecimal.valueOf(total).subtract(BigDecimal.valueOf(getCount()));
|
||||
BigDecimal timeSinceStart = BigDecimal.valueOf(Duration.between(time, Instant.now()).getSeconds())
|
||||
.setScale(6, RoundingMode.UP);
|
||||
if (timeSinceStart.compareTo(BigDecimal.ZERO) != 0)
|
||||
{
|
||||
BigDecimal timeSinceStartInHours = timeSinceStart.divide(BigDecimal.valueOf(3600), RoundingMode.UP);
|
||||
ammoPerHour = diff.divide(timeSinceStartInHours, RoundingMode.HALF_UP);
|
||||
}
|
||||
if (ammoPerHour != null)
|
||||
{
|
||||
return ammoPerHour.intValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
|
||||
* 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.ammo;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Ammo",
|
||||
description = "Shows the current ammo the player has equipped",
|
||||
tags = {"bolts", "darts", "chinchompa", "equipment"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
@Singleton
|
||||
public class AmmoPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
private AmmoCounter counterBox;
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
final ItemContainer container = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
|
||||
if (container != null)
|
||||
{
|
||||
checkInventory(container.getItems());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
infoBoxManager.removeInfoBox(counterBox);
|
||||
counterBox = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onItemContainerChanged(ItemContainerChanged event)
|
||||
{
|
||||
if (event.getItemContainer() != client.getItemContainer(InventoryID.EQUIPMENT))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
checkInventory(event.getItemContainer().getItems());
|
||||
}
|
||||
|
||||
private void checkInventory(final Item[] items)
|
||||
{
|
||||
// Check for weapon slot items. This overrides the ammo slot,
|
||||
// as the player will use the thrown weapon (eg. chinchompas, knives, darts)
|
||||
if (items.length > EquipmentInventorySlot.WEAPON.getSlotIdx())
|
||||
{
|
||||
final Item weapon = items[EquipmentInventorySlot.WEAPON.getSlotIdx()];
|
||||
final ItemDefinition weaponComp = itemManager.getItemDefinition(weapon.getId());
|
||||
if (weaponComp.isStackable())
|
||||
{
|
||||
updateInfobox(weapon, weaponComp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (items.length <= EquipmentInventorySlot.AMMO.getSlotIdx())
|
||||
{
|
||||
removeInfobox();
|
||||
return;
|
||||
}
|
||||
|
||||
final Item ammo = items[EquipmentInventorySlot.AMMO.getSlotIdx()];
|
||||
final ItemDefinition comp = itemManager.getItemDefinition(ammo.getId());
|
||||
|
||||
if (!comp.isStackable())
|
||||
{
|
||||
removeInfobox();
|
||||
return;
|
||||
}
|
||||
|
||||
updateInfobox(ammo, comp);
|
||||
}
|
||||
|
||||
private void updateInfobox(final Item item, final ItemDefinition comp)
|
||||
{
|
||||
if (counterBox != null && counterBox.getItemID() == item.getId())
|
||||
{
|
||||
counterBox.setCount(item.getQuantity());
|
||||
return;
|
||||
}
|
||||
|
||||
removeInfobox();
|
||||
final BufferedImage image = itemManager.getImage(item.getId(), 5, false);
|
||||
counterBox = new AmmoCounter(this, item.getId(), item.getQuantity(), comp.getName(), image);
|
||||
infoBoxManager.addInfoBox(counterBox);
|
||||
}
|
||||
|
||||
private void removeInfobox()
|
||||
{
|
||||
infoBoxManager.removeInfoBox(counterBox);
|
||||
counterBox = null;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* 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.animations;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.http.api.animation.AnimationsClient;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Animations",
|
||||
hidden = true
|
||||
)
|
||||
@Slf4j
|
||||
public class AnimationsPlugin extends Plugin
|
||||
{
|
||||
private final AnimationsClient animationsClient = new AnimationsClient();
|
||||
|
||||
private HashMap<Integer, int[]> animations;
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
{
|
||||
try
|
||||
{
|
||||
animations = animationsClient.get();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onAnimationChanged(AnimationChanged event)
|
||||
{
|
||||
if (event.getActor() instanceof NPC)
|
||||
{
|
||||
if (event.getActor().getAnimation() != -1)
|
||||
{
|
||||
if (ArrayUtils.contains(animations.get(((NPC) event.getActor()).getId()), event.getActor().getAnimation()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int[] newAnimations = ArrayUtils.add(animations.get(((NPC) event.getActor()).getId()), event.getActor().getAnimation());
|
||||
animations.put(((NPC) event.getActor()).getId(), newAnimations);
|
||||
animationsClient.submit(((NPC) event.getActor()).getId(), event.getActor().getAnimation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.animsmoothing;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup(AnimationSmoothingPlugin.CONFIG_GROUP)
|
||||
public interface AnimationSmoothingConfig extends Config
|
||||
{
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "smoothPlayerAnimations",
|
||||
name = "Smooth Player Animations",
|
||||
description = "Configures whether the player animations are smooth or not",
|
||||
position = 1
|
||||
)
|
||||
default boolean smoothPlayerAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "smoothNpcAnimations",
|
||||
name = "Smooth NPC Animations",
|
||||
description = "Configures whether the npc animations are smooth or not",
|
||||
position = 2
|
||||
)
|
||||
default boolean smoothNpcAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "smoothObjectAnimations",
|
||||
name = "Smooth Object Animations",
|
||||
description = "Configures whether the object animations are smooth or not",
|
||||
position = 3
|
||||
)
|
||||
default boolean smoothObjectAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "smoothWidgetAnimations",
|
||||
name = "Smooth Widget Animations",
|
||||
description = "Configures whether the widget animations are smooth or not",
|
||||
position = 4
|
||||
)
|
||||
default boolean smoothWidgetAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.animsmoothing;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Animation Smoothing",
|
||||
description = "Show smoother player, NPC, and object animations",
|
||||
tags = {"npcs", "objects", "players"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.MISCELLANEOUS
|
||||
)
|
||||
@Singleton
|
||||
public class AnimationSmoothingPlugin extends Plugin
|
||||
{
|
||||
static final String CONFIG_GROUP = "animationSmoothing";
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private AnimationSmoothingConfig config;
|
||||
|
||||
@Provides
|
||||
AnimationSmoothingConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AnimationSmoothingConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
client.setInterpolatePlayerAnimations(false);
|
||||
client.setInterpolateNpcAnimations(false);
|
||||
client.setInterpolateObjectAnimations(false);
|
||||
client.setInterpolateWidgetAnimations(false);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals(CONFIG_GROUP))
|
||||
{
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private void update()
|
||||
{
|
||||
client.setInterpolatePlayerAnimations(config.smoothPlayerAnimations());
|
||||
client.setInterpolateNpcAnimations(config.smoothNpcAnimations());
|
||||
client.setInterpolateObjectAnimations(config.smoothObjectAnimations());
|
||||
client.setInterpolateWidgetAnimations(config.smoothWidgetAnimations());
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, DennisDeV <https://github.com/DevDennis>
|
||||
* 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.antidrag;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.KeyEvent;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.client.config.Alpha;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Keybind;
|
||||
import net.runelite.client.config.ModifierlessKeybind;
|
||||
|
||||
@ConfigGroup("antiDrag")
|
||||
public interface AntiDragConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "alwaysOn",
|
||||
name = "Always On",
|
||||
description = "Makes the anti-drag always active and disables the hotkey toggle",
|
||||
disabledBy = "toggleKeyBind || holdKeyBind",
|
||||
hide = "toggleKeyBind || holdKeyBind"
|
||||
)
|
||||
default boolean alwaysOn()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "toggleKeyBind",
|
||||
name = "Toggle with Keybind",
|
||||
description = "Toggle anti drag on and off, rather than always on.",
|
||||
disabledBy = "alwaysOn || holdKeyBind",
|
||||
hide = "alwaysOn || holdKeyBind"
|
||||
)
|
||||
default boolean toggleKeyBind()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "holdKeyBind",
|
||||
name = "Hold with Keybind",
|
||||
description = "Hold anti drag key to turn it on, rather than toggle it on or off.",
|
||||
disabledBy = "alwaysOn || toggleKeyBind",
|
||||
hide = "alwaysOn || toggleKeyBind"
|
||||
)
|
||||
default boolean holdKeyBind()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "key",
|
||||
name = "Keybind",
|
||||
description = "The keybind you want to use for antidrag",
|
||||
position = 3,
|
||||
hidden = true,
|
||||
unhide = "toggleKeyBind || holdKeyBind"
|
||||
)
|
||||
default Keybind key()
|
||||
{
|
||||
return new ModifierlessKeybind(KeyEvent.VK_SHIFT, 0);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "dragDelay",
|
||||
name = "Drag Delay",
|
||||
description = "Configures the inventory drag delay in client ticks (20ms)",
|
||||
position = 4
|
||||
)
|
||||
default int dragDelay()
|
||||
{
|
||||
return Constants.GAME_TICK_LENGTH / Constants.CLIENT_TICK_LENGTH; // one game tick
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "reqFocus",
|
||||
name = "Reset on focus loss",
|
||||
description = "Disable antidrag when losing focus (like alt tabbing)",
|
||||
position = 5,
|
||||
hidden = true,
|
||||
unhide = "toggleKeyBind || holdKeyBind"
|
||||
)
|
||||
default boolean reqFocus()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "overlay",
|
||||
name = "Enable overlay",
|
||||
description = "Do you really need a description?",
|
||||
position = 6,
|
||||
hidden = true,
|
||||
unhide = "toggleKeyBind || holdKeyBind"
|
||||
)
|
||||
default boolean overlay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "color",
|
||||
name = "Overlay color",
|
||||
description = "Change the overlay color, duh",
|
||||
hidden = true,
|
||||
unhide = "toggleKeyBind || holdKeyBind",
|
||||
position = 7
|
||||
)
|
||||
default Color color()
|
||||
{
|
||||
return new Color(255, 0, 0, 30);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "changeCursor",
|
||||
name = "Change Cursor",
|
||||
description = "Change cursor when you have anti-drag enabled.",
|
||||
position = 8,
|
||||
hidden = true,
|
||||
unhide = "toggleKeyBind || holdKeyBind"
|
||||
)
|
||||
default boolean changeCursor()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "cursorStyle",
|
||||
name = "Cursor",
|
||||
description = "Select which cursor you wish to use",
|
||||
hidden = true,
|
||||
unhide = "changeCursor",
|
||||
position = 9
|
||||
)
|
||||
default CustomCursor selectedCursor()
|
||||
{
|
||||
return CustomCursor.RS3_GOLD;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://openosrs.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.antidrag;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
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;
|
||||
|
||||
@Singleton
|
||||
public class AntiDragOverlay extends Overlay
|
||||
{
|
||||
private static final int RADIUS = 20;
|
||||
|
||||
private final Client client;
|
||||
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Color color;
|
||||
|
||||
@Inject
|
||||
private AntiDragOverlay(final Client client)
|
||||
{
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.TOOLTIP);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
g.setColor(color);
|
||||
|
||||
final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition();
|
||||
final Point mousePosition = new Point(mouseCanvasPosition.getX() - RADIUS, mouseCanvasPosition.getY() - RADIUS);
|
||||
final Rectangle bounds = new Rectangle(mousePosition.x, mousePosition.y, 2 * RADIUS, 2 * RADIUS);
|
||||
g.fillOval(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
|
||||
return bounds.getSize();
|
||||
}
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, DennisDeV <https://github.com/DevDennis>
|
||||
* Copyright (c) 2019, ganom <https://github.com/ganom>
|
||||
* 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.antidrag;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.Keybind;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.HotkeyListener;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Anti Drag",
|
||||
description = "Prevent dragging an item for a specified delay",
|
||||
tags = {"antidrag", "delay", "inventory", "items"},
|
||||
type = PluginType.UTILITY,
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Singleton
|
||||
public class AntiDragPlugin extends Plugin
|
||||
{
|
||||
private static final int DEFAULT_DELAY = 5;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientUI clientUI;
|
||||
|
||||
@Inject
|
||||
private AntiDragConfig config;
|
||||
|
||||
@Inject
|
||||
private AntiDragOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
private boolean toggleDrag;
|
||||
private boolean configOverlay;
|
||||
private boolean changeCursor;
|
||||
private CustomCursor selectedCursor;
|
||||
private Keybind key;
|
||||
|
||||
private final HotkeyListener toggleListener = new HotkeyListener(() -> this.key)
|
||||
{
|
||||
@Override
|
||||
public void hotkeyPressed()
|
||||
{
|
||||
toggleDrag = !toggleDrag;
|
||||
if (toggleDrag)
|
||||
{
|
||||
if (configOverlay)
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
if (changeCursor)
|
||||
{
|
||||
clientUI.setCursor(selectedCursor.getCursorImage(), selectedCursor.toString());
|
||||
}
|
||||
|
||||
client.setInventoryDragDelay(config.dragDelay());
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
clientUI.resetCursor();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final HotkeyListener holdListener = new HotkeyListener(() -> this.key)
|
||||
{
|
||||
@Override
|
||||
public void hotkeyPressed()
|
||||
{
|
||||
if (configOverlay)
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
if (changeCursor)
|
||||
{
|
||||
clientUI.setCursor(selectedCursor.getCursorImage(), selectedCursor.toString());
|
||||
}
|
||||
|
||||
client.setInventoryDragDelay(config.dragDelay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hotkeyReleased()
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
clientUI.resetCursor();
|
||||
}
|
||||
};
|
||||
|
||||
@Provides
|
||||
AntiDragConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AntiDragConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
overlay.setColor(config.color());
|
||||
updateConfig();
|
||||
updateKeyListeners();
|
||||
|
||||
if (config.alwaysOn())
|
||||
{
|
||||
client.setInventoryDragDelay(config.dragDelay());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
keyManager.unregisterKeyListener(holdListener);
|
||||
keyManager.unregisterKeyListener(toggleListener);
|
||||
toggleDrag = false;
|
||||
overlayManager.remove(overlay);
|
||||
clientUI.resetCursor();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("antiDrag"))
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
switch (event.getKey())
|
||||
{
|
||||
case "toggleKeyBind":
|
||||
case "holdKeyBind":
|
||||
updateKeyListeners();
|
||||
break;
|
||||
case "alwaysOn":
|
||||
client.setInventoryDragDelay(config.alwaysOn() ? config.dragDelay() : DEFAULT_DELAY);
|
||||
break;
|
||||
case "dragDelay":
|
||||
if (config.alwaysOn())
|
||||
{
|
||||
client.setInventoryDragDelay(config.dragDelay());
|
||||
}
|
||||
break;
|
||||
case ("changeCursor"):
|
||||
clientUI.resetCursor();
|
||||
break;
|
||||
case ("color"):
|
||||
overlay.setColor(config.color());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
keyManager.unregisterKeyListener(toggleListener);
|
||||
keyManager.unregisterKeyListener(holdListener);
|
||||
}
|
||||
else if (event.getGameState() == GameState.LOGGING_IN)
|
||||
{
|
||||
updateKeyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.key = config.key();
|
||||
this.configOverlay = config.overlay();
|
||||
this.changeCursor = config.changeCursor();
|
||||
this.selectedCursor = config.selectedCursor();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onFocusChanged(FocusChanged focusChanged)
|
||||
{
|
||||
if (!focusChanged.isFocused() && config.reqFocus() && !config.alwaysOn())
|
||||
{
|
||||
client.setInventoryDragDelay(DEFAULT_DELAY);
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateKeyListeners()
|
||||
{
|
||||
if (config.holdKeyBind())
|
||||
{
|
||||
keyManager.registerKeyListener(holdListener);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyManager.unregisterKeyListener(holdListener);
|
||||
}
|
||||
|
||||
if (config.toggleKeyBind())
|
||||
{
|
||||
keyManager.registerKeyListener(toggleListener);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyManager.unregisterKeyListener(toggleListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Kruithne <kruithne@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.antidrag;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.plugins.customcursor.CustomCursorPlugin;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
public enum CustomCursor
|
||||
{
|
||||
RS3_GOLD("RS3 Gold", "cursor-rs3-gold.png"),
|
||||
RS3_SILVER("RS3 Silver", "cursor-rs3-silver.png"),
|
||||
DRAGON_DAGGER("Dragon Dagger", "cursor-dragon-dagger.png"),
|
||||
DRAGON_DAGGER_POISON("Dragon Dagger (p)", "cursor-dragon-dagger-p.png"),
|
||||
TROUT("Trout", "cursor-trout.png"),
|
||||
DRAGON_SCIMITAR("Dragon Scimitar", "cursor-dragon-scimitar.png"),
|
||||
ARMADYL_GODSWORD("Armadyl Godsword", "cursor-armadyl-godsword.png"),
|
||||
BANDOS_GODSWORD("Bandos Godsword", "cursor-bandos-godsword.png"),
|
||||
MOUSE("Mouse", "cursor-mouse.png"),
|
||||
SARADOMIN_GODSWORD("Saradomin Godsword", "cursor-saradomin-godsword.png"),
|
||||
ZAMORAK_GODSWORD("Zamorak Godsword", "cursor-zamorak-godsword.png"),
|
||||
SKILL_SPECS("Skill Specs", "cursor-skill-specs.png");
|
||||
|
||||
private final String name;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final BufferedImage cursorImage;
|
||||
|
||||
CustomCursor(String name, String icon)
|
||||
{
|
||||
this.name = name;
|
||||
this.cursorImage = ImageUtil.getResourceStreamFromClass(CustomCursorPlugin.class, icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Modified by farhan1666
|
||||
*
|
||||
* 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.aoewarnings;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.api.ProjectileID;
|
||||
|
||||
|
||||
public enum AoeProjectileInfo
|
||||
{
|
||||
LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 5),
|
||||
CRAZY_ARCHAEOLOGIST_AOE(ProjectileID.CRAZY_ARCHAEOLOGIST_AOE, 3),
|
||||
ICE_DEMON_RANGED_AOE(ProjectileID.ICE_DEMON_RANGED_AOE, 3),
|
||||
|
||||
/**
|
||||
* When you don't have pray range on ice demon does an ice barrage
|
||||
*/
|
||||
ICE_DEMON_ICE_BARRAGE_AOE(ProjectileID.ICE_DEMON_ICE_BARRAGE_AOE, 3),
|
||||
|
||||
/**
|
||||
* The AOE when vasa first starts
|
||||
*/
|
||||
VASA_AWAKEN_AOE(ProjectileID.VASA_AWAKEN_AOE, 3),
|
||||
VASA_RANGED_AOE(ProjectileID.VASA_RANGED_AOE, 3),
|
||||
TEKTON_METEOR_AOE(ProjectileID.TEKTON_METEOR_AOE, 3),
|
||||
|
||||
/**
|
||||
* The AOEs of Vorkath
|
||||
*/
|
||||
VORKATH_BOMB(ProjectileID.VORKATH_BOMB_AOE, 3),
|
||||
VORKATH_POISON_POOL(ProjectileID.VORKATH_POISON_POOL_AOE, 1),
|
||||
VORKATH_SPAWN(ProjectileID.VORKATH_SPAWN_AOE, 1), //extra tick because hard to see otherwise
|
||||
VORKATH_TICK_FIRE(ProjectileID.VORKATH_TICK_FIRE_AOE, 1),
|
||||
|
||||
/**
|
||||
* the AOEs of Galvek
|
||||
*/
|
||||
GALVEK_MINE(ProjectileID.GALVEK_MINE, 3),
|
||||
GALVEK_BOMB(ProjectileID.GALVEK_BOMB, 3),
|
||||
|
||||
/**
|
||||
* the AOEs of Grotesque Guardians
|
||||
*/
|
||||
DAWN_FREEZE(ProjectileID.DAWN_FREEZE, 3),
|
||||
DUSK_CEILING(ProjectileID.DUSK_CEILING, 3),
|
||||
|
||||
/**
|
||||
* the AOE of Vet'ion
|
||||
*/
|
||||
VETION_LIGHTNING(ProjectileID.VETION_LIGHTNING, 1),
|
||||
|
||||
/**
|
||||
* the AOE of Chaos Fanatic
|
||||
*/
|
||||
CHAOS_FANATIC(ProjectileID.CHAOS_FANATIC_AOE, 1),
|
||||
|
||||
/**
|
||||
* the AOE of the Corporeal Beast
|
||||
*/
|
||||
CORPOREAL_BEAST(ProjectileID.CORPOREAL_BEAST_AOE, 1),
|
||||
CORPOREAL_BEAST_DARK_CORE(ProjectileID.CORPOREAL_BEAST_DARK_CORE_AOE, 3),
|
||||
|
||||
/**
|
||||
* the AOEs of The Great Olm
|
||||
*/
|
||||
OLM_FALLING_CRYSTAL(ProjectileID.OLM_FALLING_CRYSTAL, 3),
|
||||
OLM_BURNING(ProjectileID.OLM_BURNING, 1),
|
||||
OLM_FALLING_CRYSTAL_TRAIL(ProjectileID.OLM_FALLING_CRYSTAL_TRAIL, 1),
|
||||
OLM_ACID_TRAIL(ProjectileID.OLM_ACID_TRAIL, 1),
|
||||
OLM_FIRE_LINE(ProjectileID.OLM_FIRE_LINE, 1),
|
||||
|
||||
/**
|
||||
* the AOE of the Wintertodt snow that falls
|
||||
*/
|
||||
WINTERTODT_SNOW_FALL(ProjectileID.WINTERTODT_SNOW_FALL_AOE, 3),
|
||||
|
||||
/**
|
||||
* AOE of Xarpus throwing poison
|
||||
*/
|
||||
XARPUS_POISON_AOE(ProjectileID.XARPUS_ACID, 1),
|
||||
|
||||
/**
|
||||
* Aoe of Addy Drags
|
||||
*/
|
||||
ADDY_DRAG_POISON(ProjectileID.ADDY_DRAG_POISON, 1),
|
||||
|
||||
/**
|
||||
* the Breath of the Drake
|
||||
*/
|
||||
DRAKE_BREATH(ProjectileID.DRAKE_BREATH, 1),
|
||||
|
||||
/**
|
||||
* Cerbs fire
|
||||
*/
|
||||
CERB_FIRE(ProjectileID.CERB_FIRE, 2),
|
||||
|
||||
/**
|
||||
* Demonic gorilla
|
||||
*/
|
||||
DEMONIC_GORILLA_BOULDER(ProjectileID.DEMONIC_GORILLA_BOULDER, 1),
|
||||
|
||||
/**
|
||||
* Marble gargoyle (Superior Gargoyle)
|
||||
*/
|
||||
MARBLE_GARGOYLE_AOE(ProjectileID.MARBLE_GARGOYLE_AOE, 1);
|
||||
|
||||
private static final Map<Integer, AoeProjectileInfo> map = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for (AoeProjectileInfo aoe : values())
|
||||
{
|
||||
map.put(aoe.id, aoe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the projectile to trigger this AoE warning
|
||||
*/
|
||||
private final int id;
|
||||
/**
|
||||
* How long the indicator should last for this AoE warning This might
|
||||
* need to be a bit longer than the projectile actually takes to land as
|
||||
* there is a fade effect on the warning
|
||||
*/
|
||||
private final int aoeSize;
|
||||
|
||||
AoeProjectileInfo(int id, int aoeSize)
|
||||
{
|
||||
this.id = id;
|
||||
this.aoeSize = aoeSize;
|
||||
}
|
||||
|
||||
public static AoeProjectileInfo getById(int id)
|
||||
{
|
||||
return map.get(id);
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getAoeSize()
|
||||
{
|
||||
return aoeSize;
|
||||
}
|
||||
}
|
||||
@@ -1,965 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified by farhan1666
|
||||
*
|
||||
* 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.aoewarnings;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigTitleSection;
|
||||
import net.runelite.client.config.Range;
|
||||
import net.runelite.client.config.Title;
|
||||
|
||||
@ConfigGroup("aoe")
|
||||
public interface AoeWarningConfig extends Config
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@AllArgsConstructor
|
||||
enum FontStyle
|
||||
{
|
||||
BOLD("Bold", Font.BOLD),
|
||||
ITALIC("Italic", Font.ITALIC),
|
||||
PLAIN("Plain", Font.PLAIN);
|
||||
|
||||
private String name;
|
||||
private int font;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "notifyTitle",
|
||||
name = "Notify",
|
||||
description = "",
|
||||
position = -1
|
||||
)
|
||||
default Title notifyTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "aoeNotifyAll",
|
||||
name = "Notify for all AoE warnings",
|
||||
description = "Configures whether or not AoE Projectile Warnings should trigger a notification",
|
||||
position = 0,
|
||||
titleSection = "notifyTitle"
|
||||
)
|
||||
default boolean aoeNotifyAll()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "overlayTitle",
|
||||
name = "Overlay",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
default Title overlayTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "overlayColor",
|
||||
name = "Overlay Color",
|
||||
description = "Configures the color of the AoE Projectile Warnings overlay",
|
||||
titleSection = "overlayTitle"
|
||||
)
|
||||
default Color overlayColor()
|
||||
{
|
||||
return new Color(0, 150, 200);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "outline",
|
||||
name = "Display Outline",
|
||||
description = "Configures whether or not AoE Projectile Warnings have an outline",
|
||||
titleSection = "overlayTitle",
|
||||
position = 3
|
||||
)
|
||||
default boolean isOutlineEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "delay",
|
||||
name = "Fade Delay",
|
||||
description = "Configures the amount of time in milliseconds that the warning lingers for after the projectile has touched the ground",
|
||||
titleSection = "overlayTitle",
|
||||
position = 4
|
||||
)
|
||||
default int delay()
|
||||
{
|
||||
return 300;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fade",
|
||||
name = "Fade Warnings",
|
||||
description = "Configures whether or not AoE Projectile Warnings fade over time",
|
||||
titleSection = "overlayTitle",
|
||||
position = 5
|
||||
)
|
||||
default boolean isFadeEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tickTimers",
|
||||
name = "Tick Timers",
|
||||
description = "Configures whether or not AoE Projectile Warnings has tick timers overlaid as well.",
|
||||
titleSection = "overlayTitle",
|
||||
position = 6
|
||||
)
|
||||
default boolean tickTimers()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "textTitle",
|
||||
position = 7,
|
||||
name = "Text",
|
||||
description = "",
|
||||
hidden = true,
|
||||
unhide = "tickTimers"
|
||||
)
|
||||
default Title textTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "fontStyle",
|
||||
name = "Font Style",
|
||||
description = "Bold/Italics/Plain",
|
||||
titleSection = "textTitle",
|
||||
hidden = true,
|
||||
unhide = "tickTimers"
|
||||
)
|
||||
default FontStyle fontStyle()
|
||||
{
|
||||
return FontStyle.BOLD;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 20,
|
||||
max = 40
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "textSize",
|
||||
name = "Text Size",
|
||||
description = "Text Size for Timers.",
|
||||
titleSection = "textTitle",
|
||||
hidden = true,
|
||||
unhide = "tickTimers"
|
||||
)
|
||||
default int textSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "shadows",
|
||||
name = "Shadows",
|
||||
description = "Adds Shadows to text.",
|
||||
titleSection = "textTitle",
|
||||
hidden = true,
|
||||
unhide = "tickTimers"
|
||||
)
|
||||
default boolean shadows()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "npcTitle",
|
||||
name = "NPC's",
|
||||
description = "",
|
||||
position = 11
|
||||
)
|
||||
default Title npcTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "lizardmanaoeTitle",
|
||||
name = "Lizardman Shamans",
|
||||
description = "",
|
||||
position = 12,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title lizardmanaoeTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lizardmanaoe",
|
||||
name = "Lizardman Shamans",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans is displayed",
|
||||
titleSection = "lizardmanaoeTitle",
|
||||
position = 13
|
||||
)
|
||||
default boolean isShamansEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lizardmanaoenotify",
|
||||
name = "Lizardman Shamans Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans should trigger a notification",
|
||||
titleSection = "lizardmanaoeTitle",
|
||||
position = 14,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isShamansNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "archaeologistaoeTitle",
|
||||
name = "Crazy Archaeologist",
|
||||
description = "",
|
||||
position = 15,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title archaeologistaoeTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "archaeologistaoe",
|
||||
name = "Crazy Archaeologist",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Archaeologist is displayed",
|
||||
titleSection = "archaeologistaoeTitle",
|
||||
position = 16
|
||||
)
|
||||
default boolean isArchaeologistEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "archaeologistaoenotify",
|
||||
name = "Crazy Archaeologist Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Crazy Archaeologist should trigger a notification",
|
||||
titleSection = "archaeologistaoeTitle",
|
||||
position = 17,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isArchaeologistNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "icedemonTitle",
|
||||
name = "Ice Demon",
|
||||
description = "",
|
||||
position = 18,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title icedemonTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "icedemon",
|
||||
name = "Ice Demon",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Ice Demon is displayed",
|
||||
titleSection = "icedemonTitle",
|
||||
position = 19
|
||||
)
|
||||
default boolean isIceDemonEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "icedemonnotify",
|
||||
name = "Ice Demon Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Ice Demon should trigger a notification",
|
||||
titleSection = "icedemonTitle",
|
||||
position = 20,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isIceDemonNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "vasaTitle",
|
||||
name = "Vasa",
|
||||
description = "",
|
||||
position = 21,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title vasaTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vasa",
|
||||
name = "Vasa",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vasa is displayed",
|
||||
titleSection = "vasaTitle",
|
||||
position = 22
|
||||
)
|
||||
default boolean isVasaEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vasanotify",
|
||||
name = "Vasa Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vasa should trigger a notification",
|
||||
titleSection = "vasaTitle",
|
||||
position = 23,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isVasaNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "tektonTitle",
|
||||
name = "Tekton",
|
||||
description = "",
|
||||
position = 24,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title tektonTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tekton",
|
||||
name = "Tekton",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Tekton is displayed",
|
||||
titleSection = "tektonTitle",
|
||||
position = 25
|
||||
)
|
||||
default boolean isTektonEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tektonnotify",
|
||||
name = "Tekton Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Tekton should trigger a notification",
|
||||
titleSection = "tektonTitle",
|
||||
position = 26,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isTektonNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "vorkathTitle",
|
||||
name = "Vorkath",
|
||||
description = "",
|
||||
position = 27,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title vorkathTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vorkath",
|
||||
name = "Vorkath",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vorkath are displayed",
|
||||
titleSection = "vorkathTitle",
|
||||
position = 28
|
||||
)
|
||||
default boolean isVorkathEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vorkathotify",
|
||||
name = "Vorkath Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vorkath should trigger a notification",
|
||||
titleSection = "vorkathTitle",
|
||||
position = 29,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isVorkathNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "galvekTitle",
|
||||
name = "Galvek",
|
||||
description = "",
|
||||
position = 30,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title galvekTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "galvek",
|
||||
name = "Galvek",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Galvek are displayed",
|
||||
titleSection = "galvekTitle",
|
||||
position = 31
|
||||
)
|
||||
default boolean isGalvekEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "galveknotify",
|
||||
name = "Galvek Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Galvek should trigger a notification",
|
||||
titleSection = "galvekTitle",
|
||||
position = 32,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isGalvekNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "gargbossTitle",
|
||||
name = "Gargoyle Boss",
|
||||
description = "",
|
||||
position = 33,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title gargbossTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gargboss",
|
||||
name = "Gargoyle Boss",
|
||||
description = "Configs whether or not AoE Projectile Warnings for Dawn/Dusk are displayed",
|
||||
titleSection = "gargbossTitle",
|
||||
position = 34
|
||||
)
|
||||
default boolean isGargBossEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gargbossnotify",
|
||||
name = "Gargoyle Boss Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Gargoyle Bosses should trigger a notification",
|
||||
titleSection = "gargbossTitle",
|
||||
position = 35,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isGargBossNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "vetionTitle",
|
||||
name = "Vet'ion",
|
||||
description = "",
|
||||
position = 36,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title vetionTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vetion",
|
||||
name = "Vet'ion",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vet'ion are displayed",
|
||||
titleSection = "vetionTitle",
|
||||
position = 37
|
||||
)
|
||||
default boolean isVetionEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vetionnotify",
|
||||
name = "Vet'ion Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vet'ion should trigger a notification",
|
||||
titleSection = "vetionTitle",
|
||||
position = 38,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isVetionNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "chaosfanaticTitle",
|
||||
name = "Chaos Fanatic",
|
||||
description = "",
|
||||
position = 39,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title chaosfanaticTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "chaosfanatic",
|
||||
name = "Chaos Fanatic",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic are displayed",
|
||||
titleSection = "chaosfanaticTitle",
|
||||
position = 40
|
||||
)
|
||||
default boolean isChaosFanaticEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "chaosfanaticnotify",
|
||||
name = "Chaos Fanatic Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic should trigger a notification",
|
||||
titleSection = "chaosfanaticTitle",
|
||||
position = 41,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isChaosFanaticNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "olmTitle",
|
||||
name = "Olm",
|
||||
description = "",
|
||||
position = 42,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title olmTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "olm",
|
||||
name = "Olm",
|
||||
description = "Configures whether or not AoE Projectile Warnings for The Great Olm are displayed",
|
||||
titleSection = "olmTitle",
|
||||
position = 43
|
||||
)
|
||||
default boolean isOlmEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "olmnotify",
|
||||
name = "Olm Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Olm should trigger a notification",
|
||||
titleSection = "olmTitle",
|
||||
position = 44,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isOlmNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "olmBombsTitle",
|
||||
name = "Bombs",
|
||||
description = "",
|
||||
position = 45,
|
||||
titleSection = "olmTitle"
|
||||
)
|
||||
default Title olmBombsTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bombDisplay",
|
||||
name = "Olm Bombs",
|
||||
description = "Display a timer and colour-coded AoE for Olm's crystal-phase bombs.",
|
||||
titleSection = "olmBombsTitle",
|
||||
position = 46
|
||||
)
|
||||
default boolean bombDisplay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bombDisplaynotify",
|
||||
name = "Olm Bombs Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Olm Bombs should trigger a notification",
|
||||
titleSection = "olmBombsTitle",
|
||||
position = 47,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean bombDisplayNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "olmlightningTitle",
|
||||
name = "Lightning Trails",
|
||||
description = "",
|
||||
position = 48,
|
||||
titleSection = "olmTitle"
|
||||
)
|
||||
default Title olmlightningTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lightning",
|
||||
name = "Olm Lightning Trails",
|
||||
description = "Show Lightning Trails",
|
||||
titleSection = "olmlightningTitle",
|
||||
position = 49
|
||||
)
|
||||
default boolean LightningTrail()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lightningnotify",
|
||||
name = "Olm Lightning Trails Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Olm Lightning Trails should trigger a notification",
|
||||
titleSection = "olmlightningTitle",
|
||||
position = 50,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean LightningTrailNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "corpTitle",
|
||||
name = "Corporeal Beast",
|
||||
description = "",
|
||||
position = 51,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title corpTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "corp",
|
||||
name = "Corporeal Beast",
|
||||
description = "Configures whether or not AoE Projectile Warnings for the Corporeal Beast are displayed",
|
||||
titleSection = "corpTitle",
|
||||
position = 52
|
||||
)
|
||||
default boolean isCorpEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "corpnotify",
|
||||
name = "Corporeal Beast Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Corporeal Beast should trigger a notification",
|
||||
titleSection = "corpTitle",
|
||||
position = 53,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isCorpNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "wintertodtTitle",
|
||||
name = "Wintertodt",
|
||||
description = "",
|
||||
position = 54,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title wintertodtTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "wintertodt",
|
||||
name = "Wintertodt Snow Fall",
|
||||
description = "Configures whether or not AOE Projectile Warnings for the Wintertodt snow fall are displayed",
|
||||
titleSection = "wintertodtTitle",
|
||||
position = 55
|
||||
)
|
||||
default boolean isWintertodtEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "wintertodtnotify",
|
||||
name = "Wintertodt Snow Fall Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Wintertodt Snow Fall Notify should trigger a notification",
|
||||
titleSection = "wintertodtTitle",
|
||||
position = 56,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isWintertodtNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "xarpusTitle",
|
||||
name = "Xarpus",
|
||||
description = "",
|
||||
position = 57,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title xarpusTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "isXarpusEnabled",
|
||||
name = "Xarpus",
|
||||
description = "Configures whether or not AOE Projectile Warnings for Xarpus are displayed",
|
||||
titleSection = "xarpusTitle",
|
||||
position = 58
|
||||
)
|
||||
default boolean isXarpusEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "isXarpusEnablednotify",
|
||||
name = "Xarpus Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Xarpus should trigger a notification",
|
||||
titleSection = "xarpusTitle",
|
||||
position = 59,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isXarpusNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "addyDragsTitle",
|
||||
name = "Addy Drags",
|
||||
description = "",
|
||||
position = 60,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title addyDragsTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "addyDrags",
|
||||
name = "Addy Drags",
|
||||
description = "Show Bad Areas",
|
||||
titleSection = "addyDragsTitle",
|
||||
position = 61
|
||||
)
|
||||
default boolean addyDrags()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "addyDragsnotify",
|
||||
name = "Addy Drags Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Addy Dragons should trigger a notification",
|
||||
titleSection = "addyDragsTitle",
|
||||
position = 62,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean addyDragsNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "drakeTitle",
|
||||
name = "Drakes",
|
||||
description = "",
|
||||
position = 63,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title drakeTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "drake",
|
||||
name = "Drakes Breath",
|
||||
description = "Configures if Drakes Breath tile markers are displayed",
|
||||
titleSection = "drakeTitle",
|
||||
position = 64
|
||||
)
|
||||
default boolean isDrakeEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "drakenotify",
|
||||
name = "Drakes Breath Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Drakes Breath should trigger a notification",
|
||||
titleSection = "drakeTitle",
|
||||
position = 65,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isDrakeNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "cerberusTitle",
|
||||
name = "Cerberus",
|
||||
description = "",
|
||||
position = 66,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title cerberusTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "cerbFire",
|
||||
name = "Cerberus Fire",
|
||||
description = "Configures if Cerberus fire tile markers are displayed",
|
||||
titleSection = "cerberusTitle",
|
||||
position = 67
|
||||
)
|
||||
default boolean isCerbFireEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "cerbFirenotify",
|
||||
name = "Cerberus Fire Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Cerberus his fire should trigger a notification",
|
||||
titleSection = "cerberusTitle",
|
||||
position = 68,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isCerbFireNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "demonicGorillaTitle",
|
||||
name = "Demonic Gorilla",
|
||||
description = "",
|
||||
position = 69,
|
||||
titleSection = "npcTitle"
|
||||
)
|
||||
default Title demonicGorillaTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "demonicGorilla",
|
||||
name = "Demonic Gorilla",
|
||||
description = "Configures if Demonic Gorilla boulder tile markers are displayed",
|
||||
titleSection = "demonicGorillaTitle",
|
||||
position = 70
|
||||
)
|
||||
default boolean isDemonicGorillaEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "demonicGorillaNotify",
|
||||
name = "Demonic Gorilla Notify",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Demonic Gorilla boulders should trigger a notification",
|
||||
titleSection = "demonicGorillaTitle",
|
||||
position = 71,
|
||||
hide = "aoeNotifyAll"
|
||||
)
|
||||
default boolean isDemonicGorillaNotifyEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Modified by farhan1666
|
||||
*
|
||||
* 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.aoewarnings;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
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.OverlayUtil;
|
||||
import static net.runelite.client.util.ColorUtil.setAlphaComponent;
|
||||
|
||||
@Singleton
|
||||
public class AoeWarningOverlay extends Overlay
|
||||
{
|
||||
private static final int FILL_START_ALPHA = 25;
|
||||
private static final int OUTLINE_START_ALPHA = 255;
|
||||
|
||||
private final Client client;
|
||||
private final AoeWarningPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public AoeWarningOverlay(final Client client, final AoeWarningPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
WorldPoint lp = client.getLocalPlayer().getWorldLocation();
|
||||
|
||||
plugin.getLightningTrail().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o, lp, new Color(0, 150, 200), 2, 150, 50));
|
||||
|
||||
plugin.getAcidTrail().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o.getWorldLocation(), lp, new Color(69, 241, 44), 2, 150, 50));
|
||||
|
||||
plugin.getCrystalSpike().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o.getWorldLocation(), lp, new Color(255, 0, 84), 2, 150, 50));
|
||||
|
||||
plugin.getWintertodtSnowFall().forEach(o ->
|
||||
OverlayUtil.drawTiles(graphics, client, o.getWorldLocation(), lp, new Color(255, 0, 84), 2, 150, 50));
|
||||
|
||||
Instant now = Instant.now();
|
||||
Set<ProjectileContainer> projectiles = plugin.getProjectiles();
|
||||
projectiles.forEach(proj ->
|
||||
{
|
||||
if (proj.getTargetPoint() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color color;
|
||||
|
||||
if (now.isAfter(proj.getStartTime().plus(Duration.ofMillis(proj.getLifetime()))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (proj.getProjectile().getId() == ProjectileID.ICE_DEMON_ICE_BARRAGE_AOE || proj.getProjectile().getId() == ProjectileID.TEKTON_METEOR_AOE)
|
||||
{
|
||||
if (client.getVar(Varbits.IN_RAID) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, proj.getTargetPoint(), proj.getAoeProjectileInfo().getAoeSize());
|
||||
|
||||
if (tilePoly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final double progress = (System.currentTimeMillis() - proj.getStartTime().toEpochMilli()) / (double) proj.getLifetime();
|
||||
|
||||
final int tickProgress = proj.getFinalTick() - client.getTickCount();
|
||||
|
||||
int fillAlpha, outlineAlpha;
|
||||
if (plugin.isConfigFadeEnabled())
|
||||
{
|
||||
fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);
|
||||
outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
fillAlpha = FILL_START_ALPHA;
|
||||
outlineAlpha = OUTLINE_START_ALPHA;
|
||||
}
|
||||
if (tickProgress == 0)
|
||||
{
|
||||
color = Color.RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.WHITE;
|
||||
}
|
||||
|
||||
if (fillAlpha < 0)
|
||||
{
|
||||
fillAlpha = 0;
|
||||
}
|
||||
if (outlineAlpha < 0)
|
||||
{
|
||||
outlineAlpha = 0;
|
||||
}
|
||||
|
||||
if (fillAlpha > 255)
|
||||
{
|
||||
fillAlpha = 255;
|
||||
}
|
||||
if (outlineAlpha > 255)
|
||||
{
|
||||
outlineAlpha = 255;
|
||||
}
|
||||
|
||||
if (plugin.isConfigOutlineEnabled())
|
||||
{
|
||||
graphics.setColor(new Color(setAlphaComponent(plugin.getOverlayColor().getRGB(), outlineAlpha), true));
|
||||
graphics.drawPolygon(tilePoly);
|
||||
}
|
||||
if (plugin.isTickTimers() && tickProgress >= 0)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, Integer.toString(tickProgress), plugin.getTextSize(),
|
||||
plugin.getFontStyle(), color, centerPoint(tilePoly.getBounds()), plugin.isShadows(), 0);
|
||||
}
|
||||
|
||||
graphics.setColor(new Color(setAlphaComponent(plugin.getOverlayColor().getRGB(), fillAlpha), true));
|
||||
graphics.fillPolygon(tilePoly);
|
||||
});
|
||||
projectiles.removeIf(proj -> now.isAfter(proj.getStartTime().plus(Duration.ofMillis(proj.getLifetime()))));
|
||||
return null;
|
||||
}
|
||||
|
||||
private Point centerPoint(Rectangle rect)
|
||||
{
|
||||
int x = (int) (rect.getX() + rect.getWidth() / 2);
|
||||
int y = (int) (rect.getY() + rect.getHeight() / 2);
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
@@ -1,496 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified by farhan1666
|
||||
*
|
||||
* 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.aoewarnings;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.NullObjectID;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "AoE Warnings",
|
||||
description = "Shows the final destination for AoE Attack projectiles",
|
||||
tags = {"bosses", "combat", "pve", "overlay"},
|
||||
type = PluginType.PVM,
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class AoeWarningPlugin extends Plugin
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<CrystalBomb> bombs = new HashSet<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<ProjectileContainer> projectiles = new HashSet<>();
|
||||
|
||||
@Inject
|
||||
public AoeWarningConfig config;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AoeWarningOverlay coreOverlay;
|
||||
|
||||
@Inject
|
||||
private BombOverlay bombOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> lightningTrail = new ArrayList<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<GameObject> acidTrail = new ArrayList<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<GameObject> crystalSpike = new ArrayList<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<GameObject> wintertodtSnowFall = new ArrayList<>();
|
||||
|
||||
// Config values
|
||||
private boolean aoeNotifyAll;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color overlayColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean configOutlineEnabled;
|
||||
private int delay;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean configFadeEnabled;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean tickTimers;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int fontStyle;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int textSize;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean shadows;
|
||||
private boolean configShamansEnabled;
|
||||
private boolean configShamansNotifyEnabled;
|
||||
private boolean configArchaeologistEnabled;
|
||||
private boolean configArchaeologistNotifyEnabled;
|
||||
private boolean configIceDemonEnabled;
|
||||
private boolean configIceDemonNotifyEnabled;
|
||||
private boolean configVasaEnabled;
|
||||
private boolean configVasaNotifyEnabled;
|
||||
private boolean configTektonEnabled;
|
||||
private boolean configTektonNotifyEnabled;
|
||||
private boolean configVorkathEnabled;
|
||||
private boolean configVorkathNotifyEnabled;
|
||||
private boolean configGalvekEnabled;
|
||||
private boolean configGalvekNotifyEnabled;
|
||||
private boolean configGargBossEnabled;
|
||||
private boolean configGargBossNotifyEnabled;
|
||||
private boolean configVetionEnabled;
|
||||
private boolean configVetionNotifyEnabled;
|
||||
private boolean configChaosFanaticEnabled;
|
||||
private boolean configChaosFanaticNotifyEnabled;
|
||||
private boolean configOlmEnabled;
|
||||
private boolean configOlmNotifyEnabled;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean configbombDisplay;
|
||||
private boolean configbombDisplayNotifyEnabled;
|
||||
private boolean configLightningTrail;
|
||||
private boolean configLightningTrailNotifyEnabled;
|
||||
private boolean configCorpEnabled;
|
||||
private boolean configCorpNotifyEnabled;
|
||||
private boolean configWintertodtEnabled;
|
||||
private boolean configWintertodtNotifyEnabled;
|
||||
private boolean configXarpusEnabled;
|
||||
private boolean configXarpusNotifyEnabled;
|
||||
private boolean configaddyDrags;
|
||||
private boolean configaddyDragsNotifyEnabled;
|
||||
private boolean configDrakeEnabled;
|
||||
private boolean configDrakeNotifyEnabled;
|
||||
private boolean configCerbFireEnabled;
|
||||
private boolean configCerbFireNotifyEnabled;
|
||||
private boolean configDemonicGorillaEnabled;
|
||||
private boolean configDemonicGorillaNotifyEnabled;
|
||||
|
||||
@Provides
|
||||
AoeWarningConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AoeWarningConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
overlayManager.add(coreOverlay);
|
||||
overlayManager.add(bombOverlay);
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
overlayManager.remove(coreOverlay);
|
||||
overlayManager.remove(bombOverlay);
|
||||
reset();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("aoe"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
final Projectile projectile = event.getProjectile();
|
||||
|
||||
if (AoeProjectileInfo.getById(projectile.getId()) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int id = projectile.getId();
|
||||
final int lifetime = this.delay + (projectile.getRemainingCycles() * 20);
|
||||
int ticksRemaining = projectile.getRemainingCycles() / 30;
|
||||
if (!isTickTimersEnabledForProjectileID(id))
|
||||
{
|
||||
ticksRemaining = 0;
|
||||
}
|
||||
final int tickCycle = client.getTickCount() + ticksRemaining;
|
||||
if (isConfigEnabledForProjectileId(id, false))
|
||||
{
|
||||
projectiles.add(new ProjectileContainer(projectile, Instant.now(), lifetime, tickCycle));
|
||||
|
||||
if (this.aoeNotifyAll || isConfigEnabledForProjectileId(id, true))
|
||||
{
|
||||
notifier.notify("AoE attack detected!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onProjectileMoved(ProjectileMoved event)
|
||||
{
|
||||
if (projectiles.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Projectile projectile = event.getProjectile();
|
||||
|
||||
projectiles.forEach(proj ->
|
||||
{
|
||||
if (proj.getProjectile() == projectile)
|
||||
{
|
||||
proj.setTargetPoint(event.getPosition());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
bombs.add(new CrystalBomb(gameObject, client.getTickCount()));
|
||||
|
||||
if (this.aoeNotifyAll || this.configbombDisplayNotifyEnabled)
|
||||
{
|
||||
notifier.notify("Bomb!");
|
||||
}
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
acidTrail.add(gameObject);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
crystalSpike.add(gameObject);
|
||||
break;
|
||||
case NullObjectID.NULL_26690:
|
||||
if (this.configWintertodtEnabled)
|
||||
{
|
||||
wintertodtSnowFall.add(gameObject);
|
||||
|
||||
if (this.aoeNotifyAll || this.configWintertodtNotifyEnabled)
|
||||
{
|
||||
notifier.notify("Snow Fall!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
bombs.removeIf(o -> o.getGameObject() == gameObject);
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
acidTrail.remove(gameObject);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
crystalSpike.remove(gameObject);
|
||||
break;
|
||||
case NullObjectID.NULL_26690:
|
||||
wintertodtSnowFall.remove(gameObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
lightningTrail.clear();
|
||||
|
||||
if (this.configLightningTrail)
|
||||
{
|
||||
client.getGraphicsObjects().forEach(o ->
|
||||
{
|
||||
if (o.getId() == GraphicID.OLM_LIGHTNING)
|
||||
{
|
||||
lightningTrail.add(WorldPoint.fromLocal(client, o.getLocation()));
|
||||
|
||||
if (this.aoeNotifyAll || this.configLightningTrailNotifyEnabled)
|
||||
{
|
||||
notifier.notify("Lightning!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bombs.forEach(CrystalBomb::bombClockUpdate);
|
||||
}
|
||||
|
||||
private boolean isTickTimersEnabledForProjectileID(int projectileId)
|
||||
{
|
||||
AoeProjectileInfo projectileInfo = AoeProjectileInfo.getById(projectileId);
|
||||
|
||||
if (projectileInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (projectileInfo)
|
||||
{
|
||||
case VASA_RANGED_AOE:
|
||||
case VORKATH_POISON_POOL:
|
||||
case VORKATH_SPAWN:
|
||||
case VORKATH_TICK_FIRE:
|
||||
case OLM_BURNING:
|
||||
case OLM_FALLING_CRYSTAL_TRAIL:
|
||||
case OLM_ACID_TRAIL:
|
||||
case OLM_FIRE_LINE:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isConfigEnabledForProjectileId(int projectileId, boolean notify)
|
||||
{
|
||||
AoeProjectileInfo projectileInfo = AoeProjectileInfo.getById(projectileId);
|
||||
if (projectileInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (notify && this.aoeNotifyAll)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (projectileInfo)
|
||||
{
|
||||
case LIZARDMAN_SHAMAN_AOE:
|
||||
return notify ? this.configShamansNotifyEnabled : this.configShamansEnabled;
|
||||
case CRAZY_ARCHAEOLOGIST_AOE:
|
||||
return notify ? this.configArchaeologistNotifyEnabled : this.configArchaeologistEnabled;
|
||||
case ICE_DEMON_RANGED_AOE:
|
||||
case ICE_DEMON_ICE_BARRAGE_AOE:
|
||||
return notify ? this.configIceDemonNotifyEnabled : this.configIceDemonEnabled;
|
||||
case VASA_AWAKEN_AOE:
|
||||
case VASA_RANGED_AOE:
|
||||
return notify ? this.configVasaNotifyEnabled : this.configVasaEnabled;
|
||||
case TEKTON_METEOR_AOE:
|
||||
return notify ? this.configTektonNotifyEnabled : this.configTektonEnabled;
|
||||
case VORKATH_BOMB:
|
||||
case VORKATH_POISON_POOL:
|
||||
case VORKATH_SPAWN:
|
||||
case VORKATH_TICK_FIRE:
|
||||
return notify ? this.configVorkathNotifyEnabled : this.configVorkathEnabled;
|
||||
case VETION_LIGHTNING:
|
||||
return notify ? this.configVetionNotifyEnabled : this.configVetionEnabled;
|
||||
case CHAOS_FANATIC:
|
||||
return notify ? this.configChaosFanaticNotifyEnabled : this.configChaosFanaticEnabled;
|
||||
case GALVEK_BOMB:
|
||||
case GALVEK_MINE:
|
||||
return notify ? this.configGalvekNotifyEnabled : this.configGalvekEnabled;
|
||||
case DAWN_FREEZE:
|
||||
case DUSK_CEILING:
|
||||
return notify ? this.configGargBossNotifyEnabled : this.configGargBossEnabled;
|
||||
case OLM_FALLING_CRYSTAL:
|
||||
case OLM_BURNING:
|
||||
case OLM_FALLING_CRYSTAL_TRAIL:
|
||||
case OLM_ACID_TRAIL:
|
||||
case OLM_FIRE_LINE:
|
||||
return notify ? this.configOlmNotifyEnabled : this.configOlmEnabled;
|
||||
case CORPOREAL_BEAST:
|
||||
case CORPOREAL_BEAST_DARK_CORE:
|
||||
return notify ? this.configCorpNotifyEnabled : this.configCorpEnabled;
|
||||
case XARPUS_POISON_AOE:
|
||||
return notify ? this.configXarpusNotifyEnabled : this.configXarpusEnabled;
|
||||
case ADDY_DRAG_POISON:
|
||||
return notify ? this.configaddyDragsNotifyEnabled : this.configaddyDrags;
|
||||
case DRAKE_BREATH:
|
||||
return notify ? this.configDrakeNotifyEnabled : this.configDrakeEnabled;
|
||||
case CERB_FIRE:
|
||||
return notify ? this.configCerbFireNotifyEnabled : this.configCerbFireEnabled;
|
||||
case DEMONIC_GORILLA_BOULDER:
|
||||
return notify ? this.configDemonicGorillaNotifyEnabled : this.configDemonicGorillaEnabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.aoeNotifyAll = config.aoeNotifyAll();
|
||||
this.overlayColor = config.overlayColor();
|
||||
this.configOutlineEnabled = config.isOutlineEnabled();
|
||||
this.delay = config.delay();
|
||||
this.configFadeEnabled = config.isFadeEnabled();
|
||||
this.tickTimers = config.tickTimers();
|
||||
this.fontStyle = config.fontStyle().getFont();
|
||||
this.textSize = config.textSize();
|
||||
this.shadows = config.shadows();
|
||||
this.configShamansEnabled = config.isShamansEnabled();
|
||||
this.configShamansNotifyEnabled = config.isShamansNotifyEnabled();
|
||||
this.configArchaeologistEnabled = config.isArchaeologistEnabled();
|
||||
this.configArchaeologistNotifyEnabled = config.isArchaeologistNotifyEnabled();
|
||||
this.configIceDemonEnabled = config.isIceDemonEnabled();
|
||||
this.configIceDemonNotifyEnabled = config.isIceDemonNotifyEnabled();
|
||||
this.configVasaEnabled = config.isVasaEnabled();
|
||||
this.configVasaNotifyEnabled = config.isVasaNotifyEnabled();
|
||||
this.configTektonEnabled = config.isTektonEnabled();
|
||||
this.configTektonNotifyEnabled = config.isTektonNotifyEnabled();
|
||||
this.configVorkathEnabled = config.isVorkathEnabled();
|
||||
this.configVorkathNotifyEnabled = config.isVorkathNotifyEnabled();
|
||||
this.configGalvekEnabled = config.isGalvekEnabled();
|
||||
this.configGalvekNotifyEnabled = config.isGalvekNotifyEnabled();
|
||||
this.configGargBossEnabled = config.isGargBossEnabled();
|
||||
this.configGargBossNotifyEnabled = config.isGargBossNotifyEnabled();
|
||||
this.configVetionEnabled = config.isVetionEnabled();
|
||||
this.configVetionNotifyEnabled = config.isVetionNotifyEnabled();
|
||||
this.configChaosFanaticEnabled = config.isChaosFanaticEnabled();
|
||||
this.configChaosFanaticNotifyEnabled = config.isChaosFanaticNotifyEnabled();
|
||||
this.configOlmEnabled = config.isOlmEnabled();
|
||||
this.configOlmNotifyEnabled = config.isOlmNotifyEnabled();
|
||||
this.configbombDisplay = config.bombDisplay();
|
||||
this.configbombDisplayNotifyEnabled = config.bombDisplayNotifyEnabled();
|
||||
this.configLightningTrail = config.LightningTrail();
|
||||
this.configLightningTrailNotifyEnabled = config.LightningTrailNotifyEnabled();
|
||||
this.configCorpEnabled = config.isCorpEnabled();
|
||||
this.configCorpNotifyEnabled = config.isCorpNotifyEnabled();
|
||||
this.configWintertodtEnabled = config.isWintertodtEnabled();
|
||||
this.configWintertodtNotifyEnabled = config.isWintertodtNotifyEnabled();
|
||||
this.configXarpusEnabled = config.isXarpusEnabled();
|
||||
this.configXarpusNotifyEnabled = config.isXarpusNotifyEnabled();
|
||||
this.configaddyDrags = config.addyDrags();
|
||||
this.configaddyDragsNotifyEnabled = config.addyDragsNotifyEnabled();
|
||||
this.configDrakeEnabled = config.isDrakeEnabled();
|
||||
this.configDrakeNotifyEnabled = config.isDrakeNotifyEnabled();
|
||||
this.configCerbFireEnabled = config.isCerbFireEnabled();
|
||||
this.configCerbFireNotifyEnabled = config.isCerbFireNotifyEnabled();
|
||||
this.configDemonicGorillaEnabled = config.isDemonicGorillaEnabled();
|
||||
this.configDemonicGorillaNotifyEnabled = config.isDemonicGorillaNotifyEnabled();
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
lightningTrail.clear();
|
||||
acidTrail.clear();
|
||||
crystalSpike.clear();
|
||||
wintertodtSnowFall.clear();
|
||||
bombs.clear();
|
||||
projectiles.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, PallasDieKatze (Pallas Cat)
|
||||
* 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.aoewarnings;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Locale;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.coords.WorldPoint;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class BombOverlay extends Overlay
|
||||
{
|
||||
|
||||
private static final String SAFE = "#00cc00";
|
||||
private static final String CAUTION = "#ffff00";
|
||||
private static final String WARNING = "#ff9933";
|
||||
private static final String DANGER = "#ff6600";
|
||||
private static final String LETHAL = "#cc0000";
|
||||
private static final int BOMB_AOE = 7;
|
||||
private static final int BOMB_DETONATE_TIME = 8;
|
||||
private static final double ESTIMATED_TICK_LENGTH = .6;
|
||||
private static final NumberFormat TIME_LEFT_FORMATTER =
|
||||
DecimalFormat.getInstance(Locale.US);
|
||||
|
||||
static
|
||||
{
|
||||
((DecimalFormat) TIME_LEFT_FORMATTER).applyPattern("#0.0");
|
||||
}
|
||||
|
||||
private final Client client;
|
||||
private final AoeWarningPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public BombOverlay(final Client client, final AoeWarningPlugin plugin)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (plugin.isConfigbombDisplay())
|
||||
{
|
||||
drawDangerZone(graphics);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawDangerZone(Graphics2D graphics)
|
||||
{
|
||||
final WorldPoint loc = client.getLocalPlayer().getWorldLocation();
|
||||
plugin.getBombs().forEach(bomb ->
|
||||
{
|
||||
final LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation());
|
||||
final WorldPoint worldLoc = bomb.getWorldLocation();
|
||||
|
||||
if (localLoc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final double distance_x = Math.abs(worldLoc.getX() - loc.getX());
|
||||
final double distance_y = Math.abs(worldLoc.getY() - loc.getY());
|
||||
|
||||
Color color_code = Color.decode(SAFE);
|
||||
|
||||
if (distance_x < 1 && distance_y < 1)
|
||||
{
|
||||
color_code = Color.decode(LETHAL);
|
||||
}
|
||||
else if (distance_x < 2 && distance_y < 2)
|
||||
{
|
||||
color_code = Color.decode(DANGER);
|
||||
}
|
||||
else if (distance_x < 3 && distance_y < 3)
|
||||
{
|
||||
color_code = Color.decode(WARNING);
|
||||
}
|
||||
else if (distance_x < 4 && distance_y < 4)
|
||||
{
|
||||
color_code = Color.decode(CAUTION);
|
||||
}
|
||||
final LocalPoint CenterPoint = new LocalPoint(localLoc.getX(), localLoc.getY());
|
||||
final Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
graphics.setColor(color_code);
|
||||
graphics.setStroke(new BasicStroke(1));
|
||||
graphics.drawPolygon(poly);
|
||||
graphics.setColor(new Color(0, 0, 0, 10));
|
||||
graphics.fillPolygon(poly);
|
||||
}
|
||||
|
||||
final Instant now = Instant.now();
|
||||
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() - bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
|
||||
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
|
||||
|
||||
timeLeft = Math.max(0.0, timeLeft);
|
||||
final String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
|
||||
final int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
|
||||
final int textHeight = graphics.getFontMetrics().getAscent();
|
||||
final Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(), localLoc.getY(), worldLoc.getPlane());
|
||||
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
Point canvasCenterPoint = new Point(canvasPoint.getX() - textWidth / 2, canvasPoint.getY() + textHeight / 2);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, PallasDieKatze (Pallas Cat)
|
||||
* 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.aoewarnings;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Slf4j
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class CrystalBomb
|
||||
{
|
||||
private GameObject gameObject;
|
||||
private Instant plantedOn;
|
||||
private Instant lastClockUpdate;
|
||||
private int objectId;
|
||||
private int tickStarted;
|
||||
private WorldPoint worldLocation;
|
||||
|
||||
CrystalBomb(GameObject gameObject, int startTick)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
this.objectId = gameObject.getId();
|
||||
this.plantedOn = Instant.now();
|
||||
this.worldLocation = gameObject.getWorldLocation();
|
||||
this.tickStarted = startTick;
|
||||
}
|
||||
|
||||
void bombClockUpdate()
|
||||
{
|
||||
lastClockUpdate = Instant.now();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class ProjectileContainer
|
||||
{
|
||||
private Projectile projectile;
|
||||
private Instant startTime;
|
||||
private AoeProjectileInfo aoeProjectileInfo;
|
||||
private int lifetime;
|
||||
private int finalTick;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private LocalPoint targetPoint;
|
||||
|
||||
ProjectileContainer(Projectile projectile, Instant startTime, int lifetime, int finalTick)
|
||||
{
|
||||
this.projectile = projectile;
|
||||
this.startTime = startTime;
|
||||
this.targetPoint = null;
|
||||
this.aoeProjectileInfo = AoeProjectileInfo.getById(projectile.getId());
|
||||
this.lifetime = lifetime;
|
||||
this.finalTick = finalTick;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.attackstyles;
|
||||
|
||||
import net.runelite.api.Skill;
|
||||
|
||||
public enum AttackStyle
|
||||
{
|
||||
ACCURATE("Accurate", Skill.ATTACK),
|
||||
AGGRESSIVE("Aggressive", Skill.STRENGTH),
|
||||
DEFENSIVE("Defensive", Skill.DEFENCE),
|
||||
CONTROLLED("Controlled", Skill.ATTACK, Skill.STRENGTH, Skill.DEFENCE),
|
||||
RANGING("Ranging", Skill.RANGED),
|
||||
LONGRANGE("Longrange", Skill.RANGED, Skill.DEFENCE),
|
||||
CASTING("Casting", Skill.MAGIC),
|
||||
DEFENSIVE_CASTING("Defensive Casting", Skill.MAGIC, Skill.DEFENCE),
|
||||
OTHER("Other");
|
||||
|
||||
private final String name;
|
||||
private final Skill[] skills;
|
||||
|
||||
AttackStyle(String name, Skill... skills)
|
||||
{
|
||||
this.name = name;
|
||||
this.skills = skills;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public Skill[] getSkills()
|
||||
{
|
||||
return skills;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.attackstyles;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("attackIndicator")
|
||||
public interface AttackStylesConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "alwaysShowStyle",
|
||||
name = "Always show style",
|
||||
description = "Show attack style indicator at all times",
|
||||
position = 1
|
||||
)
|
||||
default boolean alwaysShowStyle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warnForDefensive",
|
||||
name = "Warn for defence",
|
||||
description = "Show warning when a Defence skill combat option is selected",
|
||||
position = 2
|
||||
)
|
||||
default boolean warnForDefence()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warnForAttack",
|
||||
name = "Warn for attack",
|
||||
description = "Show warning when an Attack skill combat option is selected",
|
||||
position = 3
|
||||
)
|
||||
default boolean warnForAttack()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warnForStrength",
|
||||
name = "Warn for strength",
|
||||
description = "Show warning when a Strength skill combat option is selected",
|
||||
position = 4
|
||||
)
|
||||
default boolean warnForStrength()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warnForRanged",
|
||||
name = "Warn for ranged",
|
||||
description = "Show warning when a Ranged skill combat option is selected",
|
||||
position = 5
|
||||
)
|
||||
default boolean warnForRanged()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warnForMagic",
|
||||
name = "Warn for magic",
|
||||
description = "Show warning when a Magic skill combat option is selected",
|
||||
position = 6
|
||||
)
|
||||
default boolean warnForMagic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideAutoRetaliate",
|
||||
name = "Hide auto retaliate",
|
||||
description = "Hide auto retaliate from the combat options tab",
|
||||
position = 7
|
||||
)
|
||||
default boolean hideAutoRetaliate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeWarnedStyles",
|
||||
name = "Remove warned styles",
|
||||
description = "Remove warned styles from the combat options tab",
|
||||
position = 8
|
||||
)
|
||||
default boolean removeWarnedStyles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.attackstyles;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@Singleton
|
||||
class AttackStylesOverlay extends Overlay
|
||||
{
|
||||
private final AttackStylesPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private AttackStylesOverlay(final AttackStylesPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT);
|
||||
this.plugin = plugin;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Attack style overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
panelComponent.getChildren().clear();
|
||||
boolean warnedSkillSelected = plugin.isWarnedSkillSelected();
|
||||
|
||||
if (warnedSkillSelected || plugin.isAlwaysShowStyle())
|
||||
{
|
||||
final AttackStyle attackStyle = plugin.getAttackStyle();
|
||||
|
||||
if (attackStyle == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final String attackStyleString = attackStyle.getName();
|
||||
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(attackStyleString)
|
||||
.color(warnedSkillSelected ? Color.RED : Color.WHITE)
|
||||
.build());
|
||||
|
||||
panelComponent.setPreferredSize(new Dimension(
|
||||
graphics.getFontMetrics().stringWidth(attackStyleString) + 10,
|
||||
0));
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,416 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.attackstyles;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetHiddenChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetID.COMBAT_GROUP_ID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Attack Styles",
|
||||
description = "Show your current attack style as an overlay",
|
||||
tags = {"combat", "defence", "magic", "overlay", "ranged", "strength", "warn", "pure"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
@Singleton
|
||||
public class AttackStylesPlugin extends Plugin
|
||||
{
|
||||
private int attackStyleVarbit = -1;
|
||||
private int equippedWeaponTypeVarbit = -1;
|
||||
private int castingModeVarbit = -1;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Nullable
|
||||
private AttackStyle attackStyle;
|
||||
private final Set<Skill> warnedSkills = new HashSet<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean warnedSkillSelected = false;
|
||||
private final Table<WeaponType, WidgetInfo, Boolean> widgetsToHide = HashBasedTable.create();
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private AttackStylesConfig config;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AttackStylesOverlay overlay;
|
||||
|
||||
@Provides
|
||||
AttackStylesConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AttackStylesConfig.class);
|
||||
}
|
||||
|
||||
// config values
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean alwaysShowStyle;
|
||||
private boolean warnForDefence;
|
||||
private boolean warnForAttack;
|
||||
private boolean warnForStrength;
|
||||
private boolean warnForRanged;
|
||||
private boolean warnForMagic;
|
||||
private boolean hideAutoRetaliate;
|
||||
@VisibleForTesting
|
||||
boolean removeWarnedStyles;
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
overlayManager.add(overlay);
|
||||
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
clientThread.invoke(this::start);
|
||||
}
|
||||
}
|
||||
|
||||
private void start()
|
||||
{
|
||||
resetWarnings();
|
||||
|
||||
attackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
equippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
castingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
updateAttackStyle(
|
||||
equippedWeaponTypeVarbit,
|
||||
attackStyleVarbit,
|
||||
castingModeVarbit);
|
||||
updateWarning(false);
|
||||
processWidgets();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
hideWarnedStyles(false);
|
||||
processWidgets();
|
||||
hideWidget(client.getWidget(WidgetInfo.COMBAT_AUTO_RETALIATE), false);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@VisibleForTesting
|
||||
void onWidgetHiddenChanged(WidgetHiddenChanged event)
|
||||
{
|
||||
if (event.getWidget().isSelfHidden() || TO_GROUP(event.getWidget().getId()) != COMBAT_GROUP_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
processWidgets();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() != COMBAT_GROUP_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
processWidgets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide or unhide widgets depending on widgetsToHide
|
||||
*/
|
||||
private void processWidgets()
|
||||
{
|
||||
WeaponType equippedWeaponType = WeaponType.getWeaponType(equippedWeaponTypeVarbit);
|
||||
|
||||
if (widgetsToHide.containsRow(equippedWeaponType))
|
||||
{
|
||||
for (WidgetInfo widgetKey : widgetsToHide.row(equippedWeaponType).keySet())
|
||||
{
|
||||
hideWidget(client.getWidget(widgetKey), widgetsToHide.get(equippedWeaponType, widgetKey));
|
||||
}
|
||||
}
|
||||
hideWidget(client.getWidget(WidgetInfo.COMBAT_AUTO_RETALIATE), this.hideAutoRetaliate);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
resetWarnings();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@VisibleForTesting
|
||||
void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
int currentAttackStyleVarbit = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||
int currentEquippedWeaponTypeVarbit = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||
int currentCastingModeVarbit = client.getVar(Varbits.DEFENSIVE_CASTING_MODE);
|
||||
|
||||
if (attackStyleVarbit != currentAttackStyleVarbit || equippedWeaponTypeVarbit != currentEquippedWeaponTypeVarbit || castingModeVarbit != currentCastingModeVarbit)
|
||||
{
|
||||
boolean weaponSwitch = currentEquippedWeaponTypeVarbit != equippedWeaponTypeVarbit;
|
||||
|
||||
attackStyleVarbit = currentAttackStyleVarbit;
|
||||
equippedWeaponTypeVarbit = currentEquippedWeaponTypeVarbit;
|
||||
castingModeVarbit = currentCastingModeVarbit;
|
||||
|
||||
updateAttackStyle(equippedWeaponTypeVarbit, attackStyleVarbit,
|
||||
castingModeVarbit);
|
||||
updateWarning(weaponSwitch);
|
||||
|
||||
if (weaponSwitch)
|
||||
{
|
||||
processWidgets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@VisibleForTesting
|
||||
void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("attackIndicator"))
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
boolean enabled = event.getNewValue().equals("true");
|
||||
switch (event.getKey())
|
||||
{
|
||||
case "warnForDefensive":
|
||||
updateWarnedSkills(enabled, Skill.DEFENCE);
|
||||
break;
|
||||
case "warnForAttack":
|
||||
updateWarnedSkills(enabled, Skill.ATTACK);
|
||||
break;
|
||||
case "warnForStrength":
|
||||
updateWarnedSkills(enabled, Skill.STRENGTH);
|
||||
break;
|
||||
case "warnForRanged":
|
||||
updateWarnedSkills(enabled, Skill.RANGED);
|
||||
break;
|
||||
case "warnForMagic":
|
||||
updateWarnedSkills(enabled, Skill.MAGIC);
|
||||
break;
|
||||
case "removeWarnedStyles":
|
||||
hideWarnedStyles(enabled);
|
||||
break;
|
||||
}
|
||||
processWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.alwaysShowStyle = config.alwaysShowStyle();
|
||||
this.warnForDefence = config.warnForDefence();
|
||||
this.warnForAttack = config.warnForAttack();
|
||||
this.warnForStrength = config.warnForStrength();
|
||||
this.warnForRanged = config.warnForRanged();
|
||||
this.warnForMagic = config.warnForMagic();
|
||||
this.hideAutoRetaliate = config.hideAutoRetaliate();
|
||||
this.removeWarnedStyles = config.removeWarnedStyles();
|
||||
}
|
||||
|
||||
private void resetWarnings()
|
||||
{
|
||||
updateWarnedSkills(this.warnForAttack, Skill.ATTACK);
|
||||
updateWarnedSkills(this.warnForStrength, Skill.STRENGTH);
|
||||
updateWarnedSkills(this.warnForDefence, Skill.DEFENCE);
|
||||
updateWarnedSkills(this.warnForRanged, Skill.RANGED);
|
||||
updateWarnedSkills(this.warnForMagic, Skill.MAGIC);
|
||||
}
|
||||
|
||||
private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode)
|
||||
{
|
||||
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles();
|
||||
if (attackStyleIndex < attackStyles.length)
|
||||
{
|
||||
attackStyle = attackStyles[attackStyleIndex];
|
||||
if (attackStyle == null)
|
||||
{
|
||||
attackStyle = OTHER;
|
||||
}
|
||||
else if ((attackStyle == CASTING) && (castingMode == 1))
|
||||
{
|
||||
attackStyle = DEFENSIVE_CASTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWarnedSkills(boolean enabled, Skill skill)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
warnedSkills.add(skill);
|
||||
}
|
||||
else
|
||||
{
|
||||
warnedSkills.remove(skill);
|
||||
}
|
||||
updateWarning(false);
|
||||
}
|
||||
|
||||
private void updateWarning(boolean weaponSwitch)
|
||||
{
|
||||
warnedSkillSelected = false;
|
||||
if (attackStyle != null)
|
||||
{
|
||||
for (Skill skill : attackStyle.getSkills())
|
||||
{
|
||||
if (warnedSkills.contains(skill))
|
||||
{
|
||||
// if (weaponSwitch)
|
||||
// {
|
||||
// // TODO : chat message to warn players that their weapon switch also caused an unwanted attack style change
|
||||
// }
|
||||
warnedSkillSelected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
hideWarnedStyles(this.removeWarnedStyles);
|
||||
}
|
||||
|
||||
private void hideWarnedStyles(boolean enabled)
|
||||
{
|
||||
WeaponType equippedWeaponType = WeaponType.getWeaponType(equippedWeaponTypeVarbit);
|
||||
if (equippedWeaponType == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AttackStyle[] attackStyles = equippedWeaponType.getAttackStyles();
|
||||
|
||||
// Iterate over attack styles
|
||||
for (int i = 0; i < attackStyles.length; i++)
|
||||
{
|
||||
AttackStyle attackStyle = attackStyles[i];
|
||||
if (attackStyle == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean warnedSkill = false;
|
||||
for (Skill skill : attackStyle.getSkills())
|
||||
{
|
||||
if (warnedSkills.contains(skill))
|
||||
{
|
||||
warnedSkill = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Magic staves defensive casting mode
|
||||
if (attackStyle == AttackStyle.DEFENSIVE_CASTING || !enabled)
|
||||
{
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_BOX, enabled && warnedSkill);
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_ICON, enabled && warnedSkill);
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_SHIELD, enabled && warnedSkill);
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_TEXT, enabled && warnedSkill);
|
||||
}
|
||||
|
||||
// Remove appropriate combat option
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_ONE, enabled && warnedSkill);
|
||||
break;
|
||||
case 1:
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_TWO, enabled && warnedSkill);
|
||||
break;
|
||||
case 2:
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_THREE, enabled && warnedSkill);
|
||||
break;
|
||||
case 3:
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_FOUR, enabled && warnedSkill);
|
||||
break;
|
||||
case 4:
|
||||
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_SPELLS, enabled && warnedSkill);
|
||||
break;
|
||||
default:
|
||||
// 5 can be defensive casting
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hideWidget(Widget widget, boolean hidden)
|
||||
{
|
||||
if (widget != null)
|
||||
{
|
||||
widget.setHidden(hidden);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Set<Skill> getWarnedSkills()
|
||||
{
|
||||
return warnedSkills;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Table<WeaponType, WidgetInfo, Boolean> getHiddenWidgets()
|
||||
{
|
||||
return widgetsToHide;
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
|
||||
* 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.attackstyles;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.ACCURATE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.AGGRESSIVE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.CONTROLLED;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.LONGRANGE;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER;
|
||||
import static net.runelite.client.plugins.attackstyles.AttackStyle.RANGING;
|
||||
|
||||
public enum WeaponType
|
||||
{
|
||||
TYPE_0(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
|
||||
TYPE_1(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
TYPE_2(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
|
||||
TYPE_3(RANGING, RANGING, null, LONGRANGE),
|
||||
TYPE_4(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
|
||||
TYPE_5(RANGING, RANGING, null, LONGRANGE),
|
||||
TYPE_6(AGGRESSIVE, RANGING, DEFENSIVE_CASTING, null),
|
||||
TYPE_7(RANGING, RANGING, null, LONGRANGE),
|
||||
TYPE_8(OTHER, AGGRESSIVE, null, null),
|
||||
TYPE_9(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
|
||||
TYPE_10(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
TYPE_11(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
TYPE_12(CONTROLLED, AGGRESSIVE, null, DEFENSIVE),
|
||||
TYPE_13(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
|
||||
TYPE_14(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
TYPE_15(CONTROLLED, CONTROLLED, CONTROLLED, DEFENSIVE),
|
||||
TYPE_16(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
|
||||
TYPE_17(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
TYPE_18(ACCURATE, AGGRESSIVE, null, DEFENSIVE, CASTING, DEFENSIVE_CASTING),
|
||||
TYPE_19(RANGING, RANGING, null, LONGRANGE),
|
||||
TYPE_20(ACCURATE, CONTROLLED, null, DEFENSIVE),
|
||||
TYPE_21(ACCURATE, AGGRESSIVE, null, DEFENSIVE, CASTING, DEFENSIVE_CASTING),
|
||||
TYPE_22(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||
TYPE_23(CASTING, CASTING, null, DEFENSIVE_CASTING),
|
||||
TYPE_24(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
|
||||
TYPE_25(CONTROLLED, AGGRESSIVE, null, DEFENSIVE),
|
||||
TYPE_26(AGGRESSIVE, AGGRESSIVE, null, AGGRESSIVE),
|
||||
TYPE_27(ACCURATE, null, null, OTHER);
|
||||
|
||||
private final AttackStyle[] attackStyles;
|
||||
|
||||
private static final Map<Integer, WeaponType> weaponTypes;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, WeaponType> builder = new ImmutableMap.Builder<>();
|
||||
|
||||
for (WeaponType weaponType : values())
|
||||
{
|
||||
builder.put(weaponType.ordinal(), weaponType);
|
||||
}
|
||||
|
||||
weaponTypes = builder.build();
|
||||
}
|
||||
|
||||
WeaponType(AttackStyle... attackStyles)
|
||||
{
|
||||
this.attackStyles = attackStyles;
|
||||
}
|
||||
|
||||
public AttackStyle[] getAttackStyles()
|
||||
{
|
||||
return attackStyles;
|
||||
}
|
||||
|
||||
public static WeaponType getWeaponType(int id)
|
||||
{
|
||||
return weaponTypes.get(id);
|
||||
}
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheLonelyDev <https://github.com/TheLonelyDev>
|
||||
* Copyright (c) 2018, Jeremy Plsek <https://github.com/jplsek>
|
||||
* 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.bank;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigSection;
|
||||
|
||||
@ConfigGroup("bank")
|
||||
public interface BankConfig extends Config
|
||||
{
|
||||
@ConfigSection(
|
||||
name = "Show Values",
|
||||
description = "",
|
||||
position = 0,
|
||||
keyName = "ValueSection"
|
||||
)
|
||||
default boolean ValueSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigSection(
|
||||
name = "Disable Left Click",
|
||||
description = "",
|
||||
position = 1,
|
||||
keyName = "DisableLClickSection"
|
||||
)
|
||||
default boolean DisableLClickSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigSection(
|
||||
name = "Bank Pin",
|
||||
description = "",
|
||||
position = 2,
|
||||
keyName = "BankPinSection"
|
||||
)
|
||||
default boolean BankPinSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showGE",
|
||||
name = "Show Grand Exchange price",
|
||||
description = "Show grand exchange price total (GE)",
|
||||
position = 0,
|
||||
section = "ValueSection"
|
||||
)
|
||||
default boolean showGE()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHA",
|
||||
name = "Show high alchemy price",
|
||||
description = "Show high alchemy price total (HA)",
|
||||
position = 2,
|
||||
section = "ValueSection"
|
||||
)
|
||||
default boolean showHA()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showExact",
|
||||
name = "Show exact bank value",
|
||||
description = "Show exact bank value",
|
||||
position = 3,
|
||||
section = "ValueSection"
|
||||
)
|
||||
default boolean showExact()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "seedVaultValue",
|
||||
name = "Show seed vault value",
|
||||
description = "Adds the total value of all seeds inside the seed vault to the title",
|
||||
position = 4,
|
||||
section = "ValueSection"
|
||||
)
|
||||
default boolean seedVaultValue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickBankInventory",
|
||||
name = "Disable left click bank inventory",
|
||||
description = "Configures whether the bank inventory button will bank your inventory on left click",
|
||||
position = 0,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickBankInventory()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickBankEquip",
|
||||
name = "Disable left click bank equipment",
|
||||
description = "Configures whether the bank equipment button will bank your equipment on left click",
|
||||
position = 1,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickBankEquip()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickBankLoot",
|
||||
name = "Disable left click bank looting bag",
|
||||
description = "Configures whether the bank looting bag button will bank your looting bag contents on left click",
|
||||
position = 2,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickBankLoot()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickSetPlaceholders",
|
||||
name = "Disable left click set placeholders",
|
||||
description = "Configures whether the set bank placeholder button will be on left click",
|
||||
position = 3,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickSetPlaceholders()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickReleasePlaceholders",
|
||||
name = "Disable left click release placeholder",
|
||||
description = "Configures whether the release bank placeholder button will be on left click",
|
||||
position = 4,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickReleasePlaceholders()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickFillBankFiller",
|
||||
name = "Disable left click fill bank fillers",
|
||||
description = "Configures whether the fill bank fillers button will be on left click",
|
||||
position = 5,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickFillBankFiller()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightClickSearch",
|
||||
name = "Disable left click search",
|
||||
description = "Configures whether the search button will search on left click",
|
||||
position = 6,
|
||||
section = "DisableLClickSection"
|
||||
)
|
||||
default boolean rightClickSearch()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "largePinNumbers",
|
||||
name = "Large bank pin numbers",
|
||||
description = "Enlarges and centers the numbers inside the bank pin buttons",
|
||||
position = 0,
|
||||
section = "BankPinSection"
|
||||
)
|
||||
default boolean largePinNumbers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,597 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheLonelyDev <https://github.com/TheLonelyDev>
|
||||
* Copyright (c) 2018, Jeremy Plsek <https://github.com/jplsek>
|
||||
* Copyright (c) 2019, Hydrox6 <ikada@protonmail.ch>
|
||||
* 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.bank;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Multiset;
|
||||
import com.google.inject.Provides;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.HIGH_ALCHEMY_MULTIPLIER;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.VarClientStr;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuShouldLeftClick;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.events.VarClientStrChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.plugins.banktags.tabs.BankSearch;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Bank",
|
||||
description = "Modifications to the banking interface",
|
||||
tags = {"grand", "exchange", "high", "alchemy", "prices", "deposit"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
@Singleton
|
||||
public class BankPlugin extends Plugin
|
||||
{
|
||||
private static final List<Varbits> TAB_VARBITS = ImmutableList.of(
|
||||
Varbits.BANK_TAB_ONE_COUNT,
|
||||
Varbits.BANK_TAB_TWO_COUNT,
|
||||
Varbits.BANK_TAB_THREE_COUNT,
|
||||
Varbits.BANK_TAB_FOUR_COUNT,
|
||||
Varbits.BANK_TAB_FIVE_COUNT,
|
||||
Varbits.BANK_TAB_SIX_COUNT,
|
||||
Varbits.BANK_TAB_SEVEN_COUNT,
|
||||
Varbits.BANK_TAB_EIGHT_COUNT,
|
||||
Varbits.BANK_TAB_NINE_COUNT
|
||||
);
|
||||
|
||||
private static final List<WidgetInfo> BANK_PINS = ImmutableList.of(
|
||||
WidgetInfo.BANK_PIN_1,
|
||||
WidgetInfo.BANK_PIN_2,
|
||||
WidgetInfo.BANK_PIN_3,
|
||||
WidgetInfo.BANK_PIN_4,
|
||||
WidgetInfo.BANK_PIN_5,
|
||||
WidgetInfo.BANK_PIN_6,
|
||||
WidgetInfo.BANK_PIN_7,
|
||||
WidgetInfo.BANK_PIN_8,
|
||||
WidgetInfo.BANK_PIN_9,
|
||||
WidgetInfo.BANK_PIN_10
|
||||
);
|
||||
|
||||
private static final String DEPOSIT_WORN = "Deposit worn items";
|
||||
private static final String DEPOSIT_INVENTORY = "Deposit inventory";
|
||||
private static final String DEPOSIT_LOOT = "Deposit loot";
|
||||
private static final String DISABLE = "Disable";
|
||||
private static final String ENABLE = "Enable";
|
||||
private static final String RELEASE_ALL_PLACEHOLDERS = "Release all placeholders";
|
||||
private static final String SEARCH = "Search";
|
||||
private static final String FILL = "Fill";
|
||||
|
||||
private static final String SEED_VAULT_TITLE = "Seed Vault";
|
||||
private static final int PIN_FONT_OFFSET = 5;
|
||||
|
||||
private static final String NUMBER_REGEX = "[0-9]+(\\.[0-9]+)?[kmb]?";
|
||||
private static final Pattern VALUE_SEARCH_PATTERN = Pattern.compile("^(?<mode>ge|ha|alch)?" +
|
||||
" *(((?<op>[<>=]|>=|<=) *(?<num>" + NUMBER_REGEX + "))|" +
|
||||
"((?<num1>" + NUMBER_REGEX + ") *- *(?<num2>" + NUMBER_REGEX + ")))$", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private BankConfig config;
|
||||
|
||||
@Inject
|
||||
private BankSearch bankSearch;
|
||||
|
||||
@Inject
|
||||
private ContainerCalculation bankCalculation;
|
||||
|
||||
@Inject
|
||||
private ContainerCalculation seedVaultCalculation;
|
||||
|
||||
private boolean forceRightClickFlag;
|
||||
private boolean largePinNumbers;
|
||||
private Multiset<Integer> itemQuantities; // bank item quantities for bank value search
|
||||
private String searchString;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showGE;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showHA;
|
||||
private boolean showExact;
|
||||
private boolean rightClickBankInventory;
|
||||
private boolean rightClickBankEquip;
|
||||
private boolean rightClickBankLoot;
|
||||
private boolean seedVaultValue;
|
||||
private boolean rightClickSetPlaceholders;
|
||||
private boolean rightClickReleasePlaceholders;
|
||||
private boolean rightClickSearch;
|
||||
private boolean rightClickFillBankFiller;
|
||||
|
||||
@Provides
|
||||
BankConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BankConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
searchString = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
clientThread.invokeLater(() -> bankSearch.reset(false));
|
||||
forceRightClickFlag = false;
|
||||
itemQuantities = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onMenuShouldLeftClick(MenuShouldLeftClick event)
|
||||
{
|
||||
if (!forceRightClickFlag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
forceRightClickFlag = false;
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if ((entry.getOption().equals(DEPOSIT_WORN) && this.rightClickBankEquip)
|
||||
|| (entry.getOption().equals(DEPOSIT_INVENTORY) && this.rightClickBankInventory)
|
||||
|| (entry.getOption().equals(DEPOSIT_LOOT) && this.rightClickBankLoot)
|
||||
|| (entry.getOption().equals(DISABLE) && this.rightClickSetPlaceholders)
|
||||
|| (entry.getOption().equals(ENABLE) && this.rightClickSetPlaceholders)
|
||||
|| (entry.getOption().equals(RELEASE_ALL_PLACEHOLDERS) && this.rightClickReleasePlaceholders)
|
||||
|| (entry.getOption().equals(SEARCH) && this.rightClickSearch)
|
||||
|| (entry.getOption().equals(FILL) && this.rightClickFillBankFiller))
|
||||
{
|
||||
event.setForceRightClick(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if ((event.getOption().equals(DEPOSIT_WORN) && this.rightClickBankEquip)
|
||||
|| (event.getOption().equals(DEPOSIT_INVENTORY) && this.rightClickBankInventory)
|
||||
|| (event.getOption().equals(DEPOSIT_LOOT) && this.rightClickBankLoot)
|
||||
|| (event.getOption().startsWith(DISABLE) && this.rightClickSetPlaceholders)
|
||||
|| (event.getOption().startsWith(ENABLE) && this.rightClickSetPlaceholders)
|
||||
|| (event.getOption().equals(RELEASE_ALL_PLACEHOLDERS) && this.rightClickReleasePlaceholders)
|
||||
|| (event.getOption().equals(SEARCH) && this.rightClickSearch)
|
||||
|| (event.getOption().equals(FILL) && this.rightClickFillBankFiller))
|
||||
{
|
||||
forceRightClickFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (event.getEventName().equals("bankPinButtons") && this.largePinNumbers)
|
||||
{
|
||||
updateBankPinSizes();
|
||||
}
|
||||
|
||||
if (!event.getEventName().equals("setBankTitle"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int[] intStack = client.getIntStack();
|
||||
String[] stringStack = client.getStringStack();
|
||||
int intStackSize = client.getIntStackSize();
|
||||
int stringStackSize = client.getStringStackSize();
|
||||
|
||||
switch (event.getEventName())
|
||||
{
|
||||
case "setBankTitle":
|
||||
final ContainerPrices prices = bankCalculation.calculate(getBankTabItems());
|
||||
if (prices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String strCurrentTab = createValueText(prices);
|
||||
|
||||
stringStack[stringStackSize - 1] += strCurrentTab;
|
||||
break;
|
||||
case "bankSearchFilter":
|
||||
int itemId = intStack[intStackSize - 1];
|
||||
String search = stringStack[stringStackSize - 1];
|
||||
|
||||
if (valueSearch(itemId, search))
|
||||
{
|
||||
// return true
|
||||
intStack[intStackSize - 2] = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() != WidgetID.SEED_VAULT_GROUP_ID || !this.seedVaultValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
updateSeedVaultTotal();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarClientStrChanged(VarClientStrChanged event)
|
||||
{
|
||||
String searchVar = client.getVar(VarClientStr.INPUT_TEXT);
|
||||
|
||||
if (!searchVar.equals(searchString))
|
||||
{
|
||||
Widget searchButtonBackground = client.getWidget(WidgetInfo.BANK_SEARCH_BUTTON_BACKGROUND);
|
||||
if (searchButtonBackground != null && searchButtonBackground.hasListener())
|
||||
{
|
||||
searchButtonBackground.setOnTimerListener((Object[]) null);
|
||||
searchButtonBackground.setHasListener(false);
|
||||
}
|
||||
|
||||
clientThread.invokeLater(() -> bankSearch.layoutBank());
|
||||
searchString = searchVar;
|
||||
}
|
||||
|
||||
if (client.getVar(VarClientInt.INPUT_TYPE) != InputType.SEARCH.getType() && Strings.isNullOrEmpty(client.getVar(VarClientStr.INPUT_TEXT)))
|
||||
{
|
||||
Widget searchBackground = client.getWidget(WidgetInfo.BANK_SEARCH_BUTTON_BACKGROUND);
|
||||
if (searchBackground != null)
|
||||
{
|
||||
searchBackground.setSpriteId(SpriteID.EQUIPMENT_SLOT_TILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemContainerChanged(ItemContainerChanged event)
|
||||
{
|
||||
int containerId = event.getContainerId();
|
||||
|
||||
if (containerId == InventoryID.BANK.getId())
|
||||
{
|
||||
itemQuantities = null;
|
||||
}
|
||||
else if (containerId == InventoryID.SEED_VAULT.getId() && this.seedVaultValue)
|
||||
{
|
||||
updateSeedVaultTotal();
|
||||
}
|
||||
}
|
||||
|
||||
private String createValueText(final ContainerPrices prices)
|
||||
{
|
||||
final long gePrice = prices.getGePrice();
|
||||
final long haPrice = prices.getHighAlchPrice();
|
||||
|
||||
String strCurrentTab = "";
|
||||
if (this.showGE && gePrice != 0)
|
||||
{
|
||||
strCurrentTab += " (";
|
||||
|
||||
if (this.showHA)
|
||||
{
|
||||
strCurrentTab += "EX: ";
|
||||
}
|
||||
|
||||
if (this.showExact)
|
||||
{
|
||||
strCurrentTab += QuantityFormatter.formatNumber(gePrice) + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
strCurrentTab += QuantityFormatter.quantityToStackSize(gePrice) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
if (this.showHA && haPrice != 0)
|
||||
{
|
||||
strCurrentTab += " (";
|
||||
|
||||
if (this.showGE)
|
||||
{
|
||||
strCurrentTab += "HA: ";
|
||||
}
|
||||
|
||||
if (this.showExact)
|
||||
{
|
||||
strCurrentTab += QuantityFormatter.formatNumber(haPrice) + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
strCurrentTab += QuantityFormatter.quantityToStackSize(haPrice) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
return strCurrentTab;
|
||||
}
|
||||
|
||||
private Item[] getBankTabItems()
|
||||
{
|
||||
final ItemContainer container = client.getItemContainer(InventoryID.BANK);
|
||||
if (container == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Item[] items = container.getItems();
|
||||
int currentTab = client.getVar(Varbits.CURRENT_BANK_TAB);
|
||||
|
||||
if (currentTab > 0)
|
||||
{
|
||||
int startIndex = 0;
|
||||
|
||||
for (int i = currentTab - 1; i > 0; i--)
|
||||
{
|
||||
startIndex += client.getVar(TAB_VARBITS.get(i - 1));
|
||||
}
|
||||
|
||||
int itemCount = client.getVar(TAB_VARBITS.get(currentTab - 1));
|
||||
return Arrays.copyOfRange(items, startIndex, startIndex + itemCount);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private void updateSeedVaultTotal()
|
||||
{
|
||||
final Widget titleContainer = client.getWidget(WidgetInfo.SEED_VAULT_TITLE_CONTAINER);
|
||||
if (titleContainer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Widget[] children = titleContainer.getDynamicChildren();
|
||||
if (children == null || children.length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final ContainerPrices prices = seedVaultCalculation.calculate(getSeedVaultItems());
|
||||
if (prices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String titleText = createValueText(prices);
|
||||
|
||||
final Widget title = children[1];
|
||||
title.setText(SEED_VAULT_TITLE + titleText);
|
||||
}
|
||||
|
||||
private Item[] getSeedVaultItems()
|
||||
{
|
||||
final ItemContainer itemContainer = client.getItemContainer(InventoryID.SEED_VAULT);
|
||||
if (itemContainer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return itemContainer.getItems();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("bank"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
private void updateBankPinSizes()
|
||||
{
|
||||
for (final WidgetInfo widgetInfo : BANK_PINS)
|
||||
{
|
||||
final Widget pin = client.getWidget(widgetInfo);
|
||||
if (pin == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Widget[] children = pin.getDynamicChildren();
|
||||
if (children.length < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Widget button = children[0];
|
||||
final Widget number = children[1];
|
||||
|
||||
// Change to a bigger font size
|
||||
number.setFontId(FontID.QUILL_CAPS_LARGE);
|
||||
number.setYTextAlignment(0);
|
||||
|
||||
// Change size to match container widths
|
||||
number.setOriginalWidth(button.getWidth());
|
||||
// The large font id text isn't centered, we need to offset it slightly
|
||||
number.setOriginalHeight(button.getHeight() + PIN_FONT_OFFSET);
|
||||
number.setOriginalY(-PIN_FONT_OFFSET);
|
||||
number.setOriginalX(0);
|
||||
|
||||
number.revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.showGE = config.showGE();
|
||||
this.showHA = config.showHA();
|
||||
this.largePinNumbers = config.largePinNumbers();
|
||||
this.showExact = config.showExact();
|
||||
this.rightClickBankInventory = config.rightClickBankInventory();
|
||||
this.rightClickBankEquip = config.rightClickBankEquip();
|
||||
this.rightClickBankLoot = config.rightClickBankLoot();
|
||||
this.seedVaultValue = config.seedVaultValue();
|
||||
this.rightClickSetPlaceholders = config.rightClickSetPlaceholders();
|
||||
this.rightClickReleasePlaceholders = config.rightClickReleasePlaceholders();
|
||||
this.rightClickSearch = config.rightClickSearch();
|
||||
this.rightClickFillBankFiller = config.rightClickFillBankFiller();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean valueSearch(final int itemId, final String str)
|
||||
{
|
||||
final Matcher matcher = VALUE_SEARCH_PATTERN.matcher(str);
|
||||
if (!matcher.matches())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Count bank items and remember it for determining item quantity
|
||||
if (itemQuantities == null)
|
||||
{
|
||||
itemQuantities = getBankItemSet();
|
||||
}
|
||||
|
||||
final ItemDefinition itemComposition = itemManager.getItemDefinition(itemId);
|
||||
long gePrice = (long) itemManager.getItemPrice(itemId) * (long) itemQuantities.count(itemId);
|
||||
long haPrice = (long) (itemComposition.getPrice() * HIGH_ALCHEMY_MULTIPLIER) * (long) itemQuantities.count(itemId);
|
||||
|
||||
long value = Math.max(gePrice, haPrice);
|
||||
|
||||
final String mode = matcher.group("mode");
|
||||
if (mode != null)
|
||||
{
|
||||
value = mode.toLowerCase().equals("ge") ? gePrice : haPrice;
|
||||
}
|
||||
|
||||
final String op = matcher.group("op");
|
||||
if (op != null)
|
||||
{
|
||||
long compare;
|
||||
try
|
||||
{
|
||||
compare = QuantityFormatter.parseQuantity(matcher.group("num"));
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case ">":
|
||||
return value > compare;
|
||||
case "<":
|
||||
return value < compare;
|
||||
case "=":
|
||||
return value == compare;
|
||||
case ">=":
|
||||
return value >= compare;
|
||||
case "<=":
|
||||
return value <= compare;
|
||||
}
|
||||
}
|
||||
|
||||
final String num1 = matcher.group("num1");
|
||||
final String num2 = matcher.group("num2");
|
||||
if (num1 != null && num2 != null)
|
||||
{
|
||||
long compare1, compare2;
|
||||
try
|
||||
{
|
||||
compare1 = QuantityFormatter.parseQuantity(num1);
|
||||
compare2 = QuantityFormatter.parseQuantity(num2);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return compare1 <= value && compare2 >= value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Multiset<Integer> getBankItemSet()
|
||||
{
|
||||
ItemContainer itemContainer = client.getItemContainer(InventoryID.BANK);
|
||||
if (itemContainer == null)
|
||||
{
|
||||
return HashMultiset.create();
|
||||
}
|
||||
|
||||
Multiset<Integer> set = HashMultiset.create();
|
||||
for (Item item : itemContainer.getItems())
|
||||
{
|
||||
if (item.getId() != ItemID.BANK_FILLER)
|
||||
{
|
||||
set.add(item.getId(), item.getQuantity());
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* 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.bank;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
|
||||
class ContainerCalculation
|
||||
{
|
||||
private final ItemManager itemManager;
|
||||
|
||||
private int hash;
|
||||
private ContainerPrices containerPrices;
|
||||
|
||||
@Inject
|
||||
private ContainerCalculation(ItemManager itemManager)
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ContainerPrices calculate(Item[] items)
|
||||
{
|
||||
// Returns last calculation if inventory hasn't changed
|
||||
|
||||
if (items == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final int newHash = hashItems(items);
|
||||
|
||||
if (containerPrices != null && hash == newHash)
|
||||
{
|
||||
return containerPrices;
|
||||
}
|
||||
|
||||
hash = newHash;
|
||||
|
||||
long ge = 0;
|
||||
long alch = 0;
|
||||
|
||||
for (final Item item : items)
|
||||
{
|
||||
final int qty = item.getQuantity();
|
||||
final int id = item.getId();
|
||||
|
||||
if (id <= 0 || qty == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case ItemID.COINS_995:
|
||||
ge += qty;
|
||||
alch += qty;
|
||||
break;
|
||||
case ItemID.PLATINUM_TOKEN:
|
||||
ge += qty * 1000L;
|
||||
alch += qty * 1000L;
|
||||
break;
|
||||
default:
|
||||
final long storePrice = itemManager.getItemDefinition(id).getPrice();
|
||||
final long alchPrice = (long) (storePrice * Constants.HIGH_ALCHEMY_MULTIPLIER);
|
||||
alch += alchPrice * qty;
|
||||
ge += (long) itemManager.getItemPrice(id) * qty;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ContainerPrices prices = new ContainerPrices(ge, alch);
|
||||
containerPrices = prices;
|
||||
|
||||
return prices;
|
||||
}
|
||||
|
||||
private int hashItems(final Item[] items)
|
||||
{
|
||||
final Map<Integer, Integer> mapCheck = new HashMap<>(items.length);
|
||||
for (Item item : items)
|
||||
{
|
||||
mapCheck.put(item.getId(), item.getQuantity());
|
||||
}
|
||||
|
||||
return mapCheck.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.bank;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
class ContainerPrices
|
||||
{
|
||||
private long gePrice;
|
||||
private long highAlchPrice;
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("banktags")
|
||||
public interface BankTagsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "useTabs",
|
||||
name = "Use Tag Tabs",
|
||||
description = "Enable the ability to add tabs to your bank which allow fast access to tags.",
|
||||
position = 1
|
||||
)
|
||||
default boolean tabs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rememberTab",
|
||||
name = "Remember last Tag Tab",
|
||||
description = "Enable the ability to remember last Tag Tab when closing/opening the bank.",
|
||||
position = 2
|
||||
)
|
||||
default boolean rememberTab()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeSeparators",
|
||||
name = "Remove tab separators in Tag Tabs",
|
||||
description = "Removes tab separators and corrects item layouts in Tag Tabs to mimic a regular tab",
|
||||
position = 3
|
||||
)
|
||||
default boolean removeSeparators()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hidePlaceholders",
|
||||
name = "Hide placeholders",
|
||||
description = "Hide placeholders in tag tabs or tag search.",
|
||||
position = 4
|
||||
)
|
||||
default boolean hidePlaceholders()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "position",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default int position()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "position",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void position(int idx);
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tab",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default String tab()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tab",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void tab(String tab);
|
||||
}
|
||||
@@ -1,626 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Lucas <https://github.com/Lucwousin>
|
||||
* 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.banktags;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.Multiset;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
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 net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.HIGH_ALCHEMY_MULTIPLIER;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemDefinition;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.VarClientStr;
|
||||
import net.runelite.api.events.DraggingWidgetChanged;
|
||||
import net.runelite.api.events.FocusChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.input.MouseWheelListener;
|
||||
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.banktags.tabs.BankSearch;
|
||||
import net.runelite.client.plugins.banktags.tabs.TabInterface;
|
||||
import static net.runelite.client.plugins.banktags.tabs.TabInterface.FILTERED_CHARS;
|
||||
import net.runelite.client.plugins.banktags.tabs.TabSprites;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Bank Tags",
|
||||
description = "Enable tagging of bank items and searching of bank tags",
|
||||
tags = {"searching", "tagging"},
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
@PluginDependency(ClueScrollPlugin.class)
|
||||
@Singleton
|
||||
public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyListener
|
||||
{
|
||||
public static final String CONFIG_GROUP = "banktags";
|
||||
public static final String TAG_SEARCH = "tag:";
|
||||
public static final String ICON_SEARCH = "icon_";
|
||||
public static final String VAR_TAG_SUFFIX = "*";
|
||||
private static final String EDIT_TAGS_MENU_OPTION = "Edit-tags";
|
||||
private static final String NUMBER_REGEX = "[0-9]+(\\.[0-9]+)?[kmb]?";
|
||||
|
||||
private static final String SEARCH_BANK_INPUT_TEXT =
|
||||
"Show items whose names or tags contain the following text:<br>" +
|
||||
"(To show only tagged items, start your search with 'tag:')";
|
||||
private static final String SEARCH_BANK_INPUT_TEXT_FOUND =
|
||||
"Show items whose names or tags contain the following text: (%d found)<br>" +
|
||||
"(To show only tagged items, start your search with 'tag:')";
|
||||
private static final Pattern VALUE_SEARCH_PATTERN = Pattern.compile("^(?<mode>ge|ha|alch)?" +
|
||||
" *(((?<op>[<>=]|>=|<=) *(?<num>" + NUMBER_REGEX + "))|" +
|
||||
"((?<num1>" + NUMBER_REGEX + ") *- *(?<num2>" + NUMBER_REGEX + ")))$", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
@VisibleForTesting
|
||||
final Multiset<Integer> itemQuantities = HashMultiset.create();
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Inject
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Inject
|
||||
private BankTagsConfig config;
|
||||
|
||||
@Inject
|
||||
private TagManager tagManager;
|
||||
|
||||
@Inject
|
||||
private TabInterface tabInterface;
|
||||
|
||||
@Inject
|
||||
private BankSearch bankSearch;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
private boolean shiftPressed = false;
|
||||
private int nextRowIndex = 0;
|
||||
|
||||
@Provides
|
||||
BankTagsConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BankTagsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
|
||||
cleanConfig();
|
||||
keyManager.registerKeyListener(this);
|
||||
mouseManager.registerMouseWheelListener(this);
|
||||
clientThread.invokeLater(tabInterface::init);
|
||||
spriteManager.addSpriteOverrides(TabSprites.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
keyManager.unregisterKeyListener(this);
|
||||
mouseManager.unregisterMouseWheelListener(this);
|
||||
clientThread.invokeLater(tabInterface::destroy);
|
||||
spriteManager.removeSpriteOverrides(TabSprites.values());
|
||||
|
||||
shiftPressed = false;
|
||||
itemQuantities.clear();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void cleanConfig()
|
||||
{
|
||||
removeInvalidTags("tagtabs");
|
||||
|
||||
List<String> tags = configManager.getConfigurationKeys(CONFIG_GROUP + ".item_");
|
||||
tags.forEach(s ->
|
||||
{
|
||||
String[] split = s.split("\\.", 2);
|
||||
removeInvalidTags(split[1]);
|
||||
});
|
||||
|
||||
List<String> icons = configManager.getConfigurationKeys(CONFIG_GROUP + ".icon_");
|
||||
icons.forEach(s ->
|
||||
{
|
||||
String[] split = s.split("\\.", 2);
|
||||
String replaced = split[1].replaceAll("[<>/]", "");
|
||||
if (!split[1].equals(replaced))
|
||||
{
|
||||
String value = configManager.getConfiguration(CONFIG_GROUP, split[1]);
|
||||
configManager.unsetConfiguration(CONFIG_GROUP, split[1]);
|
||||
if (replaced.length() > "icon_".length())
|
||||
{
|
||||
configManager.setConfiguration(CONFIG_GROUP, replaced, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void removeInvalidTags(final String key)
|
||||
{
|
||||
final String value = configManager.getConfiguration(CONFIG_GROUP, key);
|
||||
if (value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String replaced = value.replaceAll("[<>/]", "");
|
||||
if (!value.equals(replaced))
|
||||
{
|
||||
replaced = Text.toCSV(Text.fromCSV(replaced));
|
||||
if (replaced.isEmpty())
|
||||
{
|
||||
configManager.unsetConfiguration(CONFIG_GROUP, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.setConfiguration(CONFIG_GROUP, key, replaced);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSearching()
|
||||
{
|
||||
return client.getVar(VarClientInt.INPUT_TYPE) == InputType.SEARCH.getType()
|
||||
|| (client.getVar(VarClientInt.INPUT_TYPE) <= 0
|
||||
&& client.getVar(VarClientStr.INPUT_TEXT) != null && client.getVar(VarClientStr.INPUT_TEXT).length() > 0);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
String eventName = event.getEventName();
|
||||
|
||||
int[] intStack = client.getIntStack();
|
||||
String[] stringStack = client.getStringStack();
|
||||
int intStackSize = client.getIntStackSize();
|
||||
int stringStackSize = client.getStringStackSize();
|
||||
|
||||
switch (eventName)
|
||||
{
|
||||
case "setSearchBankInputText":
|
||||
stringStack[stringStackSize - 1] = SEARCH_BANK_INPUT_TEXT;
|
||||
break;
|
||||
case "setSearchBankInputTextFound":
|
||||
{
|
||||
int matches = intStack[intStackSize - 1];
|
||||
stringStack[stringStackSize - 1] = String.format(SEARCH_BANK_INPUT_TEXT_FOUND, matches);
|
||||
break;
|
||||
}
|
||||
case "bankSearchFilter":
|
||||
int itemId = intStack[intStackSize - 1];
|
||||
String search = stringStack[stringStackSize - 1];
|
||||
|
||||
boolean tagSearch = search.startsWith(TAG_SEARCH);
|
||||
if (tagSearch)
|
||||
{
|
||||
search = search.substring(TAG_SEARCH.length()).trim();
|
||||
}
|
||||
|
||||
if (tagManager.findTag(itemId, search) || valueSearch(itemId, search))
|
||||
{
|
||||
if (!config.hidePlaceholders())
|
||||
{
|
||||
// return true
|
||||
intStack[intStackSize - 2] = 1;
|
||||
}
|
||||
|
||||
// not a placeholder
|
||||
else if (itemManager.getItemDefinition(itemId).getPlaceholderTemplateId() == -1)
|
||||
{
|
||||
// return true
|
||||
intStack[intStackSize - 2] = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (tagSearch)
|
||||
{
|
||||
intStack[intStackSize - 2] = 0;
|
||||
}
|
||||
break;
|
||||
case "getSearchingTagTab":
|
||||
intStack[intStackSize - 1] = tabInterface.isActive() ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!config.removeSeparators() || !isSearching() || !tabInterface.isActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (eventName)
|
||||
{
|
||||
case "lineSpace":
|
||||
// prevent Y value being incremented to account for line separators
|
||||
// fallthrough
|
||||
case "tabTextSpace":
|
||||
// prevent Y value being incremented to account for "Tab x" text
|
||||
intStack[intStackSize - 1] = 0;
|
||||
break;
|
||||
case "hideLine":
|
||||
case "hideTabText":
|
||||
// hide the widget for the line separator
|
||||
// hide the widget for the "Tab x" text
|
||||
intStack[intStackSize - 1] = 1;
|
||||
break;
|
||||
case "rowIndex":
|
||||
// remember the next index in the row so we can start the next tab's items there
|
||||
nextRowIndex = intStack[intStackSize - 1];
|
||||
break;
|
||||
case "rowIndexInit":
|
||||
// set the index to our remembered value instead of 0
|
||||
intStack[intStackSize - 1] = nextRowIndex;
|
||||
break;
|
||||
case "bankLayoutInit":
|
||||
// reset the row index if the bank is rebuilt
|
||||
nextRowIndex = 0;
|
||||
break;
|
||||
case "newBankRow":
|
||||
// if we haven't filled a row when the current tab is finished building,
|
||||
// adjust the y offset to continue the next tab on the same row
|
||||
if (nextRowIndex != 0)
|
||||
{
|
||||
intStack[intStackSize - 2] = intStack[intStackSize - 2] - 32;
|
||||
}
|
||||
// if we have filled the row, adjust the y offset to maintain appropriate row spacing
|
||||
else
|
||||
{
|
||||
intStack[intStackSize - 2] = intStack[intStackSize - 2] + 4;
|
||||
}
|
||||
break;
|
||||
case "addLastRow":
|
||||
// after all tabs are finished building, add an extra row of space
|
||||
// this ensures the scrollbar is set to the correct height
|
||||
intStack[intStackSize - 1] = intStack[intStackSize - 1] + 32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
&& event.getOption().equals("Examine"))
|
||||
{
|
||||
Widget container = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER);
|
||||
Widget item = container.getChild(event.getParam0());
|
||||
int itemID = item.getItemId();
|
||||
String text = EDIT_TAGS_MENU_OPTION;
|
||||
int tagCount = tagManager.getTags(itemID, false).size() + tagManager.getTags(itemID, true).size();
|
||||
|
||||
if (tagCount > 0)
|
||||
{
|
||||
text += " (" + tagCount + ")";
|
||||
}
|
||||
|
||||
client.insertMenuItem(
|
||||
text,
|
||||
event.getTarget(),
|
||||
MenuOpcode.RUNELITE.getId(),
|
||||
event.getIdentifier(),
|
||||
event.getParam0(),
|
||||
event.getParam1(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
tabInterface.handleAdd(event);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (event.getParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId()
|
||||
&& event.getMenuOpcode() == MenuOpcode.RUNELITE
|
||||
&& event.getOption().startsWith(EDIT_TAGS_MENU_OPTION))
|
||||
{
|
||||
event.consume();
|
||||
int inventoryIndex = event.getParam0();
|
||||
ItemContainer bankContainer = client.getItemContainer(InventoryID.BANK);
|
||||
if (bankContainer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Item[] items = bankContainer.getItems();
|
||||
if (inventoryIndex < 0 || inventoryIndex >= items.length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Item item = bankContainer.getItems()[inventoryIndex];
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = item.getId();
|
||||
ItemDefinition itemDefinition = itemManager.getItemDefinition(itemId);
|
||||
String name = itemDefinition.getName();
|
||||
|
||||
// Get both tags and vartags and append * to end of vartags name
|
||||
Collection<String> tags = tagManager.getTags(itemId, false);
|
||||
tagManager.getTags(itemId, true).stream()
|
||||
.map(i -> i + "*")
|
||||
.forEach(tags::add);
|
||||
|
||||
boolean isSearchOpen = client.getVar(VarClientInt.INPUT_TYPE) == InputType.SEARCH.getType();
|
||||
String searchText = client.getVar(VarClientStr.INPUT_TEXT);
|
||||
String initialValue = Text.toCSV(tags);
|
||||
|
||||
chatboxPanelManager.openTextInput(name + " tags:<br>(append " + VAR_TAG_SUFFIX + " for variation tag)")
|
||||
.addCharValidator(FILTERED_CHARS)
|
||||
.value(initialValue)
|
||||
.onDone((newValue) ->
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
// Split inputted tags to vartags (ending with *) and regular tags
|
||||
final Collection<String> newTags = new ArrayList<>(Text.fromCSV(newValue.toLowerCase()));
|
||||
final Collection<String> newVarTags = new ArrayList<>(newTags).stream().filter(s -> s.endsWith(VAR_TAG_SUFFIX)).map(s ->
|
||||
{
|
||||
newTags.remove(s);
|
||||
return s.substring(0, s.length() - VAR_TAG_SUFFIX.length());
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
// And save them
|
||||
tagManager.setTagString(itemId, Text.toCSV(newTags), false);
|
||||
tagManager.setTagString(itemId, Text.toCSV(newVarTags), true);
|
||||
|
||||
// Check both previous and current tags in case the tag got removed in new tags or in case
|
||||
// the tag got added in new tags
|
||||
tabInterface.updateTabIfActive(Text.fromCSV(initialValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), "")));
|
||||
tabInterface.updateTabIfActive(Text.fromCSV(newValue.toLowerCase().replaceAll(Pattern.quote(VAR_TAG_SUFFIX), "")));
|
||||
}))
|
||||
.build();
|
||||
|
||||
if (isSearchOpen)
|
||||
{
|
||||
bankSearch.reset(false);
|
||||
bankSearch.search(InputType.SEARCH, searchText, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tabInterface.handleClick(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onItemContainerChanged(ItemContainerChanged event)
|
||||
{
|
||||
if (event.getContainerId() == InventoryID.BANK.getId())
|
||||
{
|
||||
itemQuantities.clear();
|
||||
for (Item item : event.getItemContainer().getItems())
|
||||
{
|
||||
if (item.getId() != ItemID.BANK_FILLER)
|
||||
{
|
||||
itemQuantities.add(item.getId(), item.getQuantity());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged configChanged)
|
||||
{
|
||||
if (configChanged.getGroup().equals("banktags") && configChanged.getKey().equals("useTabs"))
|
||||
{
|
||||
if (config.tabs())
|
||||
{
|
||||
clientThread.invokeLater(tabInterface::init);
|
||||
}
|
||||
else
|
||||
{
|
||||
clientThread.invokeLater(tabInterface::destroy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
tabInterface.update();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onDraggingWidgetChanged(DraggingWidgetChanged event)
|
||||
{
|
||||
tabInterface.handleDrag(event.isDraggingWidget(), shiftPressed);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() == WidgetID.BANK_GROUP_ID)
|
||||
{
|
||||
tabInterface.init();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onFocusChanged(FocusChanged event)
|
||||
{
|
||||
if (!event.isFocused())
|
||||
{
|
||||
shiftPressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseWheelEvent mouseWheelMoved(MouseWheelEvent event)
|
||||
{
|
||||
tabInterface.handleWheel(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftPressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftPressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean valueSearch(final int itemId, final String str)
|
||||
{
|
||||
final Matcher matcher = VALUE_SEARCH_PATTERN.matcher(str);
|
||||
if (!matcher.matches())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final ItemDefinition itemComposition = itemManager.getItemDefinition(itemId);
|
||||
long gePrice = (long) itemManager.getItemPrice(itemId) * (long) itemQuantities.count(itemId);
|
||||
long haPrice = (long) (itemComposition.getPrice() * HIGH_ALCHEMY_MULTIPLIER) * (long) itemQuantities.count(itemId);
|
||||
|
||||
long value = Math.max(gePrice, haPrice);
|
||||
|
||||
final String mode = matcher.group("mode");
|
||||
if (mode != null)
|
||||
{
|
||||
value = mode.toLowerCase().equals("ge") ? gePrice : haPrice;
|
||||
}
|
||||
|
||||
final String op = matcher.group("op");
|
||||
if (op != null)
|
||||
{
|
||||
long compare;
|
||||
try
|
||||
{
|
||||
compare = QuantityFormatter.parseQuantity(matcher.group("num"));
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case ">":
|
||||
return value > compare;
|
||||
case "<":
|
||||
return value < compare;
|
||||
case "=":
|
||||
return value == compare;
|
||||
case ">=":
|
||||
return value >= compare;
|
||||
case "<=":
|
||||
return value <= compare;
|
||||
}
|
||||
}
|
||||
|
||||
final String num1 = matcher.group("num1");
|
||||
final String num2 = matcher.group("num2");
|
||||
if (num1 != null && num2 != null)
|
||||
{
|
||||
long compare1, compare2;
|
||||
try
|
||||
{
|
||||
compare1 = QuantityFormatter.parseQuantity(num1);
|
||||
compare2 = QuantityFormatter.parseQuantity(num2);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return compare1 <= value && compare2 >= value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.ItemVariationMapping;
|
||||
import static net.runelite.client.plugins.banktags.BankTagsPlugin.CONFIG_GROUP;
|
||||
import net.runelite.client.plugins.cluescrolls.ClueScrollService;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.ClueScroll;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.CoordinateClue;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.EmoteClue;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.FairyRingClue;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.HotColdClue;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.MapClue;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement;
|
||||
|
||||
@Singleton
|
||||
public class TagManager
|
||||
{
|
||||
private static final String ITEM_KEY_PREFIX = "item_";
|
||||
private final ConfigManager configManager;
|
||||
private final ItemManager itemManager;
|
||||
private final ClueScrollService clueScrollService;
|
||||
|
||||
@Inject
|
||||
private TagManager(
|
||||
final ItemManager itemManager,
|
||||
final ConfigManager configManager,
|
||||
final ClueScrollService clueScrollService)
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
this.configManager = configManager;
|
||||
this.clueScrollService = clueScrollService;
|
||||
}
|
||||
|
||||
private String getTagString(int itemId, boolean variation)
|
||||
{
|
||||
itemId = getItemId(itemId, variation);
|
||||
|
||||
String config = configManager.getConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId);
|
||||
if (config == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
Collection<String> getTags(int itemId, boolean variation)
|
||||
{
|
||||
return new LinkedHashSet<>(Text.fromCSV(getTagString(itemId, variation).toLowerCase()));
|
||||
}
|
||||
|
||||
void setTagString(int itemId, String tags, boolean variation)
|
||||
{
|
||||
itemId = getItemId(itemId, variation);
|
||||
|
||||
if (Strings.isNullOrEmpty(tags))
|
||||
{
|
||||
configManager.unsetConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
configManager.setConfiguration(CONFIG_GROUP, ITEM_KEY_PREFIX + itemId, tags);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTags(int itemId, final Collection<String> t, boolean variation)
|
||||
{
|
||||
final Collection<String> tags = getTags(itemId, variation);
|
||||
if (tags.addAll(t))
|
||||
{
|
||||
setTags(itemId, tags, variation);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTag(int itemId, String tag, boolean variation)
|
||||
{
|
||||
final Collection<String> tags = getTags(itemId, variation);
|
||||
if (tags.add(Text.standardize(tag)))
|
||||
{
|
||||
setTags(itemId, tags, variation);
|
||||
}
|
||||
}
|
||||
|
||||
private void setTags(int itemId, Collection<String> tags, boolean variation)
|
||||
{
|
||||
setTagString(itemId, Text.toCSV(tags), variation);
|
||||
}
|
||||
|
||||
boolean findTag(int itemId, String search)
|
||||
{
|
||||
if (search.equals("clue") && testClue(itemId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Collection<String> tags = getTags(itemId, false);
|
||||
tags.addAll(getTags(itemId, true));
|
||||
return tags.stream().anyMatch(tag -> tag.startsWith(Text.standardize(search)));
|
||||
}
|
||||
|
||||
public List<Integer> getItemsForTag(String tag)
|
||||
{
|
||||
final String prefix = CONFIG_GROUP + "." + ITEM_KEY_PREFIX;
|
||||
return configManager.getConfigurationKeys(prefix).stream()
|
||||
.map(item -> Integer.parseInt(item.replace(prefix, "")))
|
||||
.filter(item -> getTags(item, false).contains(tag) || getTags(item, true).contains(tag))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void removeTag(String tag)
|
||||
{
|
||||
final String prefix = CONFIG_GROUP + "." + ITEM_KEY_PREFIX;
|
||||
configManager.getConfigurationKeys(prefix).forEach(item ->
|
||||
{
|
||||
int id = Integer.parseInt(item.replace(prefix, ""));
|
||||
removeTag(id, tag);
|
||||
});
|
||||
}
|
||||
|
||||
public void removeTag(int itemId, String tag)
|
||||
{
|
||||
Collection<String> tags = getTags(itemId, false);
|
||||
if (tags.remove(Text.standardize(tag)))
|
||||
{
|
||||
setTags(itemId, tags, false);
|
||||
}
|
||||
|
||||
tags = getTags(itemId, true);
|
||||
if (tags.remove(Text.standardize(tag)))
|
||||
{
|
||||
setTags(itemId, tags, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void renameTag(String oldTag, String newTag)
|
||||
{
|
||||
List<Integer> items = getItemsForTag(Text.standardize(oldTag));
|
||||
items.forEach(id ->
|
||||
{
|
||||
Collection<String> tags = getTags(id, id < 0);
|
||||
|
||||
tags.remove(Text.standardize(oldTag));
|
||||
tags.add(Text.standardize(newTag));
|
||||
|
||||
setTags(id, tags, id < 0);
|
||||
});
|
||||
}
|
||||
|
||||
private int getItemId(int itemId, boolean variation)
|
||||
{
|
||||
itemId = Math.abs(itemId);
|
||||
itemId = itemManager.canonicalize(itemId);
|
||||
|
||||
if (variation)
|
||||
{
|
||||
itemId = ItemVariationMapping.map(itemId) * -1;
|
||||
}
|
||||
|
||||
return itemId;
|
||||
}
|
||||
|
||||
private boolean testClue(int itemId)
|
||||
{
|
||||
ClueScroll c = clueScrollService.getClue();
|
||||
|
||||
if (c == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c instanceof EmoteClue)
|
||||
{
|
||||
EmoteClue emote = (EmoteClue) c;
|
||||
|
||||
for (ItemRequirement ir : emote.getItemRequirements())
|
||||
{
|
||||
if (ir.fulfilledBy(itemId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c instanceof CoordinateClue || c instanceof HotColdClue || c instanceof FairyRingClue)
|
||||
{
|
||||
return itemId == ItemID.SPADE;
|
||||
}
|
||||
else if (c instanceof MapClue)
|
||||
{
|
||||
MapClue mapClue = (MapClue) c;
|
||||
|
||||
return mapClue.getObjectId() == -1 && itemId == ItemID.SPADE;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags.tabs;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.VarClientStr;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
|
||||
public class BankSearch
|
||||
{
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private BankSearch(
|
||||
final Client client,
|
||||
final ClientThread clientThread
|
||||
)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
}
|
||||
|
||||
public void search(InputType inputType, String search, boolean closeInput)
|
||||
{
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
|
||||
// This ensures that any chatbox input (e.g from search) will not remain visible when
|
||||
// selecting/changing tab
|
||||
if (closeInput)
|
||||
{
|
||||
client.runScript(ScriptID.MESSAGE_LAYER_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
client.setVar(VarClientInt.INPUT_TYPE, inputType.getType());
|
||||
client.setVar(VarClientStr.INPUT_TEXT, search);
|
||||
|
||||
layoutBank();
|
||||
});
|
||||
}
|
||||
|
||||
public void layoutBank()
|
||||
{
|
||||
Widget bankContainer = client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER);
|
||||
if (bankContainer == null || bankContainer.isHidden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Object[] scriptArgs = bankContainer.getOnInvTransmit();
|
||||
|
||||
if (scriptArgs == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.runScript(scriptArgs);
|
||||
}
|
||||
|
||||
public void reset(boolean closeChat)
|
||||
{
|
||||
search(InputType.NONE, "", closeChat);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags.tabs;
|
||||
|
||||
class MenuIndexes
|
||||
{
|
||||
static class NewTab
|
||||
{
|
||||
static final int NEW_TAB = 2;
|
||||
static final int IMPORT_TAB = 3;
|
||||
}
|
||||
|
||||
static class Tab
|
||||
{
|
||||
static final int OPEN_TAG = 2;
|
||||
static final int CHANGE_ICON = 3;
|
||||
static final int DELETE_TAB = 4;
|
||||
static final int EXPORT_TAB = 5;
|
||||
static final int RENAME_TAB = 6;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags.tabs;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import static net.runelite.client.plugins.banktags.BankTagsPlugin.CONFIG_GROUP;
|
||||
import static net.runelite.client.plugins.banktags.BankTagsPlugin.ICON_SEARCH;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
@Singleton
|
||||
class TabManager
|
||||
{
|
||||
private static final String TAG_TABS_CONFIG = "tagtabs";
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<TagTab> tabs = new ArrayList<>();
|
||||
private final ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
private TabManager(ConfigManager configManager)
|
||||
{
|
||||
this.configManager = configManager;
|
||||
}
|
||||
|
||||
void add(TagTab tagTab)
|
||||
{
|
||||
if (!contains(tagTab.getTag()))
|
||||
{
|
||||
tabs.add(tagTab);
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
tabs.forEach(t -> t.setHidden(true));
|
||||
tabs.clear();
|
||||
}
|
||||
|
||||
TagTab find(String tag)
|
||||
{
|
||||
Optional<TagTab> first = tabs.stream().filter(t -> t.getTag().equals(Text.standardize(tag))).findAny();
|
||||
return first.orElse(null);
|
||||
}
|
||||
|
||||
List<String> getAllTabs()
|
||||
{
|
||||
return Text.fromCSV(MoreObjects.firstNonNull(configManager.getConfiguration(CONFIG_GROUP, TAG_TABS_CONFIG), ""));
|
||||
}
|
||||
|
||||
TagTab load(String tag)
|
||||
{
|
||||
TagTab tagTab = find(tag);
|
||||
|
||||
if (tagTab == null)
|
||||
{
|
||||
tag = Text.standardize(tag);
|
||||
String item = configManager.getConfiguration(CONFIG_GROUP, ICON_SEARCH + tag);
|
||||
int itemid = NumberUtils.toInt(item, ItemID.SPADE);
|
||||
tagTab = new TagTab(itemid, tag);
|
||||
}
|
||||
|
||||
return tagTab;
|
||||
}
|
||||
|
||||
void move(String tagToMove, String tagDestination)
|
||||
{
|
||||
tagToMove = Text.standardize(tagToMove);
|
||||
tagDestination = Text.standardize(tagDestination);
|
||||
|
||||
if (contains(tagToMove) && contains(tagDestination))
|
||||
{
|
||||
Collections.swap(tabs, indexOf(tagToMove), indexOf(tagDestination));
|
||||
}
|
||||
}
|
||||
|
||||
void remove(String tag)
|
||||
{
|
||||
TagTab tagTab = find(tag);
|
||||
|
||||
if (tagTab != null)
|
||||
{
|
||||
tagTab.setHidden(true);
|
||||
tabs.remove(tagTab);
|
||||
removeIcon(tag);
|
||||
}
|
||||
}
|
||||
|
||||
void save()
|
||||
{
|
||||
String tags = Text.toCSV(tabs.stream().map(TagTab::getTag).collect(Collectors.toList()));
|
||||
configManager.setConfiguration(CONFIG_GROUP, TAG_TABS_CONFIG, tags);
|
||||
}
|
||||
|
||||
void removeIcon(final String tag)
|
||||
{
|
||||
configManager.unsetConfiguration(CONFIG_GROUP, ICON_SEARCH + Text.standardize(tag));
|
||||
}
|
||||
|
||||
void setIcon(final String tag, final String icon)
|
||||
{
|
||||
configManager.setConfiguration(CONFIG_GROUP, ICON_SEARCH + Text.standardize(tag), icon);
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
return tabs.size();
|
||||
}
|
||||
|
||||
private boolean contains(String tag)
|
||||
{
|
||||
return tabs.stream().anyMatch(t -> t.getTag().equals(tag));
|
||||
}
|
||||
|
||||
private int indexOf(TagTab tagTab)
|
||||
{
|
||||
return tabs.indexOf(tagTab);
|
||||
}
|
||||
|
||||
private int indexOf(String tag)
|
||||
{
|
||||
return indexOf(find(tag));
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags.tabs;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.client.game.SpriteOverride;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum TabSprites implements SpriteOverride
|
||||
{
|
||||
INCINERATOR(-200, "incinerator.png"),
|
||||
TAB_BACKGROUND(-201, "tag-tab.png"),
|
||||
TAB_BACKGROUND_ACTIVE(-202, "tag-tab-active.png"),
|
||||
UP_ARROW(-203, "up-arrow.png"),
|
||||
DOWN_ARROW(-204, "down-arrow.png"),
|
||||
NEW_TAB(-205, "new-tab.png");
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final int spriteId;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
private final String fileName;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018, Ron Young <https://github.com/raiyni>
|
||||
* 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.banktags.tabs;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(of = "tag")
|
||||
class TagTab
|
||||
{
|
||||
private String tag;
|
||||
private int iconItemId;
|
||||
private Widget background;
|
||||
private Widget icon;
|
||||
|
||||
TagTab(int iconItemId, String tag)
|
||||
{
|
||||
this.iconItemId = iconItemId;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
void setHidden(boolean hide)
|
||||
{
|
||||
if (background != null)
|
||||
{
|
||||
background.setHidden(hide);
|
||||
}
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
icon.setHidden(hide);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package net.runelite.client.plugins.banlist;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigTitleSection;
|
||||
import net.runelite.client.config.Title;
|
||||
|
||||
@ConfigGroup("banlist")
|
||||
|
||||
public interface BanListConfig extends Config
|
||||
{
|
||||
@ConfigTitleSection(
|
||||
keyName = "listsTitle",
|
||||
name = "Lists",
|
||||
description = "",
|
||||
position = 0
|
||||
)
|
||||
default Title listsTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bannedPlayers",
|
||||
name = "Manual Scammer List",
|
||||
description = "Manually add players seperated by commas that you wish to be warned about while in a clan/cox/tob party",
|
||||
position = 1,
|
||||
titleSection = "listsTitle"
|
||||
)
|
||||
default String getBannedPlayers()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bannedPlayers",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void setBannedPlayers(String key);
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "enableWDRScam",
|
||||
name = "Enable WDR Scammer List",
|
||||
description = "Incorporate WDR Scammer list",
|
||||
titleSection = "listsTitle"
|
||||
)
|
||||
default boolean enableWDRScam()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "enableWDRToxic",
|
||||
name = "Enable WDR Toxic List",
|
||||
description = "Incorporate WDR Toxic list",
|
||||
titleSection = "listsTitle"
|
||||
)
|
||||
default boolean enableWDRToxic()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "enableRuneWatch",
|
||||
name = "Enable RuneWatch List",
|
||||
description = "Incorporate RuneWatch potential scammer list",
|
||||
titleSection = "listsTitle"
|
||||
)
|
||||
default boolean enableRuneWatch()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigTitleSection(
|
||||
keyName = "highlightTitle",
|
||||
name = "Highlight",
|
||||
description = "",
|
||||
position = 5
|
||||
)
|
||||
default Title highlightTitle()
|
||||
{
|
||||
return new Title();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "highlightInClan",
|
||||
name = "Highlight red in Clan Chat",
|
||||
description = "Highlights Scammer\'s name in your current clan chat.",
|
||||
titleSection = "highlightTitle"
|
||||
)
|
||||
default boolean highlightInClan()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "highlightInTrade",
|
||||
name = "Highlight red in trade screen",
|
||||
description = "Highlights Scammer\'s name in your trade window",
|
||||
titleSection = "highlightTitle"
|
||||
)
|
||||
default boolean highlightInTrade()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,455 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* 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.banlist;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.ClanMember;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.ClanMemberJoined;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.WidgetHiddenChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.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.events.ConfigChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Ban List",
|
||||
description = "Displays warning in chat when you join a" +
|
||||
"clan chat/new member join your clan chat and he is in a WDR/RuneWatch/Manual List",
|
||||
tags = {"PVM", "WDR", "RuneWatch"},
|
||||
type = PluginType.MISCELLANEOUS,
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class BanListPlugin extends Plugin
|
||||
{
|
||||
private final Set<String> wdrScamSet = new HashSet<>();
|
||||
private final Set<String> wdrToxicSet = new HashSet<>();
|
||||
private final Set<String> runeWatchSet = new HashSet<>();
|
||||
private final Set<String> manualBans = new HashSet<>();
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private BanListConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
private String tobNames = "";
|
||||
private boolean enableWDRScam;
|
||||
private boolean enableWDRToxic;
|
||||
private boolean enableRuneWatch;
|
||||
private boolean highlightInClan;
|
||||
private boolean highlightInTrade;
|
||||
|
||||
@Provides
|
||||
BanListConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BanListConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
manualBans.addAll(Text.fromCSV(Text.standardize(config.getBannedPlayers())));
|
||||
|
||||
fetchFromWebsites();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
|
||||
wdrScamSet.clear();
|
||||
wdrToxicSet.clear();
|
||||
runeWatchSet.clear();
|
||||
manualBans.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("banlist") && event.getKey().equals("bannedPlayers"))
|
||||
{
|
||||
manualBans.clear();
|
||||
|
||||
String newValue = event.getNewValue();
|
||||
|
||||
manualBans.addAll(Text.fromCSV(Text.standardize(newValue)));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.enableWDRScam = config.enableWDRScam();
|
||||
this.enableWDRToxic = config.enableWDRToxic();
|
||||
this.enableRuneWatch = config.enableRuneWatch();
|
||||
this.highlightInClan = config.highlightInClan();
|
||||
this.highlightInTrade = config.highlightInTrade();
|
||||
}
|
||||
|
||||
/**
|
||||
* Event to keep making sure player names are highlighted red in clan chat, since the red name goes away frequently
|
||||
*/
|
||||
@Subscribe
|
||||
private void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN
|
||||
|| client.getWidget(WidgetInfo.LOGIN_CLICK_TO_PLAY_SCREEN) != null
|
||||
|| client.getViewportWidget() == null
|
||||
|| client.getWidget(WidgetInfo.CLAN_CHAT) == null
|
||||
|| !this.highlightInClan)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
if (!client.getWidget(WidgetInfo.CLAN_CHAT).isHidden())
|
||||
{
|
||||
highlightRedInCC();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onClanMemberJoined(ClanMemberJoined event)
|
||||
{
|
||||
ClanMember member = event.getMember();
|
||||
String memberUsername = Text.standardize(member.getUsername().toLowerCase());
|
||||
|
||||
ListType scamList = checkScamList(memberUsername);
|
||||
ListType toxicList = checkToxicList(memberUsername);
|
||||
|
||||
if (scamList != null)
|
||||
{
|
||||
sendWarning(memberUsername, scamList);
|
||||
if (this.highlightInClan)
|
||||
{
|
||||
highlightRedInCC();
|
||||
}
|
||||
}
|
||||
|
||||
if (toxicList != null)
|
||||
{
|
||||
sendWarning(memberUsername, toxicList);
|
||||
if (this.highlightInClan)
|
||||
{
|
||||
highlightRedInCC();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a trade window is opened and the person trading us is on the list, modify "trading with"
|
||||
*/
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(WidgetLoaded widgetLoaded)
|
||||
{
|
||||
if (this.highlightInTrade && widgetLoaded.getGroupId() == PLAYER_TRADE_SCREEN_GROUP_ID)
|
||||
{ //if trading window was loaded
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
Widget tradingWith = client.getWidget(WidgetInfo.TRADING_WITH);
|
||||
|
||||
String name = tradingWith.getText().replaceAll("Trading With: ", "").toLowerCase();
|
||||
if (checkScamList(name) != null)
|
||||
{
|
||||
tradingWith.setText(tradingWith.getText().replaceAll(name, "<col=ff0000>" + name + " (Scammer)" + "</col>"));
|
||||
}
|
||||
if (checkToxicList(name) != null)
|
||||
{
|
||||
tradingWith.setText(tradingWith.getText().replaceAll(name, "<col=ff6400>" + name + " (Toxic)" + "</col>"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
final Widget raidingParty = client.getWidget(WidgetInfo.THEATRE_OF_BLOOD_RAIDING_PARTY);
|
||||
if (raidingParty == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String allNames = raidingParty.getText();
|
||||
|
||||
if (allNames.equalsIgnoreCase(tobNames))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tobNames = allNames;
|
||||
|
||||
String[] split = allNames.split("<br>");
|
||||
|
||||
for (String name : split)
|
||||
{
|
||||
if (!name.equals("-"))
|
||||
{
|
||||
String stdName = Text.standardize(name);
|
||||
|
||||
ListType scamList = checkScamList(stdName);
|
||||
|
||||
if (scamList != null)
|
||||
{
|
||||
sendWarning(name, scamList);
|
||||
}
|
||||
|
||||
ListType toxicList = checkToxicList(stdName);
|
||||
|
||||
if (toxicList != null)
|
||||
{
|
||||
sendWarning(name, toxicList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares player name to everything in the ban lists
|
||||
*/
|
||||
private ListType checkScamList(String nameToBeChecked)
|
||||
{
|
||||
if (this.enableWDRScam && wdrScamSet.contains(nameToBeChecked))
|
||||
{
|
||||
return ListType.WEDORAIDSSCAM_LIST;
|
||||
}
|
||||
|
||||
if (this.enableRuneWatch && runeWatchSet.contains(nameToBeChecked))
|
||||
{
|
||||
return ListType.RUNEWATCH_LIST;
|
||||
}
|
||||
|
||||
if (manualBans.contains(nameToBeChecked))
|
||||
{
|
||||
return ListType.MANUAL_LIST;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ListType checkToxicList(String nameToBeChecked)
|
||||
{
|
||||
if (this.enableWDRToxic && wdrToxicSet.contains(nameToBeChecked))
|
||||
{
|
||||
return ListType.WEDORAIDSTOXIC_LIST;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a warning to our player, notifying them that a player is on a ban list
|
||||
*/
|
||||
private void sendWarning(String playerName, ListType listType)
|
||||
{
|
||||
switch (listType)
|
||||
{
|
||||
case WEDORAIDSSCAM_LIST:
|
||||
final String wdr__scam_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on WeDoRaids\' scammer list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(wdr__scam_message)
|
||||
.build());
|
||||
break;
|
||||
|
||||
case WEDORAIDSTOXIC_LIST:
|
||||
final String wdr__toxic_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on WeDoRaids\' toxic list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(wdr__toxic_message)
|
||||
.build());
|
||||
break;
|
||||
|
||||
case RUNEWATCH_LIST:
|
||||
final String rw_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on the Runewatch\'s potential scammer list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(rw_message)
|
||||
.build());
|
||||
break;
|
||||
case MANUAL_LIST:
|
||||
final String manual_message = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Warning! " + playerName + " is on your manual scammer list!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(
|
||||
QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(manual_message)
|
||||
.build());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls data from wdr and runewatch to build a list of blacklisted usernames
|
||||
*/
|
||||
private void fetchFromWebsites()
|
||||
{
|
||||
Request request = new Request.Builder()
|
||||
.url("https://wdrdev.github.io/index")
|
||||
.build();
|
||||
fetchAndParseWdr(request, wdrScamSet);
|
||||
|
||||
|
||||
Request secondRequest = new Request.Builder()
|
||||
.url("https://runewatch.com/incident-index-page/")
|
||||
.build();
|
||||
RuneLiteAPI.CLIENT.newCall(secondRequest).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e)
|
||||
{
|
||||
log.debug("error retrieving names from runewatch");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException
|
||||
{
|
||||
String text = response.body().string();
|
||||
String mytext = text.substring(text.indexOf("lcp_instance_0"), text.indexOf("strong>Evidence Quality Suggestion"));
|
||||
String[] split = mytext.split("href=");
|
||||
for (String x : split)
|
||||
{
|
||||
if (x.contains("title"))
|
||||
{
|
||||
x = x.substring(x.indexOf("title"), x.indexOf('>'));
|
||||
x = x.substring(x.indexOf('=') + 2, x.length() - 1);
|
||||
runeWatchSet.add(Text.standardize(x).toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Request thirdRequest = new Request.Builder()
|
||||
.url("https://wdrdev.github.io/toxic")
|
||||
.build();
|
||||
fetchAndParseWdr(thirdRequest, wdrToxicSet);
|
||||
}
|
||||
|
||||
private void fetchAndParseWdr(Request req, Set<String> tgtSet)
|
||||
{
|
||||
RuneLiteAPI.CLIENT.newCall(req).enqueue(new Callback()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e)
|
||||
{
|
||||
log.debug("error retrieving names from wdr");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException
|
||||
{
|
||||
String text = response.body().string();
|
||||
text = text.substring(text.indexOf("<p>") + 3, text.indexOf("</p>"));
|
||||
text = text.replace("/", ",");
|
||||
text = text.replace(", $", "");
|
||||
|
||||
Text.fromCSV(text).forEach(str -> tgtSet.add(Text.standardize(str)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the clan chat list widget and checks if a string (name) is on any of the ban lists to highlight them red.
|
||||
*/
|
||||
private void highlightRedInCC()
|
||||
{
|
||||
clientThread.invokeLater(() ->
|
||||
{
|
||||
Widget widget = client.getWidget(WidgetInfo.CLAN_CHAT_LIST);
|
||||
for (Widget widgetChild : widget.getDynamicChildren())
|
||||
{
|
||||
String text = widgetChild.getText(), lc = text.toLowerCase();
|
||||
|
||||
if (checkScamList(lc) != null)
|
||||
{
|
||||
widgetChild.setText("<col=ff0000>" + text + "</col>");
|
||||
}
|
||||
else if (checkToxicList(lc) != null)
|
||||
{
|
||||
widgetChild.setText("<col=ff6400>" + text + "</col>");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package net.runelite.client.plugins.banlist;
|
||||
|
||||
public enum ListType
|
||||
{
|
||||
WEDORAIDSSCAM_LIST,
|
||||
WEDORAIDSTOXIC_LIST,
|
||||
RUNEWATCH_LIST,
|
||||
MANUAL_LIST
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
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.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
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.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
class AboveSceneOverlay extends Overlay
|
||||
{
|
||||
private static final int HEALTH_BAR_HEIGHT = 20;
|
||||
private static final int HEALTH_BAR_WIDTH = 115;
|
||||
private static final int CENTER_OFFSET = Perspective.LOCAL_HALF_TILE_SIZE / 8;
|
||||
private static final int EGG_DIAMETER = Perspective.LOCAL_HALF_TILE_SIZE / 4;
|
||||
private static final Color HEALTH_BAR_COLOR = new Color(225, 35, 0, 125);
|
||||
private static final ImmutableMap<WidgetInfo, Point> TEAMMATES = ImmutableMap.of(
|
||||
WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2),
|
||||
WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2),
|
||||
WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2),
|
||||
WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2));
|
||||
|
||||
private final Client client;
|
||||
private final BarbarianAssaultPlugin game;
|
||||
|
||||
|
||||
@Inject
|
||||
private AboveSceneOverlay(final Client client, final BarbarianAssaultPlugin game)
|
||||
{
|
||||
super(game);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!game.isInGame() || game.getRole() == null || game.isUsingGloryHorn())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (game.getRole())
|
||||
{
|
||||
|
||||
case HEALER:
|
||||
if (game.isShowTeammateHealthbars())
|
||||
{
|
||||
renderHealthBars(graphics);
|
||||
}
|
||||
if (game.isHealerCodes())
|
||||
{
|
||||
renderHealerCodes(graphics);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case COLLECTOR:
|
||||
if (game.isHighlightCollectorEggs())
|
||||
{
|
||||
renderEggs(graphics);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO add poison color change or low health color change
|
||||
private void renderHealthBars(Graphics2D graphics)
|
||||
{
|
||||
for (Map.Entry<WidgetInfo, Point> teammate : TEAMMATES.entrySet())
|
||||
{
|
||||
Widget widget = client.getWidget(teammate.getKey());
|
||||
if (widget == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// This will give us two elements, the first will be current health, and the second will be max health
|
||||
String[] teammateHealth = widget.getText().split(" / ");
|
||||
|
||||
graphics.setColor(HEALTH_BAR_COLOR);
|
||||
graphics.fillRect((widget.getCanvasLocation().getX() - teammate.getValue().getX()),
|
||||
(widget.getCanvasLocation().getY() - teammate.getValue().getY()),
|
||||
getBarWidth(Integer.parseInt(teammateHealth[1]), Integer.parseInt(teammateHealth[0])),
|
||||
HEALTH_BAR_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
private int getBarWidth(int base, int current)
|
||||
{
|
||||
final double ratio = (double) current / base;
|
||||
|
||||
if (ratio >= 1)
|
||||
{
|
||||
return HEALTH_BAR_WIDTH;
|
||||
}
|
||||
|
||||
return (int) Math.round(ratio * HEALTH_BAR_WIDTH);
|
||||
}
|
||||
|
||||
private void renderHealerCodes(Graphics2D graphics)
|
||||
{
|
||||
for (Healer healer : game.getHealers().values())
|
||||
{
|
||||
Color color = Color.GREEN;
|
||||
int timeLeft = 0;
|
||||
|
||||
if (game.getWave() != null)
|
||||
{
|
||||
timeLeft = healer.getLastFoodTime() - (int) game.getWave().getWaveTimer().getElapsedTime();
|
||||
}
|
||||
|
||||
timeLeft = timeLeft < 1 ? 0 : timeLeft;
|
||||
|
||||
if (timeLeft > 0)
|
||||
{
|
||||
color = Color.RED;
|
||||
}
|
||||
|
||||
String text = String.format("%d %d", healer.getFoodRemaining(), timeLeft);
|
||||
|
||||
OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderEggs(Graphics2D graphics)
|
||||
{
|
||||
final Color color = graphics.getColor();
|
||||
final Stroke originalStroke = graphics.getStroke();
|
||||
String listen = game.getLastListenText();
|
||||
if (listen != null && !listen.equals("- - -"))
|
||||
{
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
//TODO Render quantity text as well
|
||||
//TODO add config options for overlay colors
|
||||
switch (listen)
|
||||
{
|
||||
case "Red eggs":
|
||||
graphics.setColor(new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue(), 150));
|
||||
game.getRedEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
|
||||
break;
|
||||
case "Green eggs":
|
||||
graphics.setColor(new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 150));
|
||||
game.getGreenEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
|
||||
break;
|
||||
case "Blue eggs":
|
||||
graphics.setColor(new Color(Color.BLUE.getRed(), Color.BLUE.getGreen(), Color.BLUE.getBlue(), 150));
|
||||
game.getBlueEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
graphics.setColor(new Color(Color.YELLOW.getRed(), Color.YELLOW.getGreen(), Color.YELLOW.getBlue(), 150));
|
||||
game.getYellowEggs().forEach((point, quantity) -> drawCircle(graphics, LocalPoint.fromWorld(client, point)));
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(originalStroke);
|
||||
}
|
||||
|
||||
private void drawCircle(Graphics2D graphics, LocalPoint point)
|
||||
{
|
||||
if (point == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Point canvasPoint = Perspective.localToCanvas(client, point, 0);
|
||||
if (canvasPoint == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO rendering a model would be better / more accurate
|
||||
graphics.fillOval(canvasPoint.getX() - CENTER_OFFSET, canvasPoint.getY() - CENTER_OFFSET, EGG_DIAMETER, EGG_DIAMETER);
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
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.OverlayUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Singleton
|
||||
class AboveWidgetsOverlay extends Overlay
|
||||
{
|
||||
private static final int OFFSET_X_TEXT_QUANTITY = 0;
|
||||
private static final int OFFSET_Y_TEXT_QUANTITY = 10;
|
||||
|
||||
private final Client client;
|
||||
private final BarbarianAssaultPlugin game;
|
||||
|
||||
@Inject
|
||||
private AboveWidgetsOverlay(final Client client, final BarbarianAssaultPlugin game)
|
||||
{
|
||||
super(game);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!game.isInGame() || game.getRole() == null || game.isUsingGloryHorn())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Role role = game.getRole();
|
||||
|
||||
if (game.isShowTimer())
|
||||
{
|
||||
renderTimer(graphics, role);
|
||||
}
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case ATTACKER:
|
||||
if (game.isHighlightArrows())
|
||||
{
|
||||
renderInventoryHighlights(graphics, game.getRole().getListenItem(game.getLastListenText()), game.getHighlightArrowColor());
|
||||
}
|
||||
break;
|
||||
|
||||
case DEFENDER:
|
||||
if (game.isHighlightBait())
|
||||
{
|
||||
renderInventoryHighlights(graphics, game.getRole().getListenItem(game.getLastListenText()), game.getHighlightBaitColor());
|
||||
}
|
||||
break;
|
||||
|
||||
case HEALER:
|
||||
if (game.isHighlightPoison())
|
||||
{
|
||||
renderInventoryHighlights(graphics, game.getRole().getListenItem(game.getLastListenText()), game.getHighlightPoisonColor());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderTimer(Graphics2D graphics, Role role)
|
||||
{
|
||||
Widget roleText = client.getWidget(role.getRoleText());
|
||||
Widget roleSprite = client.getWidget(role.getRoleSprite());
|
||||
|
||||
if (roleText == null || roleSprite == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (role == Role.COLLECTOR && game.isShowEggCountOverlay() && game.getWave() != null)
|
||||
{
|
||||
roleText.setText("(" + game.getWave().getCollectedEggCount() + ") " + formatClock());
|
||||
}
|
||||
else if (role == Role.HEALER && game.isShowHpCountOverlay() && game.getWave() != null)
|
||||
{
|
||||
roleText.setText("(" + game.getWave().getHpHealed() + ") " + formatClock());
|
||||
}
|
||||
else
|
||||
{
|
||||
roleText.setText(formatClock());
|
||||
}
|
||||
|
||||
Rectangle spriteBounds = roleSprite.getBounds();
|
||||
graphics.drawImage(game.getClockImage(), spriteBounds.x, spriteBounds.y, null);
|
||||
roleSprite.setHidden(true);
|
||||
}
|
||||
|
||||
private void renderInventoryHighlights(Graphics2D graphics, int itemID, Color color)
|
||||
{
|
||||
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
|
||||
|
||||
if (inventory == null || inventory.isHidden() || itemID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color highlight = new Color(color.getRed(), color.getGreen(), color.getBlue(), 150);
|
||||
BufferedImage image = ImageUtil.fillImage(client.createItemSprite(itemID, 300, 2, 0, 0, true, 710).toBufferedImage(), highlight);
|
||||
for (WidgetItem item : inventory.getWidgetItems())
|
||||
{
|
||||
if (item.getId() == itemID)
|
||||
{
|
||||
OverlayUtil.renderImageLocation(graphics, item.getCanvasLocation(), image);
|
||||
//The item's text quantity is rendered after the sprite's image is rendered so that the text appears on top
|
||||
if (item.getQuantity() > 1)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics,
|
||||
new Point(item.getCanvasLocation().getX() + OFFSET_X_TEXT_QUANTITY, item.getCanvasLocation().getY() + OFFSET_Y_TEXT_QUANTITY),
|
||||
String.valueOf(item.getQuantity()), Color.YELLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String formatClock()
|
||||
{
|
||||
if (game.getCallTimer() == null)
|
||||
{
|
||||
return "- - -";
|
||||
}
|
||||
else
|
||||
{
|
||||
long timeLeft = game.getTimeToChange();
|
||||
if (timeLeft < 0)
|
||||
{
|
||||
return "00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.format("00:%02d", timeLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.ConfigSection;
|
||||
import net.runelite.client.config.Range;
|
||||
|
||||
@ConfigGroup("barbarianAssault")
|
||||
public interface BarbarianAssaultConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "swapLadder",
|
||||
name = "Swap quick-start",
|
||||
description = "Enables swapping of 'Climb-down' and 'Quick-start' in the wave lobby",
|
||||
position = 0
|
||||
)
|
||||
default boolean swapLadder()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTimer",
|
||||
name = "Show call change timer",
|
||||
description = "Shows time to next call change",
|
||||
position = 1
|
||||
)
|
||||
default boolean showTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeIncorrectCalls",
|
||||
name = "Remove incorrect calls",
|
||||
description = "Removes incorrect 'Tell' menu options from horn",
|
||||
position = 2
|
||||
)
|
||||
default boolean removeIncorrectCalls()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeUnusedMenus",
|
||||
name = "Remove unused menus",
|
||||
description = "Removes unnecessary menu options" +
|
||||
"<br>Example: Attack options are removed when not attacker",
|
||||
position = 3
|
||||
)
|
||||
default boolean removeUnusedMenus()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "prayerMetronome",
|
||||
name = "Enable prayer metronome",
|
||||
description = "Turns on a metronome sync'd to the game's tick rate when any prayer is active",
|
||||
position = 4
|
||||
)
|
||||
default boolean prayerMetronome()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 1,
|
||||
max = 50
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "prayerMetronomeVolume",
|
||||
name = "Metronome volume",
|
||||
description = "Adjusts the metronome's volume",
|
||||
position = 5,
|
||||
hidden = true,
|
||||
unhide = "prayerMetronome"
|
||||
)
|
||||
default int prayerMetronomeVolume()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showDeathTimes",
|
||||
name = "Show death times",
|
||||
description = "Shows the time all penance monsters of a certain type are killed in the chat box, an info box, or both",
|
||||
position = 6
|
||||
)
|
||||
default boolean showDeathTimes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showDeathTimesMode",
|
||||
name = "Mode",
|
||||
description = "",
|
||||
position = 7,
|
||||
hidden = true,
|
||||
unhide = "showDeathTimes"
|
||||
)
|
||||
default DeathTimesMode showDeathTimesMode()
|
||||
{
|
||||
return DeathTimesMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "waveTimes",
|
||||
name = "Show wave and game duration",
|
||||
description = "Displays wave duration after each wave and total game time after wave 10",
|
||||
position = 8
|
||||
)
|
||||
default boolean waveTimes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTotalRewards",
|
||||
name = "Summarize total reward points",
|
||||
description = "Gives summary of advanced points breakdown in chat log",
|
||||
position = 9
|
||||
)
|
||||
default boolean showTotalRewards()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*///************///*/
|
||||
/*/// Attacker ///*/
|
||||
/*///************///*/
|
||||
|
||||
@ConfigSection(
|
||||
name = "Attacker",
|
||||
description = "",
|
||||
position = 10,
|
||||
keyName = "attackerSection"
|
||||
)
|
||||
default boolean attackerSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightArrows",
|
||||
name = "Highlight called arrows",
|
||||
description = "Highlights arrows called by your teammate",
|
||||
position = 0,
|
||||
section = "attackerSection"
|
||||
)
|
||||
default boolean highlightArrows()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightArrowColor",
|
||||
name = "Arrow color",
|
||||
description = "Configures the color to highlight the called arrows",
|
||||
position = 1,
|
||||
section = "attackerSection",
|
||||
hidden = true,
|
||||
unhide = "highlightArrows"
|
||||
)
|
||||
default Color highlightArrowColor()
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeIncorrectAttackStyles",
|
||||
name = "Remove incorrect attack styles",
|
||||
description = "Hides wrong attack styles for dragon claws and crystal halberd",
|
||||
position = 2,
|
||||
section = "attackerSection"
|
||||
)
|
||||
default boolean removeIncorrectAttackStyles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tagging",
|
||||
name = "Enable tagging",
|
||||
description = "Highlights the menu entry of an attacker/ranger that has not been tagged.",
|
||||
position = 3,
|
||||
section = "attackerSection"
|
||||
)
|
||||
default boolean tagging()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*///************///*/
|
||||
/*/// Defender ///*/
|
||||
/*///************///*/
|
||||
|
||||
@ConfigSection(
|
||||
name = "Defender",
|
||||
description = "",
|
||||
position = 11,
|
||||
keyName = "defenderSection"
|
||||
)
|
||||
default boolean defenderSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightBait",
|
||||
name = "Highlight called bait",
|
||||
description = "Highlights bait called by your teammate",
|
||||
position = 0,
|
||||
section = "defenderSection"
|
||||
)
|
||||
default boolean highlightBait()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightBaitColor",
|
||||
name = "Bait color",
|
||||
description = "Configures the color to highlight the called bait",
|
||||
position = 1,
|
||||
section = "defenderSection",
|
||||
hidden = true,
|
||||
unhide = "highlightBait"
|
||||
)
|
||||
default Color highlightBaitColor()
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showDefTimer",
|
||||
name = "Show defender tick timer",
|
||||
description = "Shows the current cycle tick of runners",
|
||||
position = 2,
|
||||
section = "defenderSection"
|
||||
)
|
||||
default boolean showDefTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "deprioritizeBait",
|
||||
name = "Deprioritize bait",
|
||||
description = "Moves 'Take' menu option for all bait below 'Walk Here'",
|
||||
position = 3,
|
||||
section = "defenderSection"
|
||||
)
|
||||
default boolean deprioritizeBait()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removePenanceCave",
|
||||
name = "Remove penance cave",
|
||||
description = "Removes 'Block' menu option from penance cave",
|
||||
position = 4,
|
||||
section = "defenderSection"
|
||||
)
|
||||
default boolean removePenanceCave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*///**********///*/
|
||||
/*/// Healer ///*/
|
||||
/*///**********///*/
|
||||
|
||||
@ConfigSection(
|
||||
name = "Healer",
|
||||
description = "",
|
||||
position = 12,
|
||||
keyName = "healerSection"
|
||||
)
|
||||
default boolean healerSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightPoison",
|
||||
name = "Highlight called poison",
|
||||
description = "Highlights poison called by your teammate",
|
||||
position = 0,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean highlightPoison()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightPoisonColor",
|
||||
name = "Poison color",
|
||||
description = "Configures the color to highlight the called poison",
|
||||
position = 1,
|
||||
section = "healerSection",
|
||||
hidden = true,
|
||||
unhide = "highlightPoison"
|
||||
)
|
||||
default Color highlightPoisonColor()
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightNotification",
|
||||
name = "Highlight incorrect notification",
|
||||
description = "Highlights incorrect poison chat notification",
|
||||
position = 2,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean highlightNotification()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightNotificationColor",
|
||||
name = "Notification color",
|
||||
description = "Configures the color to highlight the notification text",
|
||||
position = 3,
|
||||
section = "healerSection",
|
||||
hidden = true,
|
||||
unhide = "highlightNotification"
|
||||
)
|
||||
default Color highlightNotificationColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHpCountOverlay",
|
||||
name = "Show number of hitpoints healed",
|
||||
description = "Displays current number of hitpoints healed",
|
||||
position = 4,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean showHpCountOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTeammateHealthbars",
|
||||
name = "Show health bars",
|
||||
description = "Displays a health bar where a teammate's remaining health is located",
|
||||
position = 5,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean showTeammateHealthbars()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerCodes",
|
||||
name = "Show healer codes",
|
||||
description = "Overlay to show healer codes",
|
||||
position = 6,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean healerCodes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerMenuOption",
|
||||
name = "Show healer menu options",
|
||||
description = "Shows tick count in healer menu options",
|
||||
position = 7,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean healerMenuOption()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "shiftOverstock",
|
||||
name = "Enable shift overstock",
|
||||
description = "Enables overstocking by pressing shift",
|
||||
position = 8,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean shiftOverstock()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "controlHealer",
|
||||
name = "Control Healer",
|
||||
description = "Hold ctrl to put last healer clicked on top",
|
||||
position = 9,
|
||||
section = "healerSection"
|
||||
)
|
||||
default boolean controlHealer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*///*************///*/
|
||||
/*/// Collector ///*/
|
||||
/*///*************///*/
|
||||
|
||||
@ConfigSection(
|
||||
name = "Collector",
|
||||
description = "",
|
||||
position = 13,
|
||||
keyName = "collectorSection"
|
||||
)
|
||||
default boolean collectorSection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapCollectorBag",
|
||||
name = "Swap empty",
|
||||
description = "Enables swapping of 'Look-in' and 'Empty' on the collector's bag",
|
||||
position = 0,
|
||||
section = "collectorSection"
|
||||
)
|
||||
default boolean swapCollectorBag()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapDestroyEggs",
|
||||
name = "Swap destroy",
|
||||
description = "Enables swapping of 'Use' and 'Destroy' on collector eggs; this does not affect yellow/omega eggs",
|
||||
position = 1,
|
||||
section = "collectorSection"
|
||||
)
|
||||
default boolean swapDestroyEggs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightCollectorEggs",
|
||||
name = "Highlight collector eggs",
|
||||
description = "Highlight called egg colors",
|
||||
position = 2,
|
||||
section = "collectorSection"
|
||||
)
|
||||
default boolean highlightCollectorEggs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "deprioritizeIncorrectEggs",
|
||||
name = "Deprioritize incorrect eggs",
|
||||
description = "Moves 'Take' menu option for incorrect eggs below 'Walk Here'",
|
||||
position = 3,
|
||||
section = "collectorSection"
|
||||
)
|
||||
default boolean deprioritizeIncorrectEggs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showEggCountOverlay",
|
||||
name = "Show number of eggs collected",
|
||||
description = "Displays current number of eggs collected",
|
||||
position = 4,
|
||||
section = "collectorSection"
|
||||
)
|
||||
default boolean showEggCountOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.client.menus.AbstractComparableEntry;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
|
||||
class BarbarianAssaultMenu
|
||||
{
|
||||
private final MenuManager menuManager;
|
||||
private final BarbarianAssaultPlugin game;
|
||||
private final List<AbstractComparableEntry> tracker = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean hornUpdated = false;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean rebuildForced = false;
|
||||
|
||||
@Inject
|
||||
BarbarianAssaultMenu(final MenuManager menuManager, final BarbarianAssaultPlugin game)
|
||||
{
|
||||
this.menuManager = menuManager;
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
private boolean isHornOptionHidden(String option)
|
||||
{
|
||||
if (game.isInGame() && game.getRole() != null && game.getRole().getTell(game.getLastCallText()).equalsIgnoreCase(option))
|
||||
{
|
||||
// This will force the menu to be rebuilt after the correct tell is found
|
||||
// medic will be added to the menu if it wasn't there before
|
||||
if (!hornUpdated)
|
||||
{
|
||||
rebuildForced = true;
|
||||
}
|
||||
hornUpdated = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void clearHiddenMenus()
|
||||
{
|
||||
// Clears menus from MenuManager and tracker
|
||||
for (Iterator<AbstractComparableEntry> iterator = tracker.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
menuManager.removeHiddenEntry(iterator.next());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO add omega egg use on?
|
||||
void validateHiddenMenus(Role role)
|
||||
{
|
||||
clearHiddenMenus();
|
||||
|
||||
HashSet<Menus> hiddenMenus = Sets.newHashSet(Menus.getMenus());
|
||||
HashSet<Menus> conditionalMenus = Sets.newHashSet(Menus.getMenus());
|
||||
|
||||
// Any option left in this set will not be hidden
|
||||
// Checking each option for the correct role prevents MenuManager from
|
||||
// iterating over off role menu entry options that are not possible
|
||||
conditionalMenus.removeIf(entry ->
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
// Attacker role options
|
||||
case TELL_BLUE_ATTACKER_HORN:
|
||||
case TELL_GREEN_ATTACKER_HORN:
|
||||
case TELL_RED_ATTACKER_HORN:
|
||||
return ((role == Role.ATTACKER && isHornOptionHidden(entry.getOption())) || role == null) && game.isRemoveIncorrectCalls();
|
||||
|
||||
case ATTACK_PENANCE_FIGHTER:
|
||||
case ATTACK_PENANCE_RANGER:
|
||||
case GET_SPIKES_PETRIFIED_MUSHROOM:
|
||||
case TAKE_ATTACKER_ITEM_MACHINE:
|
||||
return (role != Role.ATTACKER && role != null) && game.isRemoveUnusedMenus();
|
||||
|
||||
|
||||
// Defender role Options
|
||||
case TELL_MEAT_DEFENDER_HORN:
|
||||
case TELL_TOFU_DEFENDER_HORN:
|
||||
case TELL_WORMS_DEFENDER_HORN:
|
||||
return ((role == Role.DEFENDER && isHornOptionHidden(entry.getOption())) || role == null) && game.isRemoveIncorrectCalls();
|
||||
|
||||
case BLOCK_PENANCE_CAVE:
|
||||
return ((role != Role.DEFENDER && role != null) && game.isRemoveUnusedMenus())
|
||||
|| (role == Role.DEFENDER && game.isRemovePenanceCave());
|
||||
|
||||
case DUNK_LAVA_CRATER:
|
||||
case FIX:
|
||||
case STOCK_UP_DEFENDER_ITEM_MACHINE:
|
||||
case TAKE_DEFENDER_ITEM_MACHINE:
|
||||
case TAKE_HAMMER:
|
||||
case TAKE_LOGS:
|
||||
return (role != Role.DEFENDER && role != null) && game.isRemoveUnusedMenus();
|
||||
|
||||
|
||||
// Collector role options
|
||||
case TELL_ACCURATE_COLLECTOR_HORN:
|
||||
case TELL_AGGRESSIVE_COLLECTOR_HORN:
|
||||
case TELL_CONTROLLED_COLLECTOR_HORN:
|
||||
case TELL_DEFENSIVE_COLLECTOR_HORN:
|
||||
return ((role == Role.COLLECTOR && isHornOptionHidden(entry.getOption())) || role == null) && game.isRemoveIncorrectCalls();
|
||||
|
||||
case CONVERT_COLLECTOR_CONVERTER:
|
||||
case LOAD_EGG_HOPPER:
|
||||
case TAKE_BLUE_EGG:
|
||||
case TAKE_GREEN_EGG:
|
||||
case TAKE_RED_EGG:
|
||||
case TAKE_YELLOW_EGG:
|
||||
return (role != Role.COLLECTOR && role != null) && game.isRemoveUnusedMenus();
|
||||
|
||||
|
||||
// Healer role options
|
||||
case TELL_CRACKERS_HEALER_HORN:
|
||||
case TELL_TOFU_HEALER_HORN:
|
||||
case TELL_WORMS_HEALER_HORN:
|
||||
return ((role == Role.HEALER && isHornOptionHidden(entry.getOption())) || role == null) && game.isRemoveIncorrectCalls();
|
||||
|
||||
case DUNK_POISON_CRATER:
|
||||
case STOCK_UP_HEALER_ITEM_MACHINE:
|
||||
case TAKE_HEALER_ITEM_MACHINE:
|
||||
case TAKE_FROM_HEALER_SPRING:
|
||||
case DRINK_FROM_HEALER_SPRING:
|
||||
return (role != Role.HEALER && role != null) && game.isRemoveUnusedMenus();
|
||||
|
||||
case USE_VIAL_GROUND:
|
||||
case USE_VIAL_ITEM:
|
||||
case USE_VIAL_NPC:
|
||||
case USE_VIAL_WIDGET:
|
||||
return role == Role.HEALER && game.isRemoveUnusedMenus();
|
||||
|
||||
|
||||
// Any role options
|
||||
case DROP_HORN:
|
||||
case EXAMINE_HORN:
|
||||
case USE_HORN:
|
||||
return game.isRemoveIncorrectCalls();
|
||||
|
||||
case MEDIC_HORN:
|
||||
return game.isRemoveIncorrectCalls() && !hornUpdated;
|
||||
|
||||
default:
|
||||
return role != null && game.isRemoveUnusedMenus();
|
||||
}
|
||||
});
|
||||
|
||||
hiddenMenus.removeAll(conditionalMenus);
|
||||
|
||||
for (Menus entry : hiddenMenus)
|
||||
{
|
||||
menuManager.addHiddenEntry(entry.getEntry());
|
||||
tracker.add(entry.getEntry());
|
||||
}
|
||||
}
|
||||
|
||||
void enableSwaps()
|
||||
{
|
||||
if (game.isSwapLadder())
|
||||
{
|
||||
menuManager.addSwap("climb-down", "ladder", "quick-start", "ladder");
|
||||
}
|
||||
if (game.isSwapCollectorBag())
|
||||
{
|
||||
menuManager.addSwap("look-in", "collection bag", "empty", "collection bag");
|
||||
}
|
||||
if (game.isSwapDestroyEggs())
|
||||
{
|
||||
menuManager.addSwap("use", "blue egg", "destroy", "blue egg");
|
||||
menuManager.addSwap("use", "green egg", "destroy", "green egg");
|
||||
menuManager.addSwap("use", "red egg", "destroy", "red egg");
|
||||
}
|
||||
}
|
||||
|
||||
void disableSwaps(boolean force)
|
||||
{
|
||||
if (!game.isSwapLadder() || force)
|
||||
{
|
||||
menuManager.removeSwap("climb-down", "ladder", "quick-start", "ladder");
|
||||
}
|
||||
|
||||
if (!game.isSwapCollectorBag() || force)
|
||||
{
|
||||
menuManager.removeSwap("look-in", "collection bag", "empty", "collection bag");
|
||||
}
|
||||
|
||||
if (!game.isSwapDestroyEggs() || force)
|
||||
{
|
||||
menuManager.removeSwap("use", "blue egg", "destroy", "blue egg");
|
||||
menuManager.removeSwap("use", "green egg", "destroy", "green egg");
|
||||
menuManager.removeSwap("use", "red egg", "destroy", "red egg");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
|
||||
public enum DeathTimesMode
|
||||
{
|
||||
BOTH("Both"),
|
||||
CHAT_BOX("Chat Box"),
|
||||
INFO_BOX("Info Box");
|
||||
|
||||
private final String name;
|
||||
|
||||
DeathTimesMode(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
|
||||
|
||||
@Data
|
||||
class Healer
|
||||
{
|
||||
@Getter(AccessLevel.NONE)
|
||||
private static final List<List<int[]>> CODES = ImmutableList.of(
|
||||
// ImmutableList.of(firstCallFood, secondCallFood, lastFoodTime),
|
||||
ImmutableList.of(new int[]{1, 1}, new int[]{0, 0}, new int[]{0, 0}),
|
||||
ImmutableList.of(new int[]{1, 1, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 21}),
|
||||
ImmutableList.of(new int[]{1, 6, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 0}),
|
||||
ImmutableList.of(new int[]{2, 5, 2, 0}, new int[]{0, 0, 7, 10}, new int[]{0, 0, 0, 0}),
|
||||
ImmutableList.of(new int[]{2, 5, 2, 3, 0}, new int[]{0, 0, 0, 0, 7}, new int[]{0, 0, 21, 30, 0}),
|
||||
ImmutableList.of(new int[]{3, 5, 2, 2, 0, 0}, new int[]{0, 0, 0, 2, 9, 10}, new int[]{12, 18, 21, 0, 0, 0}),
|
||||
ImmutableList.of(new int[]{3, 7, 1, 1, 0, 0, 0}, new int[]{2, 0, 1, 1, 2, 4, 10}, new int[]{0, 21, 0, 0, 30, 45, 0}),
|
||||
ImmutableList.of(new int[]{1, 9, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 2, 10}, new int[]{0, 0, 0, 0, 33, 42, 0}),
|
||||
ImmutableList.of(new int[]{2, 8, 1, 1, 0, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 1, 1, 10}, new int[]{0, 21, 0, 0, 0, 0, 0, 0, 0}),
|
||||
ImmutableList.of(new int[]{2, 5, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 4, 4, 8}, new int[]{21, 33, 0, 33, 30, 45, 0}));
|
||||
|
||||
private final NPC npc;
|
||||
|
||||
private int wave;
|
||||
|
||||
private int spawnNumber;
|
||||
|
||||
private int foodRemaining;
|
||||
|
||||
private int lastFoodTime;
|
||||
|
||||
private int firstCallFood;
|
||||
|
||||
private int secondCallFood;
|
||||
|
||||
private Instant timeLastPoisoned = null;
|
||||
|
||||
Healer(NPC npc, int spawnNumber, int wave)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.wave = wave;
|
||||
this.spawnNumber = spawnNumber;
|
||||
List<int[]> code = CODES.get(wave - 1);
|
||||
this.firstCallFood = code.get(0)[spawnNumber];
|
||||
this.secondCallFood = code.get(1)[spawnNumber];
|
||||
this.lastFoodTime = code.get(2)[spawnNumber];
|
||||
this.foodRemaining = firstCallFood + secondCallFood;
|
||||
}
|
||||
|
||||
int timeToPoison()
|
||||
{
|
||||
if (timeLastPoisoned == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
long time = Duration.between(timeLastPoisoned, Instant.now()).getSeconds();
|
||||
return time > 20 ? 0 : (int) (20 - time);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.MenuOpcode;
|
||||
import net.runelite.client.menus.BaseComparableEntry;
|
||||
import static net.runelite.client.menus.ComparableEntries.newBaseComparableEntry;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum Menus
|
||||
{
|
||||
ATTACK_PENANCE_FIGHTER(Role.ATTACKER, newBaseComparableEntry("attack", "penance fighter", -1, -1, true, false)),
|
||||
ATTACK_PENANCE_RANGER(Role.ATTACKER, newBaseComparableEntry("attack", "penance ranger", -1, -1, true, false)),
|
||||
GET_SPIKES_PETRIFIED_MUSHROOM(Role.ATTACKER, newBaseComparableEntry("get-spikes", "petrified mushroom", -1, -1, true, true)),
|
||||
TAKE_ATTACKER_ITEM_MACHINE(Role.ATTACKER, newBaseComparableEntry("take", "attacker item machine", -1, -1, false, true)),
|
||||
TELL_RED_ATTACKER_HORN(Role.ATTACKER, newBaseComparableEntry("tell-red", "attacker horn", -1, -1, true, true)),
|
||||
TELL_GREEN_ATTACKER_HORN(Role.ATTACKER, newBaseComparableEntry("tell-green", "attacker horn", -1, -1, true, true)),
|
||||
TELL_BLUE_ATTACKER_HORN(Role.ATTACKER, newBaseComparableEntry("tell-blue", "attacker horn", -1, -1, true, true)),
|
||||
|
||||
BLOCK_PENANCE_CAVE(Role.DEFENDER, newBaseComparableEntry("block", "penance cave", -1, -1, true, true)),
|
||||
DUNK_LAVA_CRATER(Role.DEFENDER, newBaseComparableEntry("dunk", "lava crater", -1, -1, true, true)),
|
||||
FIX(Role.DEFENDER, newBaseComparableEntry("fix", "", -1, -1, true, false)),
|
||||
STOCK_UP_DEFENDER_ITEM_MACHINE(Role.DEFENDER, newBaseComparableEntry("stock-up", "defender item machine", -1, -1, true, true)),
|
||||
TAKE_DEFENDER_ITEM_MACHINE(Role.DEFENDER, newBaseComparableEntry("take", "defender item machine", -1, -1, false, true)),
|
||||
TAKE_HAMMER(Role.DEFENDER, newBaseComparableEntry("take", "hammer", -1, -1, true, true)),
|
||||
TAKE_LOGS(Role.DEFENDER, newBaseComparableEntry("take", "logs", -1, -1, true, true)),
|
||||
TELL_WORMS_DEFENDER_HORN(Role.DEFENDER, newBaseComparableEntry("tell-worms", "defender horn", -1, -1, true, true)),
|
||||
TELL_TOFU_DEFENDER_HORN(Role.DEFENDER, newBaseComparableEntry("tell-tofu", "defender horn", -1, -1, true, true)),
|
||||
TELL_MEAT_DEFENDER_HORN(Role.DEFENDER, newBaseComparableEntry("tell-meat", "defender horn", -1, -1, true, true)),
|
||||
|
||||
DRINK_FROM_HEALER_SPRING(Role.HEALER, newBaseComparableEntry("drink-from", "healer spring", -1, -1, true, true)),
|
||||
DUNK_POISON_CRATER(Role.HEALER, newBaseComparableEntry("dunk", "poison crater", -1, -1, true, true)),
|
||||
STOCK_UP_HEALER_ITEM_MACHINE(Role.HEALER, newBaseComparableEntry("stock-up", "healer item machine", -1, -1, true, true)),
|
||||
TAKE_HEALER_ITEM_MACHINE(Role.HEALER, newBaseComparableEntry("take", "healer item machine", -1, -1, false, true)),
|
||||
TAKE_FROM_HEALER_SPRING(Role.HEALER, newBaseComparableEntry("take-from", "healer spring", -1, -1, true, true)),
|
||||
TELL_TOFU_HEALER_HORN(Role.HEALER, newBaseComparableEntry("tell-tofu", "healer horn", -1, -1, true, true)),
|
||||
TELL_CRACKERS_HEALER_HORN(Role.HEALER, newBaseComparableEntry("tell-crackers", "healer horn", -1, -1, true, true)),
|
||||
TELL_WORMS_HEALER_HORN(Role.HEALER, newBaseComparableEntry("tell-worms", "healer horn", -1, -1, true, true)),
|
||||
USE_VIAL_GROUND(Role.HEALER, newBaseComparableEntry("use", "healing vial", -1, MenuOpcode.ITEM_USE_ON_GROUND_ITEM.getId(), true, false)),
|
||||
USE_VIAL_ITEM(Role.HEALER, newBaseComparableEntry("use", "healing vial", -1, MenuOpcode.ITEM_USE_ON_WIDGET_ITEM.getId(), true, false)),
|
||||
USE_VIAL_NPC(Role.HEALER, newBaseComparableEntry("use", "healing vial", -1, MenuOpcode.ITEM_USE_ON_NPC.getId(), true, false)),
|
||||
USE_VIAL_WIDGET(Role.HEALER, newBaseComparableEntry("use", "healing vial", -1, MenuOpcode.ITEM_USE_ON_WIDGET.getId(), true, false)),
|
||||
|
||||
CONVERT_COLLECTOR_CONVERTER(Role.COLLECTOR, newBaseComparableEntry("convert", "collector converter", -1, -1, true, true)),
|
||||
LOAD_EGG_HOPPER(Role.COLLECTOR, newBaseComparableEntry("load", "egg hopper", -1, -1, true, true)),
|
||||
TAKE_BLUE_EGG(Role.COLLECTOR, newBaseComparableEntry("take", "blue egg", -1, -1, true, true)),
|
||||
TAKE_GREEN_EGG(Role.COLLECTOR, newBaseComparableEntry("take", "green egg", -1, -1, true, true)),
|
||||
TAKE_RED_EGG(Role.COLLECTOR, newBaseComparableEntry("take", "red egg", -1, -1, true, true)),
|
||||
TAKE_YELLOW_EGG(Role.COLLECTOR, newBaseComparableEntry("take", "yellow egg", -1, -1, true, true)),
|
||||
TELL_CONTROLLED_COLLECTOR_HORN(Role.COLLECTOR, newBaseComparableEntry("tell-controlled", "collector horn", -1, -1, true, true)),
|
||||
TELL_ACCURATE_COLLECTOR_HORN(Role.COLLECTOR, newBaseComparableEntry("tell-accurate", "collector horn", -1, -1, true, true)),
|
||||
TELL_AGGRESSIVE_COLLECTOR_HORN(Role.COLLECTOR, newBaseComparableEntry("tell-aggressive", "collector horn", -1, -1, true, true)),
|
||||
TELL_DEFENSIVE_COLLECTOR_HORN(Role.COLLECTOR, newBaseComparableEntry("tell-defensive", "collector horn", -1, -1, true, true)),
|
||||
|
||||
ATTACK_PENANCE_QUEEN(null, newBaseComparableEntry("attack", "penance queen", -1, -1, true, false)),
|
||||
ATTACK_QUEEN_SPAWN(null, newBaseComparableEntry("attack", "queen spawn", -1, -1, true, false)),
|
||||
DROP_HORN(null, newBaseComparableEntry("drop", "r horn", -1, -1, true, false)),
|
||||
EXAMINE_HORN(null, newBaseComparableEntry("examine", "r horn", -1, -1, true, false)),
|
||||
LIGHT_LOGS(null, newBaseComparableEntry("light", "logs", -1, -1, true, true)),
|
||||
MEDIC_HORN(null, newBaseComparableEntry("medic", "r horn", -1, -1, true, false)),
|
||||
USE_HORN(null, newBaseComparableEntry("use", "r horn", -1, -1, true, false));
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Role role;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final BaseComparableEntry entry;
|
||||
|
||||
private static final ImmutableSet<Menus> ALL = ImmutableSet.copyOf(Menus.values());
|
||||
|
||||
public String getOption()
|
||||
{
|
||||
return entry.getOption();
|
||||
}
|
||||
|
||||
public String getTarget()
|
||||
{
|
||||
return entry.getTarget();
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return entry.getId();
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return entry.getType();
|
||||
}
|
||||
|
||||
public boolean isStrictOption()
|
||||
{
|
||||
return entry.isStrictOption();
|
||||
}
|
||||
|
||||
public boolean isStrictTarget()
|
||||
{
|
||||
return entry.isStrictTarget();
|
||||
}
|
||||
|
||||
public static ImmutableSet<Menus> getMenus()
|
||||
{
|
||||
return ALL;
|
||||
}
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
enum Role
|
||||
{
|
||||
ATTACKER(WidgetInfo.BA_ATK_WAVE_TEXT, WidgetInfo.BA_ATK_LISTEN_TOP_TEXT, WidgetInfo.BA_ATK_HORN_LISTEN_TEXT,
|
||||
WidgetInfo.BA_ATK_CALL_TEXT, WidgetInfo.BA_COLL_HORN_LISTEN_TEXT, WidgetInfo.BA_ATK_ROLE_TEXT,
|
||||
WidgetInfo.BA_ATK_ROLE_SPRITE),
|
||||
DEFENDER(WidgetInfo.BA_DEF_WAVE_TEXT, WidgetInfo.BA_DEF_LISTEN_TEXT, WidgetInfo.BA_DEF_HORN_LISTEN_TEXT,
|
||||
WidgetInfo.BA_DEF_CALL_TEXT, WidgetInfo.BA_HEAL_HORN_LISTEN_TEXT, WidgetInfo.BA_DEF_ROLE_TEXT,
|
||||
WidgetInfo.BA_DEF_ROLE_SPRITE),
|
||||
COLLECTOR(WidgetInfo.BA_COLL_WAVE_TEXT, WidgetInfo.BA_COLL_LISTEN_TEXT, WidgetInfo.BA_COLL_HORN_LISTEN_TEXT,
|
||||
WidgetInfo.BA_COLL_CALL_TEXT, WidgetInfo.BA_ATK_HORN_LISTEN_TEXT, WidgetInfo.BA_COLL_ROLE_TEXT,
|
||||
WidgetInfo.BA_COLL_ROLE_SPRITE),
|
||||
HEALER(WidgetInfo.BA_HEAL_WAVE_TEXT, WidgetInfo.BA_HEAL_LISTEN_TEXT, WidgetInfo.BA_DEF_HORN_LISTEN_TEXT,
|
||||
WidgetInfo.BA_HEAL_CALL_TEXT, WidgetInfo.BA_DEF_HORN_LISTEN_TEXT, WidgetInfo.BA_HEAL_ROLE_TEXT,
|
||||
WidgetInfo.BA_HEAL_ROLE_SPRITE);
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo wave;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo listen;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo gloryListen;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo call;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo gloryCall;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo roleText;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WidgetInfo roleSprite;
|
||||
|
||||
// Duplicate* entries are to catch instances where the horn of glory has
|
||||
// text different than the normal horn
|
||||
private static final ImmutableMap<String, String> TELLS = ImmutableMap.<String, String>builder()
|
||||
.put("Red egg", "Tell-red")
|
||||
.put("Green egg", "Tell-green")
|
||||
.put("Blue egg", "Tell-blue")
|
||||
.put("Controlled/Bullet/Wind", "Tell-controlled")
|
||||
.put("Accurate/Field/Water", "Tell-accurate")
|
||||
.put("Aggressive/Blunt/Earth", "Tell-aggressive")
|
||||
.put("Defensive/Barbed/Fire", "Tell-defensive")
|
||||
.put("Tofu", "Tell-tofu")
|
||||
.put("Crackers", "Tell-crackers")
|
||||
.put("Worms", "Tell-worms")
|
||||
.put("Poison Worms", "Tell-worms")
|
||||
.put("Pois. Worms", "Tell-worms")
|
||||
.put("Poison Tofu", "Tell-tofu")
|
||||
.put("Pois. Tofu", "Tell-tofu")
|
||||
.put("Poison Meat", "Tell-meat")
|
||||
.put("Pois. Meat", "Tell-meat")
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> GLORY_CALLS = ImmutableMap.<String, String>builder()
|
||||
.put("Controlled/Bullet/Wind", "Controlled/")
|
||||
.put("Accurate/Field/Water", "Accurate/")
|
||||
.put("Aggressive/Blunt/Earth", "Aggressive/")
|
||||
.put("Defensive/Barbed/Fire", "Defensive/")
|
||||
.put("Tofu", "Tofu")
|
||||
.put("Crackers", "Crackers")
|
||||
.put("Worms", "Worms")
|
||||
.put("Poison worms", "Pois. Worms")
|
||||
.put("Poison tofu", "Pois. Tofu")
|
||||
.put("Poison meat", "Pois. Meat")
|
||||
.put("Red egg", "Red egg")
|
||||
.put("Green egg", "Green egg")
|
||||
.put("Blue egg", "Blue egg")
|
||||
.build();
|
||||
private static final ImmutableMap<String, Integer> ITEMS = ImmutableMap.<String, Integer>builder()
|
||||
.put("Tofu", ItemID.TOFU)
|
||||
.put("Crackers", ItemID.CRACKERS)
|
||||
.put("Worms", ItemID.WORMS)
|
||||
.put("Pois. Worms", ItemID.POISONED_WORMS)
|
||||
.put("Pois. Tofu", ItemID.POISONED_TOFU)
|
||||
.put("Pois. Meat", ItemID.POISONED_MEAT)
|
||||
.put("Defensive/", ItemID.BARBED_ARROW)
|
||||
.put("Aggressive/", ItemID.BLUNT_ARROW)
|
||||
.put("Accurate/", ItemID.FIELD_ARROW)
|
||||
.put("Controlled/", ItemID.BULLET_ARROW)
|
||||
.build();
|
||||
private static final ImmutableMap<String, String> SPLIT_LISTENS = ImmutableMap.<String, String>builder()
|
||||
.put("Controlled/", "Bullet/Wind")
|
||||
.put("Bullet/Wind", "Controlled/")
|
||||
.put("Accurate/", "Field/Water")
|
||||
.put("Field/Water", "Accurate/")
|
||||
.put("Aggressive/", "Blunt/Earth")
|
||||
.put("Blunt/Earth", "Aggressive/")
|
||||
.put("Defensive/", "Barbed/Fire")
|
||||
.put("Barbed/Fire", "Defensive/")
|
||||
.build();
|
||||
|
||||
|
||||
int getListenItem(String listen)
|
||||
{
|
||||
return ITEMS.getOrDefault(listen, -1);
|
||||
}
|
||||
|
||||
String getTell(String call)
|
||||
{
|
||||
return TELLS.getOrDefault(call, "");
|
||||
}
|
||||
|
||||
String getCall(Client client)
|
||||
{
|
||||
// Do not reverse these if statements to be more efficient
|
||||
// The normal widgets are no longer null/hidden after you
|
||||
// click one time in the horn, and the values are incorrect
|
||||
Widget callWidget = client.getWidget(getGloryCall());
|
||||
if (callWidget != null)
|
||||
{
|
||||
return GLORY_CALLS.get(callWidget.getText());
|
||||
}
|
||||
|
||||
callWidget = client.getWidget(getCall());
|
||||
if (callWidget != null)
|
||||
{
|
||||
return callWidget.getText();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String getListen(Client client)
|
||||
{
|
||||
// See the comment in getCall(Client client), before editing
|
||||
Widget listenWidget = client.getWidget(getGloryListen());
|
||||
if (listenWidget != null)
|
||||
{
|
||||
return GLORY_CALLS.get(listenWidget.getText());
|
||||
}
|
||||
|
||||
listenWidget = client.getWidget(getListen());
|
||||
if (listenWidget != null)
|
||||
{
|
||||
return listenWidget.getText();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String getMissingListen(String listen)
|
||||
{
|
||||
return SPLIT_LISTENS.getOrDefault(listen, "- - -");
|
||||
}
|
||||
|
||||
// I call it "Switchception" :wutwedoin:
|
||||
// Should probably switch to using an interface instead of an enum at this point
|
||||
String getCallFromTell(String listen)
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case COLLECTOR:
|
||||
switch (listen)
|
||||
{
|
||||
case "Tell-controlled":
|
||||
return "Controlled/";
|
||||
case "Tell-accurate":
|
||||
return "Accurate/";
|
||||
case "Tell-aggressive":
|
||||
return "Aggressive/";
|
||||
case "Tell-defensive":
|
||||
return "Defensive/";
|
||||
}
|
||||
break;
|
||||
case ATTACKER:
|
||||
switch (listen)
|
||||
{
|
||||
case "Tell-red":
|
||||
return "Red egg";
|
||||
case "Tell-green":
|
||||
return "Green egg";
|
||||
case "Tell-blue":
|
||||
return "Blue egg";
|
||||
}
|
||||
break;
|
||||
case HEALER:
|
||||
switch (listen)
|
||||
{
|
||||
case "Tell-tofu":
|
||||
return "Tofu";
|
||||
case "Tell-crackers":
|
||||
return "Crackers";
|
||||
case "Tell-worms":
|
||||
return "Worms";
|
||||
}
|
||||
break;
|
||||
case DEFENDER:
|
||||
switch (listen)
|
||||
{
|
||||
case "Tell-meat":
|
||||
return "Pois. Meat";
|
||||
case "Tell-tofu":
|
||||
return "Pois. Tofu";
|
||||
case "Tell-worms":
|
||||
return "Pois. Worms";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class Scorecard
|
||||
{
|
||||
private BarbarianAssaultPlugin game;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private List<Wave> waves = new ArrayList<>();
|
||||
private String[] totalDescriptions = {
|
||||
"A: ",
|
||||
"; D: ",
|
||||
"; C: ",
|
||||
"; Vial: ",
|
||||
"; H packs: ",
|
||||
"; Total: "};
|
||||
private String[] otherPointsDescriptions = {
|
||||
" A: ",
|
||||
"; D: ",
|
||||
"; C: ",
|
||||
"; H: "
|
||||
};
|
||||
private int[] totalPoints = new int[6];
|
||||
private int[] totalAmounts = new int[6];
|
||||
private int[] otherRolesPoints = new int[4];
|
||||
|
||||
Scorecard(BarbarianAssaultPlugin game)
|
||||
{
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
if (chatMessage.getMessage().startsWith("---- Points:") && game.getStage() == 1)
|
||||
{
|
||||
totalPoints = new int[6];
|
||||
totalAmounts = new int[6];
|
||||
}
|
||||
}
|
||||
|
||||
void addWave(Wave wave)
|
||||
{
|
||||
this.waves.add(wave);
|
||||
}
|
||||
|
||||
int getNumberOfWaves()
|
||||
{
|
||||
return waves.size();
|
||||
}
|
||||
|
||||
ChatMessageBuilder getGameSummary()
|
||||
{
|
||||
int[] amountsList;
|
||||
int[] pointsList;
|
||||
int[] otherRolesPointsList;
|
||||
ChatMessageBuilder message = new ChatMessageBuilder();
|
||||
message.append("Game points: ");
|
||||
for (Wave wave : waves)
|
||||
{
|
||||
amountsList = wave.getAmounts();
|
||||
pointsList = wave.getPoints();
|
||||
otherRolesPointsList = wave.getOtherRolesPointsList();
|
||||
for (int j = 0; j < totalAmounts.length; j++)
|
||||
{
|
||||
totalAmounts[j] += amountsList[j];
|
||||
}
|
||||
for (int k = 0; k < totalPoints.length; k++)
|
||||
{
|
||||
totalPoints[k] += pointsList[k];
|
||||
}
|
||||
for (int z = 0; z < otherRolesPoints.length; z++)
|
||||
{
|
||||
otherRolesPoints[z] += otherRolesPointsList[z];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < otherRolesPoints.length; i++)
|
||||
{
|
||||
otherRolesPoints[i] += 80;
|
||||
}
|
||||
totalAmounts[5] += 80;
|
||||
for (int i = 0; i < totalDescriptions.length; i++)
|
||||
{
|
||||
if (i != 4)
|
||||
{
|
||||
message.append(totalDescriptions[i]);
|
||||
message.append(String.valueOf(totalAmounts[i]));
|
||||
message.append("(");
|
||||
if (totalPoints[i] < 0)
|
||||
{
|
||||
message.append(Color.RED, String.valueOf(totalPoints[i]));
|
||||
}
|
||||
else if (totalPoints[i] > 0)
|
||||
{
|
||||
message.append(Color.BLUE, String.valueOf(totalPoints[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
message.append(String.valueOf(totalPoints[i]));
|
||||
}
|
||||
message.append(")");
|
||||
}
|
||||
}
|
||||
message.append(System.getProperty("line.separator"));
|
||||
message.append("All roles points this game: ");
|
||||
for (int i = 0; i < otherPointsDescriptions.length; i++)
|
||||
{
|
||||
message.append(otherPointsDescriptions[i]);
|
||||
message.append(String.valueOf(otherRolesPoints[i]));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
class Timer
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Instant startTime;
|
||||
|
||||
Timer()
|
||||
{
|
||||
this.startTime = Instant.now();
|
||||
}
|
||||
|
||||
long getElapsedTime()
|
||||
{
|
||||
return Duration.between(startTime, Instant.now()).getSeconds();
|
||||
}
|
||||
|
||||
String getElapsedTimeFormatted()
|
||||
{
|
||||
return formatTime(LocalTime.ofSecondOfDay(getElapsedTime()));
|
||||
}
|
||||
|
||||
private static String formatTime(LocalTime time)
|
||||
{
|
||||
if (time.getHour() > 0)
|
||||
{
|
||||
return time.format(DateTimeFormatter.ofPattern("HH:mm"));
|
||||
}
|
||||
else if (time.getMinute() > 9)
|
||||
{
|
||||
return time.format(DateTimeFormatter.ofPattern("mm:ss"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return time.format(DateTimeFormatter.ofPattern("m:ss"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class TimerBox extends InfoBox
|
||||
{
|
||||
private int count;
|
||||
|
||||
private boolean inSync = true;
|
||||
|
||||
private boolean tooltipEnabled = false;
|
||||
|
||||
TimerBox(BufferedImage image, Plugin plugin, int count)
|
||||
{
|
||||
super(image, plugin);
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
if (count == -1)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return Integer.toString(getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getTextColor()
|
||||
{
|
||||
if (inSync)
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip()
|
||||
{
|
||||
if (!tooltipEnabled)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else if (inSync)
|
||||
{
|
||||
return "<col=00FF00>Valid";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "<col=FF0000>Invalid";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* Copyright (c) 2019, 7ate9 <https://github.com/se7enAte9>
|
||||
* Copyright (c) 2019, https://openosrs.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.barbarianassault;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.awt.Color;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
|
||||
@Data
|
||||
public class Wave
|
||||
{
|
||||
@Getter(AccessLevel.NONE)
|
||||
private static final ImmutableList<WidgetInfo> WIDGETS = ImmutableList.of(
|
||||
WidgetInfo.BA_FAILED_ATTACKER_ATTACKS,
|
||||
WidgetInfo.BA_RUNNERS_PASSED,
|
||||
WidgetInfo.BA_EGGS_COLLECTED,
|
||||
WidgetInfo.BA_HITPOINTS_REPLENISHED,
|
||||
WidgetInfo.BA_WRONG_POISON_PACKS,
|
||||
WidgetInfo.BA_HONOUR_POINTS_REWARD
|
||||
);
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private static final ImmutableList<WidgetInfo> POINTSWIDGETS = ImmutableList.of(
|
||||
//Base
|
||||
WidgetInfo.BA_BASE_POINTS,
|
||||
//Attacker
|
||||
WidgetInfo.BA_FAILED_ATTACKER_ATTACKS_POINTS,
|
||||
WidgetInfo.BA_RANGERS_KILLED,
|
||||
WidgetInfo.BA_FIGHTERS_KILLED,
|
||||
//Defender
|
||||
WidgetInfo.BA_RUNNERS_PASSED_POINTS,
|
||||
WidgetInfo.BA_RUNNERS_KILLED,
|
||||
//Collector
|
||||
WidgetInfo.BA_EGGS_COLLECTED_POINTS,
|
||||
//Healer
|
||||
WidgetInfo.BA_HEALERS_KILLED,
|
||||
WidgetInfo.BA_HITPOINTS_REPLENISHED_POINTS,
|
||||
WidgetInfo.BA_WRONG_POISON_PACKS_POINTS
|
||||
);
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private final Client client;
|
||||
|
||||
private final Timer waveTimer;
|
||||
|
||||
private boolean runnersKilled;
|
||||
|
||||
private boolean rangersKilled;
|
||||
|
||||
private boolean healersKilled;
|
||||
|
||||
private boolean fightersKilled;
|
||||
|
||||
private int collectedEggCount = 0;
|
||||
|
||||
private int positiveEggCount = 0;
|
||||
|
||||
private int wrongEggs = 0;
|
||||
|
||||
private int hpHealed = 0;
|
||||
|
||||
private int totalCollectedEggCount = 0;
|
||||
|
||||
private int totalHpHealed = 0;
|
||||
|
||||
private int[] amounts = new int[6];
|
||||
|
||||
private int[] allPointsList = new int[10];
|
||||
|
||||
private int[] points = new int[6];
|
||||
|
||||
private int[] otherRolesPointsList = new int[4];
|
||||
|
||||
private String[] descriptions = {" A: ", "; D: ", "; C: ", "; Vial: ", "; H packs: ", "; Total: "};
|
||||
|
||||
private String[] otherPointsDescriptions = {" A: ", " D: ", " C: ", " H: "};
|
||||
|
||||
Wave(Client client)
|
||||
{
|
||||
this.client = client;
|
||||
this.waveTimer = new Timer();
|
||||
}
|
||||
|
||||
void setAmounts()
|
||||
{
|
||||
for (int i = 0; i < WIDGETS.size(); i++)
|
||||
{
|
||||
Widget w = client.getWidget(WIDGETS.get(i));
|
||||
if (w != null)
|
||||
{
|
||||
amounts[i] = Integer.parseInt(w.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setPoints()
|
||||
{
|
||||
for (int i = 0; i < POINTSWIDGETS.size(); i++)
|
||||
{
|
||||
Widget w = client.getWidget(POINTSWIDGETS.get(i));
|
||||
allPointsList[i] = Integer.parseInt(w.getText());
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
points[0] += allPointsList[i];
|
||||
break;
|
||||
case 4:
|
||||
points[1] += allPointsList[i];
|
||||
break;
|
||||
case 6:
|
||||
points[2] += allPointsList[i];
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
points[3] += allPointsList[i];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
points[5] = 0;
|
||||
for (int i = 0; i < points.length - 1; i++)
|
||||
{
|
||||
points[5] += points[i];
|
||||
}
|
||||
for (int i = 0; i < POINTSWIDGETS.size(); i++)
|
||||
{
|
||||
Widget w = client.getWidget(POINTSWIDGETS.get(i));
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
otherRolesPointsList[0] += Integer.parseInt(w.getText());
|
||||
otherRolesPointsList[1] += Integer.parseInt(w.getText());
|
||||
otherRolesPointsList[2] += Integer.parseInt(w.getText());
|
||||
otherRolesPointsList[3] += Integer.parseInt(w.getText());
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
otherRolesPointsList[0] += Integer.parseInt(w.getText());
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
otherRolesPointsList[1] += Integer.parseInt(w.getText());
|
||||
break;
|
||||
case 6:
|
||||
otherRolesPointsList[2] += Integer.parseInt(w.getText());
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
otherRolesPointsList[3] += Integer.parseInt(w.getText());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChatMessageBuilder getSummary()
|
||||
{
|
||||
ChatMessageBuilder message = new ChatMessageBuilder();
|
||||
message.append("Wave points:");
|
||||
for (int i = 0; i < descriptions.length; i++)
|
||||
{
|
||||
message.append(descriptions[i]);
|
||||
if (i != 5)
|
||||
{
|
||||
message.append(String.valueOf(amounts[i]));
|
||||
}
|
||||
message.append("(");
|
||||
if (points[i] < 0)
|
||||
{
|
||||
message.append(Color.RED, String.valueOf(points[i]));
|
||||
}
|
||||
else if (points[i] > 0)
|
||||
{
|
||||
message.append(Color.BLUE, String.valueOf(points[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
message.append(String.valueOf(points[i]));
|
||||
}
|
||||
message.append(")");
|
||||
}
|
||||
message.append(System.getProperty("line.separator"));
|
||||
message.append("All roles points this wave: ");
|
||||
for (int i = 0; i < otherPointsDescriptions.length; i++)
|
||||
{
|
||||
message.append(otherPointsDescriptions[i]);
|
||||
message.append(String.valueOf(otherRolesPointsList[i]));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@Singleton
|
||||
public class BarrowsBrotherSlainOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private BarrowsBrotherSlainOverlay(final BarrowsPlugin plugin, final Client client)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
this.client = client;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Barrows overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Do not display overlay if potential is null/hidden
|
||||
final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL);
|
||||
if (potential == null || potential.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Hide original overlay
|
||||
final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS);
|
||||
if (barrowsBrothers != null)
|
||||
{
|
||||
barrowsBrothers.setHidden(true);
|
||||
potential.setHidden(true);
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
|
||||
for (BarrowsBrothers brother : BarrowsBrothers.values())
|
||||
{
|
||||
final boolean brotherSlain = client.getVar(brother.getKilledVarbit()) > 0;
|
||||
String slain = brotherSlain ? "\u2713" : "\u2717";
|
||||
tableComponent.addRow(brother.getName(), ColorUtil.prependColorTag(slain, brotherSlain ? Color.GREEN : Color.RED));
|
||||
}
|
||||
|
||||
float rewardPercent = client.getVar(Varbits.BARROWS_REWARD_POTENTIAL) / 10.0f;
|
||||
tableComponent.addRow("Potential", ColorUtil.prependColorTag(rewardPercent != 0 ? rewardPercent + "%" : "0%", rewardPercent >= 73.0f && rewardPercent <= 88.0f ? Color.GREEN : rewardPercent < 65.6f ? Color.WHITE : Color.YELLOW));
|
||||
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.barrows;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum BarrowsBrothers
|
||||
{
|
||||
AHRIM("Ahrim", new WorldPoint(3566, 3289, 0), Varbits.BARROWS_KILLED_AHRIM),
|
||||
DHAROK("Dharok", new WorldPoint(3575, 3298, 0), Varbits.BARROWS_KILLED_DHAROK),
|
||||
GUTHAN("Guthan", new WorldPoint(3577, 3283, 0), Varbits.BARROWS_KILLED_GUTHAN),
|
||||
KARIL("Karil", new WorldPoint(3566, 3275, 0), Varbits.BARROWS_KILLED_KARIL),
|
||||
TORAG("Torag", new WorldPoint(3553, 3283, 0), Varbits.BARROWS_KILLED_TORAG),
|
||||
VERAC("Verac", new WorldPoint(3557, 3298, 0), Varbits.BARROWS_KILLED_VERAC);
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final String name;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final WorldPoint location;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Varbits killedVarbit;
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("barrows")
|
||||
public interface BarrowsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "showMinimap",
|
||||
name = "Show Minimap in tunnels",
|
||||
description = "Configures whether or not the minimap is displayed",
|
||||
position = 0
|
||||
)
|
||||
default boolean showMinimap()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showBrotherLoc",
|
||||
name = "Show Brothers location",
|
||||
description = "Configures whether or not the brothers location is displayed",
|
||||
position = 1
|
||||
)
|
||||
default boolean showBrotherLoc()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "brotherLocColor",
|
||||
name = "Brother location color",
|
||||
description = "Change the color of the name displayed on the minimap",
|
||||
position = 2
|
||||
)
|
||||
default Color brotherLocColor()
|
||||
{
|
||||
return Color.CYAN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "deadBrotherLocColor",
|
||||
name = "Dead Brother loc. color",
|
||||
description = "Change the color of the name displayed on the minimap for a dead brother",
|
||||
position = 3
|
||||
)
|
||||
default Color deadBrotherLocColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showPuzzleAnswer",
|
||||
name = "Show Puzzle Answer",
|
||||
description = "Configures if the puzzle answer should be shown.",
|
||||
position = 4
|
||||
)
|
||||
default boolean showPuzzleAnswer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showPrayerDrainTimer",
|
||||
name = "Show Prayer Drain Timer",
|
||||
description = "Configure whether or not a countdown until the next prayer drain is displayed",
|
||||
position = 5
|
||||
)
|
||||
default boolean showPrayerDrainTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.barrows;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.ObjectDefinition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@Singleton
|
||||
class BarrowsOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
|
||||
private final Client client;
|
||||
private final BarrowsPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private BarrowsOverlay(final Client client, final BarrowsPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
final Color npcColor = getMinimapDotColor(1);
|
||||
final Color playerColor = getMinimapDotColor(2);
|
||||
Widget puzzleAnswer = plugin.getPuzzleAnswer();
|
||||
|
||||
// tunnels are only on z=0
|
||||
if (!plugin.getWalls().isEmpty() && client.getPlane() == 0 && plugin.isShowMinimap())
|
||||
{
|
||||
// NPC dots
|
||||
graphics.setColor(npcColor);
|
||||
final List<NPC> npcs = client.getNpcs();
|
||||
for (NPC npc : npcs)
|
||||
{
|
||||
final NPCDefinition composition = npc.getDefinition();
|
||||
|
||||
if (composition != null && !composition.isMinimapVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
net.runelite.api.Point minimapLocation = npc.getMinimapLocation();
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Player dots
|
||||
graphics.setColor(playerColor);
|
||||
final List<Player> players = client.getPlayers();
|
||||
for (Player player : players)
|
||||
{
|
||||
if (player == local)
|
||||
{
|
||||
// Skip local player as we draw square for it later
|
||||
continue;
|
||||
}
|
||||
|
||||
net.runelite.api.Point minimapLocation = player.getMinimapLocation();
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
graphics.fillOval(minimapLocation.getX(), minimapLocation.getY(), 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Render barrows walls/doors
|
||||
renderObjects(graphics, local);
|
||||
|
||||
// Local player square
|
||||
graphics.setColor(playerColor);
|
||||
graphics.fillRect(local.getMinimapLocation().getX(), local.getMinimapLocation().getY(), 3, 3);
|
||||
}
|
||||
else if (plugin.isShowBrotherLoc())
|
||||
{
|
||||
renderBarrowsBrothers(graphics);
|
||||
}
|
||||
|
||||
if (puzzleAnswer != null && plugin.isShowPuzzleAnswer() && !puzzleAnswer.isHidden())
|
||||
{
|
||||
Rectangle answerRect = puzzleAnswer.getBounds();
|
||||
graphics.setColor(Color.GREEN);
|
||||
graphics.draw(answerRect);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderObjects(Graphics2D graphics, Player localPlayer)
|
||||
{
|
||||
LocalPoint localLocation = localPlayer.getLocalLocation();
|
||||
for (WallObject wall : plugin.getWalls())
|
||||
{
|
||||
LocalPoint location = wall.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderWalls(graphics, wall);
|
||||
}
|
||||
}
|
||||
|
||||
for (GameObject ladder : plugin.getLadders())
|
||||
{
|
||||
LocalPoint location = ladder.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderLadders(graphics, ladder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderWalls(Graphics2D graphics, WallObject wall)
|
||||
{
|
||||
net.runelite.api.Point minimapLocation = wall.getMinimapLocation();
|
||||
|
||||
if (minimapLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectDefinition objectComp = client.getObjectDefinition(wall.getId());
|
||||
ObjectDefinition impostor = objectComp.getImpostorIds() != null ? objectComp.getImpostor() : null;
|
||||
|
||||
if (impostor != null && impostor.getActions()[0] != null)
|
||||
{
|
||||
graphics.setColor(Color.green);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(Color.gray);
|
||||
}
|
||||
|
||||
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 3, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimap dot color from client
|
||||
*
|
||||
* @param typeIndex index of minimap dot type (1 npcs, 2 players)
|
||||
* @return color
|
||||
*/
|
||||
private Color getMinimapDotColor(int typeIndex)
|
||||
{
|
||||
final int pixel = client.getMapDots()[typeIndex].getPixels()[1];
|
||||
return new Color(pixel);
|
||||
}
|
||||
|
||||
private void renderLadders(Graphics2D graphics, GameObject ladder)
|
||||
{
|
||||
net.runelite.api.Point minimapLocation = ladder.getMinimapLocation();
|
||||
|
||||
if (minimapLocation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectDefinition objectComp = client.getObjectDefinition(ladder.getId());
|
||||
|
||||
if (objectComp.getImpostorIds() != null && objectComp.getImpostor() != null)
|
||||
{
|
||||
graphics.setColor(Color.orange);
|
||||
graphics.fillRect(minimapLocation.getX(), minimapLocation.getY(), 6, 6);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderBarrowsBrothers(Graphics2D graphics)
|
||||
{
|
||||
for (BarrowsBrothers brother : BarrowsBrothers.values())
|
||||
{
|
||||
LocalPoint localLocation = LocalPoint.fromWorld(client, brother.getLocation());
|
||||
|
||||
if (localLocation == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String brotherLetter = Character.toString(brother.getName().charAt(0));
|
||||
net.runelite.api.Point minimapText = Perspective.getCanvasTextMiniMapLocation(client, graphics,
|
||||
localLocation, brotherLetter);
|
||||
|
||||
if (minimapText != null)
|
||||
{
|
||||
graphics.setColor(Color.black);
|
||||
graphics.drawString(brotherLetter, minimapText.getX() + 1, minimapText.getY() + 1);
|
||||
|
||||
if (client.getVar(brother.getKilledVarbit()) > 0)
|
||||
{
|
||||
graphics.setColor(plugin.getDeadBrotherLocColor());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(plugin.getBrotherLocColor());
|
||||
}
|
||||
|
||||
graphics.drawString(brotherLetter, minimapText.getX(), minimapText.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.barrows;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.NullObjectID;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.events.GameObjectChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.WallObjectChanged;
|
||||
import net.runelite.api.events.WallObjectDespawned;
|
||||
import net.runelite.api.events.WallObjectSpawned;
|
||||
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.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxPriority;
|
||||
import net.runelite.client.ui.overlay.infobox.LoopTimer;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Barrows Brothers",
|
||||
description = "Show helpful information for the Barrows minigame",
|
||||
tags = {"combat", "minigame", "minimap", "bosses", "pve", "pvm"},
|
||||
type = PluginType.MINIGAME
|
||||
)
|
||||
@Singleton
|
||||
public class BarrowsPlugin extends Plugin
|
||||
{
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private static final Set<Integer> BARROWS_WALLS = Sets.newHashSet
|
||||
(
|
||||
ObjectID.DOOR_20678, NullObjectID.NULL_20681, NullObjectID.NULL_20682, NullObjectID.NULL_20683, NullObjectID.NULL_20684, NullObjectID.NULL_20685, NullObjectID.NULL_20686, NullObjectID.NULL_20687,
|
||||
NullObjectID.NULL_20688, NullObjectID.NULL_20689, NullObjectID.NULL_20690, NullObjectID.NULL_20691, NullObjectID.NULL_20692, NullObjectID.NULL_20693, NullObjectID.NULL_20694, NullObjectID.NULL_20695,
|
||||
NullObjectID.NULL_20696, ObjectID.DOOR_20697, NullObjectID.NULL_20700, NullObjectID.NULL_20701, NullObjectID.NULL_20702, NullObjectID.NULL_20703, NullObjectID.NULL_20704, NullObjectID.NULL_20705,
|
||||
NullObjectID.NULL_20706, NullObjectID.NULL_20707, NullObjectID.NULL_20708, NullObjectID.NULL_20709, NullObjectID.NULL_20710, NullObjectID.NULL_20711, NullObjectID.NULL_20712, NullObjectID.NULL_20713,
|
||||
NullObjectID.NULL_20714, NullObjectID.NULL_20715, NullObjectID.NULL_20728, NullObjectID.NULL_20730
|
||||
);
|
||||
|
||||
private static final Set<Integer> BARROWS_LADDERS = Sets.newHashSet(NullObjectID.NULL_20675, NullObjectID.NULL_20676, NullObjectID.NULL_20677);
|
||||
private static final ImmutableList<WidgetInfo> POSSIBLE_SOLUTIONS = ImmutableList.of(
|
||||
WidgetInfo.BARROWS_PUZZLE_ANSWER1,
|
||||
WidgetInfo.BARROWS_PUZZLE_ANSWER2,
|
||||
WidgetInfo.BARROWS_PUZZLE_ANSWER3
|
||||
);
|
||||
|
||||
private static final long PRAYER_DRAIN_INTERVAL_MS = 18200;
|
||||
private static final int CRYPT_REGION_ID = 14231;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<WallObject> walls = new HashSet<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<GameObject> ladders = new HashSet<>();
|
||||
|
||||
private LoopTimer barrowsPrayerDrainTimer;
|
||||
private boolean wasInCrypt = false;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Widget puzzleAnswer;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private BarrowsOverlay barrowsOverlay;
|
||||
|
||||
@Inject
|
||||
private BarrowsBrotherSlainOverlay brotherOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private BarrowsConfig config;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showMinimap;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showBrotherLoc;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color brotherLocColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Color deadBrotherLocColor;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean showPuzzleAnswer;
|
||||
private boolean showPrayerDrainTimer;
|
||||
|
||||
@Provides
|
||||
BarrowsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BarrowsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
overlayManager.add(barrowsOverlay);
|
||||
overlayManager.add(brotherOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
overlayManager.remove(barrowsOverlay);
|
||||
overlayManager.remove(brotherOverlay);
|
||||
walls.clear();
|
||||
ladders.clear();
|
||||
puzzleAnswer = null;
|
||||
wasInCrypt = false;
|
||||
stopPrayerDrainTimer();
|
||||
|
||||
// Restore widgets
|
||||
final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL);
|
||||
if (potential != null)
|
||||
{
|
||||
potential.setHidden(false);
|
||||
}
|
||||
|
||||
final Widget barrowsBrothers = client.getWidget(WidgetInfo.BARROWS_BROTHERS);
|
||||
if (barrowsBrothers != null)
|
||||
{
|
||||
barrowsBrothers.setHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("barrows"))
|
||||
{
|
||||
updateConfig();
|
||||
|
||||
if (!this.showPrayerDrainTimer)
|
||||
{
|
||||
stopPrayerDrainTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.showMinimap = config.showMinimap();
|
||||
this.showBrotherLoc = config.showBrotherLoc();
|
||||
this.brotherLocColor = config.brotherLocColor();
|
||||
this.deadBrotherLocColor = config.deadBrotherLocColor();
|
||||
this.showPuzzleAnswer = config.showPuzzleAnswer();
|
||||
this.showPrayerDrainTimer = config.showPrayerDrainTimer();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWallObjectSpawned(WallObjectSpawned event)
|
||||
{
|
||||
WallObject wallObject = event.getWallObject();
|
||||
if (BARROWS_WALLS.contains(wallObject.getId()))
|
||||
{
|
||||
walls.add(wallObject);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWallObjectChanged(WallObjectChanged event)
|
||||
{
|
||||
WallObject previous = event.getPrevious();
|
||||
WallObject wallObject = event.getWallObject();
|
||||
|
||||
walls.remove(previous);
|
||||
if (BARROWS_WALLS.contains(wallObject.getId()))
|
||||
{
|
||||
walls.add(wallObject);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWallObjectDespawned(WallObjectDespawned event)
|
||||
{
|
||||
WallObject wallObject = event.getWallObject();
|
||||
walls.remove(wallObject);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
if (BARROWS_LADDERS.contains(gameObject.getId()))
|
||||
{
|
||||
ladders.add(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectChanged(GameObjectChanged event)
|
||||
{
|
||||
GameObject previous = event.getPrevious();
|
||||
GameObject gameObject = event.getGameObject();
|
||||
|
||||
ladders.remove(previous);
|
||||
if (BARROWS_LADDERS.contains(gameObject.getId()))
|
||||
{
|
||||
ladders.add(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
ladders.remove(gameObject);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
wasInCrypt = isInCrypt();
|
||||
// on region changes the tiles get set to null
|
||||
walls.clear();
|
||||
ladders.clear();
|
||||
puzzleAnswer = null;
|
||||
}
|
||||
else if (event.getGameState() == GameState.LOGGED_IN && client.getLocalPlayer() != null)
|
||||
{
|
||||
boolean isInCrypt = isInCrypt();
|
||||
if (wasInCrypt && !isInCrypt)
|
||||
{
|
||||
stopPrayerDrainTimer();
|
||||
}
|
||||
else if (!wasInCrypt && isInCrypt)
|
||||
{
|
||||
startPrayerDrainTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() == WidgetID.BARROWS_PUZZLE_GROUP_ID)
|
||||
{
|
||||
final int answer = client.getWidget(WidgetInfo.BARROWS_FIRST_PUZZLE).getModelId() - 3;
|
||||
puzzleAnswer = null;
|
||||
|
||||
for (WidgetInfo puzzleNode : POSSIBLE_SOLUTIONS)
|
||||
{
|
||||
final Widget widgetToCheck = client.getWidget(puzzleNode);
|
||||
|
||||
if (widgetToCheck != null && widgetToCheck.getModelId() == answer)
|
||||
{
|
||||
puzzleAnswer = client.getWidget(puzzleNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startPrayerDrainTimer()
|
||||
{
|
||||
if (this.showPrayerDrainTimer)
|
||||
{
|
||||
final LoopTimer loopTimer = new LoopTimer(
|
||||
PRAYER_DRAIN_INTERVAL_MS,
|
||||
ChronoUnit.MILLIS,
|
||||
null,
|
||||
this,
|
||||
true);
|
||||
|
||||
spriteManager.getSpriteAsync(SpriteID.TAB_PRAYER, 0, loopTimer);
|
||||
|
||||
loopTimer.setPriority(InfoBoxPriority.MED);
|
||||
loopTimer.setTooltip("Prayer Drain");
|
||||
|
||||
infoBoxManager.addInfoBox(loopTimer);
|
||||
barrowsPrayerDrainTimer = loopTimer;
|
||||
}
|
||||
}
|
||||
|
||||
private void stopPrayerDrainTimer()
|
||||
{
|
||||
infoBoxManager.removeInfoBox(barrowsPrayerDrainTimer);
|
||||
barrowsPrayerDrainTimer = null;
|
||||
}
|
||||
|
||||
private boolean isInCrypt()
|
||||
{
|
||||
return client.getLocalPlayer().getWorldLocation().getRegionID() == CRYPT_REGION_ID;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* 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.blackjack;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("blackjack")
|
||||
public interface BlackjackConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "pickpocketOnAggro",
|
||||
name = "Pickpocket when aggro\'d",
|
||||
description = "Switches to \"Pickpocket\" when bandit is aggro\'d. Saves food at the cost of slight xp/h.",
|
||||
position = 0
|
||||
)
|
||||
default boolean pickpocketOnAggro()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "random",
|
||||
name = "Randomly Miss 1 Pickpocket",
|
||||
description = "If enabled, this will randomly miss 1 pickpocket every so often." +
|
||||
"<br> Not sure why'd you want to do that, but you can.",
|
||||
position = 1
|
||||
)
|
||||
default boolean random()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 gazivodag <https://github.com/gazivodag>
|
||||
* Copyright (c) 2019 lucwousin <https://github.com/lucwousin>
|
||||
* Copyright (c) 2019 infinitay <https://github.com/Infinitay>
|
||||
* 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.blackjack;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.util.Text;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.menus.AbstractComparableEntry;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
|
||||
/**
|
||||
* Authors gazivodag longstreet
|
||||
*/
|
||||
@PluginDescriptor(
|
||||
name = "Blackjack",
|
||||
description = "Allows for one-click blackjacking, both knocking out and pickpocketing",
|
||||
tags = {"blackjack", "thieving"},
|
||||
type = PluginType.SKILLING,
|
||||
enabledByDefault = false
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class BlackjackPlugin extends Plugin
|
||||
{
|
||||
private static final int POLLNIVNEACH_REGION = 13358;
|
||||
|
||||
private static final String SUCCESS_BLACKJACK = "You smack the bandit over the head and render them unconscious.";
|
||||
private static final String FAILED_BLACKJACK = "Your blow only glances off the bandit's head.";
|
||||
|
||||
private static final String PICKPOCKET = "Pickpocket";
|
||||
private static final String KNOCK_OUT = "Knock-out";
|
||||
private static final String BANDIT = "Bandit";
|
||||
private static final String MENAPHITE = "Menaphite Thug";
|
||||
|
||||
private static final AbstractComparableEntry PICKPOCKET_BANDIT = new BJComparableEntry(BANDIT, true);
|
||||
private static final AbstractComparableEntry KNOCKOUT_BANDIT = new BJComparableEntry(BANDIT, false);
|
||||
private static final AbstractComparableEntry PICKPOCKET_MENAPHITE = new BJComparableEntry(MENAPHITE, true);
|
||||
private static final AbstractComparableEntry KNOCKOUT_MENAPHITE = new BJComparableEntry(MENAPHITE, false);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private BlackjackConfig config;
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
|
||||
@Inject
|
||||
private MenuManager menuManager;
|
||||
|
||||
private boolean pickpocketOnAggro;
|
||||
private boolean random;
|
||||
private long nextKnockOutTick = 0;
|
||||
|
||||
@Provides
|
||||
BlackjackConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BlackjackConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
menuManager.addPriorityEntry(KNOCKOUT_BANDIT);
|
||||
menuManager.addPriorityEntry(KNOCKOUT_MENAPHITE);
|
||||
this.pickpocketOnAggro = config.pickpocketOnAggro();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
menuManager.removePriorityEntry(PICKPOCKET_BANDIT);
|
||||
menuManager.removePriorityEntry(PICKPOCKET_MENAPHITE);
|
||||
menuManager.removePriorityEntry(KNOCKOUT_BANDIT);
|
||||
menuManager.removePriorityEntry(KNOCKOUT_MENAPHITE);
|
||||
eventBus.unregister("poll");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() != GameState.LOGGED_IN || !ArrayUtils.contains(client.getMapRegions(), POLLNIVNEACH_REGION))
|
||||
{
|
||||
eventBus.unregister("poll");
|
||||
return;
|
||||
}
|
||||
|
||||
eventBus.subscribe(GameTick.class, "poll", this::onGameTick);
|
||||
eventBus.subscribe(ChatMessage.class, "poll", this::onChatMessage);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (event.getGroup().equals("blackjack"))
|
||||
{
|
||||
this.pickpocketOnAggro = config.pickpocketOnAggro();
|
||||
this.random = config.random();
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
if (client.getTickCount() >= nextKnockOutTick)
|
||||
{
|
||||
menuManager.removePriorityEntry(PICKPOCKET_BANDIT);
|
||||
menuManager.removePriorityEntry(PICKPOCKET_MENAPHITE);
|
||||
menuManager.addPriorityEntry(KNOCKOUT_BANDIT);
|
||||
menuManager.addPriorityEntry(KNOCKOUT_MENAPHITE);
|
||||
}
|
||||
}
|
||||
|
||||
private void onChatMessage(ChatMessage event)
|
||||
{
|
||||
final String msg = event.getMessage();
|
||||
|
||||
if (event.getType() == ChatMessageType.SPAM && (msg.equals(SUCCESS_BLACKJACK) || (msg.equals(FAILED_BLACKJACK) && this.pickpocketOnAggro)))
|
||||
{
|
||||
menuManager.removePriorityEntry(KNOCKOUT_BANDIT);
|
||||
menuManager.removePriorityEntry(KNOCKOUT_MENAPHITE);
|
||||
menuManager.addPriorityEntry(PICKPOCKET_BANDIT);
|
||||
menuManager.addPriorityEntry(PICKPOCKET_MENAPHITE);
|
||||
final int ticks = this.random ? RandomUtils.nextInt(3, 4) : 4;
|
||||
nextKnockOutTick = client.getTickCount() + ticks;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BJComparableEntry extends AbstractComparableEntry
|
||||
{
|
||||
private BJComparableEntry(final String npc, final boolean pickpocket)
|
||||
{
|
||||
if (!BANDIT.equals(npc) && !MENAPHITE.equals(npc))
|
||||
{
|
||||
throw new IllegalArgumentException("Only bandits or menaphites are valid");
|
||||
}
|
||||
|
||||
this.setTarget(npc.toLowerCase());
|
||||
this.setOption(pickpocket ? PICKPOCKET : KNOCK_OUT);
|
||||
this.setPriority(100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MenuEntry entry)
|
||||
{
|
||||
return entry.getOption().equalsIgnoreCase(this.getOption()) &&
|
||||
Text.removeTags(entry.getTarget(), true).equalsIgnoreCase(this.getTarget());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.blastfurnace;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.Varbits;
|
||||
|
||||
public enum BarsOres
|
||||
{
|
||||
COPPER_ORE(Varbits.BLAST_FURNACE_COPPER_ORE, ItemID.COPPER_ORE),
|
||||
TIN_ORE(Varbits.BLAST_FURNACE_TIN_ORE, ItemID.TIN_ORE),
|
||||
IRON_ORE(Varbits.BLAST_FURNACE_IRON_ORE, ItemID.IRON_ORE),
|
||||
COAL(Varbits.BLAST_FURNACE_COAL, ItemID.COAL),
|
||||
MITHRIL_ORE(Varbits.BLAST_FURNACE_MITHRIL_ORE, ItemID.MITHRIL_ORE),
|
||||
ADAMANTITE_ORE(Varbits.BLAST_FURNACE_ADAMANTITE_ORE, ItemID.ADAMANTITE_ORE),
|
||||
RUNITE_ORE(Varbits.BLAST_FURNACE_RUNITE_ORE, ItemID.RUNITE_ORE),
|
||||
SILVER_ORE(Varbits.BLAST_FURNACE_SILVER_ORE, ItemID.SILVER_ORE),
|
||||
GOLD_ORE(Varbits.BLAST_FURNACE_GOLD_ORE, ItemID.GOLD_ORE),
|
||||
BRONZE_BAR(Varbits.BLAST_FURNACE_BRONZE_BAR, ItemID.BRONZE_BAR),
|
||||
IRON_BAR(Varbits.BLAST_FURNACE_IRON_BAR, ItemID.IRON_BAR),
|
||||
STEEL_BAR(Varbits.BLAST_FURNACE_STEEL_BAR, ItemID.STEEL_BAR),
|
||||
MITHRIL_BAR(Varbits.BLAST_FURNACE_MITHRIL_BAR, ItemID.MITHRIL_BAR),
|
||||
ADAMANTITE_BAR(Varbits.BLAST_FURNACE_ADAMANTITE_BAR, ItemID.ADAMANTITE_BAR),
|
||||
RUNITE_BAR(Varbits.BLAST_FURNACE_RUNITE_BAR, ItemID.RUNITE_BAR),
|
||||
SILVER_BAR(Varbits.BLAST_FURNACE_SILVER_BAR, ItemID.SILVER_BAR),
|
||||
GOLD_BAR(Varbits.BLAST_FURNACE_GOLD_BAR, ItemID.GOLD_BAR);
|
||||
|
||||
private static final Map<Varbits, BarsOres> VARBIT;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Varbits, BarsOres> builder = new ImmutableMap.Builder<>();
|
||||
|
||||
for (BarsOres s : values())
|
||||
{
|
||||
builder.put(s.getVarbit(), s);
|
||||
}
|
||||
|
||||
VARBIT = builder.build();
|
||||
}
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Varbits varbit;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final int itemID;
|
||||
|
||||
BarsOres(Varbits varbit, int itemID)
|
||||
{
|
||||
this.varbit = varbit;
|
||||
this.itemID = itemID;
|
||||
}
|
||||
|
||||
public static BarsOres getVarbit(Varbits varbit)
|
||||
{
|
||||
return VARBIT.get(varbit);
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.blastfurnace;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
@Singleton
|
||||
class BlastFurnaceClickBoxOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
|
||||
private final Client client;
|
||||
private final BlastFurnacePlugin plugin;
|
||||
|
||||
@Inject
|
||||
private BlastFurnaceClickBoxOverlay(final Client client, final BlastFurnacePlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
int dispenserState = client.getVar(Varbits.BAR_DISPENSER);
|
||||
|
||||
if (plugin.isShowConveyorBelt() && plugin.getConveyorBelt() != null)
|
||||
{
|
||||
Color color = dispenserState == 1 ? Color.RED : Color.GREEN;
|
||||
renderObject(plugin.getConveyorBelt(), graphics, color);
|
||||
}
|
||||
|
||||
if (plugin.isShowBarDispenser() && plugin.getBarDispenser() != null)
|
||||
{
|
||||
boolean hasIceGloves = hasIceGloves();
|
||||
Color color = dispenserState == 2 && hasIceGloves ? Color.GREEN : (dispenserState == 3 ? Color.GREEN : Color.RED);
|
||||
|
||||
renderObject(plugin.getBarDispenser(), graphics, color);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasIceGloves()
|
||||
{
|
||||
ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
if (equipmentContainer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Item[] items = equipmentContainer.getItems();
|
||||
int idx = EquipmentInventorySlot.GLOVES.getSlotIdx();
|
||||
|
||||
if (items == null || idx >= items.length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Item glove = items[idx];
|
||||
return glove != null && glove.getId() == ItemID.ICE_GLOVES;
|
||||
}
|
||||
|
||||
private void renderObject(GameObject object, Graphics2D graphics, Color color)
|
||||
{
|
||||
LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
|
||||
Point mousePosition = client.getMouseCanvasPosition();
|
||||
|
||||
LocalPoint location = object.getLocalLocation();
|
||||
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
Shape objectClickbox = object.getClickbox();
|
||||
if (objectClickbox != null)
|
||||
{
|
||||
if (objectClickbox.contains(mousePosition.getX(), mousePosition.getY()))
|
||||
{
|
||||
graphics.setColor(color.darker());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(color);
|
||||
}
|
||||
graphics.draw(objectClickbox);
|
||||
graphics.setColor(new Color(0xFF, 0, 0, 20));
|
||||
graphics.fill(objectClickbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.blastfurnace;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG;
|
||||
import static net.runelite.api.Varbits.BLAST_FURNACE_COFFER;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
|
||||
@Singleton
|
||||
class BlastFurnaceCofferOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final BlastFurnacePlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private BlastFurnaceCofferOverlay(final Client client, final BlastFurnacePlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Coffer overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (plugin.getConveyorBelt() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
|
||||
Widget sack = client.getWidget(WidgetInfo.BLAST_FURNACE_COFFER);
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (sack != null)
|
||||
{
|
||||
sack.setHidden(true);
|
||||
|
||||
tableComponent.addRow("Coffer:", QuantityFormatter.quantityToStackSize(client.getVar(BLAST_FURNACE_COFFER)) + " gp");
|
||||
}
|
||||
|
||||
if (!tableComponent.isEmpty())
|
||||
{
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.blastfurnace;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("blastfurnace")
|
||||
public interface BlastFurnaceConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "showConveyorBelt",
|
||||
name = "Show conveyor belt clickbox",
|
||||
description = "Configures whether or not the clickbox for the conveyor belt is displayed",
|
||||
position = 1
|
||||
)
|
||||
default boolean showConveyorBelt()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showBarDispenser",
|
||||
name = "Show bar dispenser clickbox",
|
||||
description = "Configures whether or not the clickbox for the bar dispenser is displayed",
|
||||
position = 2
|
||||
)
|
||||
default boolean showBarDispenser()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@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.blastfurnace;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuOpcode.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.ComponentOrientation;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
@Singleton
|
||||
class BlastFurnaceOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final BlastFurnacePlugin plugin;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
BlastFurnaceOverlay(final Client client, final BlastFurnacePlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
imagePanelComponent.setOrientation(ComponentOrientation.HORIZONTAL);
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Blast furnace overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (plugin.getConveyorBelt() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
|
||||
for (BarsOres varbit : BarsOres.values())
|
||||
{
|
||||
int amount = client.getVar(varbit.getVarbit());
|
||||
|
||||
if (amount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(getImage(varbit.getItemID(), amount)));
|
||||
}
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getImage(int itemID, int amount)
|
||||
{
|
||||
return itemManager.getImage(itemID, amount, true);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user