client: Remove all plugins

This commit is contained in:
Owain van Brakel
2020-02-04 05:25:51 +01:00
parent c26d6ffbb8
commit cbb5c50939
1918 changed files with 0 additions and 240603 deletions

View File

@@ -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());
}
}

View File

@@ -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";
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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";
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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";
}
}

View File

@@ -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();
}
}

View File

@@ -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 {}

View File

@@ -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();
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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)
)
);
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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");
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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];
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
});
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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>");
}
}
});
}
}

View File

@@ -1,9 +0,0 @@
package net.runelite.client.plugins.banlist;
public enum ListType
{
WEDORAIDSSCAM_LIST,
WEDORAIDSTOXIC_LIST,
RUNEWATCH_LIST,
MANUAL_LIST
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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"));
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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