Changes 2 (#43)
* Initial commit for maxhit plugin
* WIP: Magic max hit calculator
* Add chance to obtain a Unique from Chambers of Xeric
Based on the formula from the wiki. Does not handle >80% chance properly (it should go into a second item)
* MaxHit Refactor a lot for magic max hit
* Wip: refactoring
* Pest Control Update
* Pest Control: Add Intermediate portals
* Revert "Remove raids points overlay"
This reverts commit fbd3ea6202.
* Wip: refactoring
* Fixed WidgetInfo merge issue
* Fixed trident
* Implement range
* Refactored according to intellij analyzer
* Run checkstyle from xml and fix code style issues
* Fix copyright
* Replace item names with item id's
* Code cleanup with reformat code
* Fixed checkstyle
* Use game slotitem
* Use game slotitem
* Fixed prayer bonus
* Looked up value for saradomin strike
* Fixed prayer bonus
* Fixed surge spell id's
* Fixed magix max hit tests
* Fixed rounding after obisidian
* Fix dharok custom formula
* Add melee max hit
* Refactored spellbonus items for magic
* Added voidknight
* Use boosted skill levels and add copyright
* Add accurate attack style for ranging
* Add range Tests
* Cleanup code
* Cleanup code
* Rename calculate methods to be more distinguishable
* Add parenthesis to dharok maxhit formula for clarification
* Fix widgetinfo merge
* Remove print in MaxHitPlugin
* Make sure an Item is not null when checking if the player is wearing it.
* Add daily notification for collection of ogre arrows from Rantz.
Add varbit for rantz arrow collection
Fix continuation indent settings
Group ifs to single check.
* Refactor all relevant daily checks to have grouped if check.
Further refactor grouped ifs
* Adds type
* Raids point overlay
This commit is contained in:
@@ -372,6 +372,7 @@ public enum Varbits {
|
|||||||
DAILY_ESSENCE_COLLECTED(4547),
|
DAILY_ESSENCE_COLLECTED(4547),
|
||||||
DAILY_RUNES_COLLECTED(4540),
|
DAILY_RUNES_COLLECTED(4540),
|
||||||
DAILY_SAND_COLLECTED(4549),
|
DAILY_SAND_COLLECTED(4549),
|
||||||
|
DAILY_ARROWS_STATE(4563),
|
||||||
DAILY_FLAX_STATE(4559),
|
DAILY_FLAX_STATE(4559),
|
||||||
/**
|
/**
|
||||||
* This varbit tracks how much bonemeal has been redeemed from Robin
|
* This varbit tracks how much bonemeal has been redeemed from Robin
|
||||||
@@ -481,6 +482,14 @@ public enum Varbits {
|
|||||||
*/
|
*/
|
||||||
GE_OFFER_CREATION_TYPE(4397),
|
GE_OFFER_CREATION_TYPE(4397),
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Spells being auto-casted
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
AUTO_CAST_SPELL(276),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The active tab within the quest interface
|
* The active tab within the quest interface
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public class WidgetID
|
|||||||
public static final int DIARY_GROUP_ID = 259;
|
public static final int DIARY_GROUP_ID = 259;
|
||||||
public static final int PEST_CONTROL_BOAT_GROUP_ID = 407;
|
public static final int PEST_CONTROL_BOAT_GROUP_ID = 407;
|
||||||
public static final int PEST_CONTROL_GROUP_ID = 408;
|
public static final int PEST_CONTROL_GROUP_ID = 408;
|
||||||
|
public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243;
|
||||||
|
public static final int PEST_CONTROL_DIALOG_GROUP_ID = 229;
|
||||||
public static final int CLAN_CHAT_GROUP_ID = 7;
|
public static final int CLAN_CHAT_GROUP_ID = 7;
|
||||||
public static final int MINIMAP_GROUP_ID = 160;
|
public static final int MINIMAP_GROUP_ID = 160;
|
||||||
public static final int LOGIN_CLICK_TO_PLAY_GROUP_ID = 378;
|
public static final int LOGIN_CLICK_TO_PLAY_GROUP_ID = 378;
|
||||||
@@ -127,6 +129,7 @@ public class WidgetID
|
|||||||
public static final int FULLSCREEN_MAP_GROUP_ID = 165;
|
public static final int FULLSCREEN_MAP_GROUP_ID = 165;
|
||||||
public static final int QUESTLIST_GROUP_ID = 399;
|
public static final int QUESTLIST_GROUP_ID = 399;
|
||||||
public static final int SKILLS_GROUP_ID = 320;
|
public static final int SKILLS_GROUP_ID = 320;
|
||||||
|
public static final int EQUIPMENT_PAGE_GROUP_ID = 84;
|
||||||
public static final int QUESTTAB_GROUP_ID = 629;
|
public static final int QUESTTAB_GROUP_ID = 629;
|
||||||
public static final int MUSIC_GROUP_ID = 239;
|
public static final int MUSIC_GROUP_ID = 239;
|
||||||
public static final int MUSICTAB_GROUP_ID = 239;
|
public static final int MUSICTAB_GROUP_ID = 239;
|
||||||
@@ -164,12 +167,32 @@ public class WidgetID
|
|||||||
static class PestControlBoat
|
static class PestControlBoat
|
||||||
{
|
{
|
||||||
static final int INFO = 3;
|
static final int INFO = 3;
|
||||||
|
|
||||||
|
static final int NEXT_DEPARTURE = 4;
|
||||||
|
static final int PLAYERS_READY = 5;
|
||||||
|
static final int POINTS = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class PestControlExchangeWindow
|
||||||
|
{
|
||||||
|
static final int ITEM_LIST = 2;
|
||||||
|
static final int BOTTOM = 5;
|
||||||
|
static final int POINTS = 8;
|
||||||
|
static final int CONFIRM_BUTTON = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class PestControlDialog
|
||||||
|
{
|
||||||
|
static final int TEXT = 1;
|
||||||
|
static final int CONTINUE = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class PestControl
|
static class PestControl
|
||||||
{
|
{
|
||||||
static final int INFO = 3;
|
static final int INFO = 3;
|
||||||
|
|
||||||
|
static final int TIME = 6;
|
||||||
|
|
||||||
static final int ACTIVITY_BAR = 12;
|
static final int ACTIVITY_BAR = 12;
|
||||||
static final int ACTIVITY_PROGRESS = 14;
|
static final int ACTIVITY_PROGRESS = 14;
|
||||||
|
|
||||||
@@ -675,6 +698,28 @@ public class WidgetID
|
|||||||
static final int DESTROY_ITEM_NO = 3;
|
static final int DESTROY_ITEM_NO = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class EquipmentWidgetIdentifiers
|
||||||
|
{
|
||||||
|
static final int EQUIP_YOUR_CHARACTER = 3;
|
||||||
|
static final int STAB_ATTACK_BONUS = 23;
|
||||||
|
static final int SLASH_ATTACK_BONUS = 24;
|
||||||
|
static final int CRUSH_ATTACK_BONUS = 25;
|
||||||
|
static final int MAGIC_ATTACK_BONUS = 26;
|
||||||
|
static final int RANGED_ATTACK_BONUS = 27;
|
||||||
|
static final int STAB_DEFENCE_BONUS = 29;
|
||||||
|
static final int SLASH_DEFENCE_BONUS = 30;
|
||||||
|
static final int CRUSH_DEFENCE_BONUS = 31;
|
||||||
|
static final int MAGIC_DEFENCE_BONUS = 32;
|
||||||
|
static final int RANGED_DEFENCE_BONUS = 33;
|
||||||
|
static final int MELEE_STRENGTH = 35;
|
||||||
|
static final int RANGED_STRENGTH = 36;
|
||||||
|
static final int MAGIC_DAMAGE = 37;
|
||||||
|
static final int PRAYER_BONUS = 38;
|
||||||
|
static final int UNDEAD_DAMAGE_BONUS = 40;
|
||||||
|
static final int SLAYER_DAMAGE_BONUS = 41;
|
||||||
|
static final int WEIGHT = 43;
|
||||||
|
}
|
||||||
|
|
||||||
static class VarrockMuseum
|
static class VarrockMuseum
|
||||||
{
|
{
|
||||||
static final int VARROCK_MUSEUM_QUESTION = 28;
|
static final int VARROCK_MUSEUM_QUESTION = 28;
|
||||||
|
|||||||
@@ -83,8 +83,14 @@ public enum WidgetInfo
|
|||||||
DIARY_QUEST_WIDGET_TITLE(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TITLE),
|
DIARY_QUEST_WIDGET_TITLE(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TITLE),
|
||||||
DIARY_QUEST_WIDGET_TEXT(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TEXT),
|
DIARY_QUEST_WIDGET_TEXT(WidgetID.DIARY_QUEST_GROUP_ID, WidgetID.Diary.DIARY_TEXT),
|
||||||
|
|
||||||
|
PEST_CONTROL_DIALOG(WidgetID.PEST_CONTROL_DIALOG_GROUP_ID, 0),
|
||||||
|
PEST_CONTROL_DIALOG_TEXT(WidgetID.PEST_CONTROL_DIALOG_GROUP_ID, WidgetID.PestControlDialog.TEXT),
|
||||||
|
PEST_CONTROL_EXCHANGE_WINDOW(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, 0),
|
||||||
|
PEST_CONTROL_EXCHANGE_WINDOW_POINTS(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, WidgetID.PestControlExchangeWindow.POINTS),
|
||||||
PEST_CONTROL_BOAT_INFO(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.INFO),
|
PEST_CONTROL_BOAT_INFO(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.INFO),
|
||||||
|
PEST_CONTROL_BOAT_INFO_POINTS(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.POINTS),
|
||||||
PEST_CONTROL_INFO(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.INFO),
|
PEST_CONTROL_INFO(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.INFO),
|
||||||
|
PEST_CONTROL_INFO_TIME(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.TIME),
|
||||||
PEST_CONTROL_PURPLE_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.PURPLE_SHIELD),
|
PEST_CONTROL_PURPLE_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.PURPLE_SHIELD),
|
||||||
PEST_CONTROL_BLUE_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.BLUE_SHIELD),
|
PEST_CONTROL_BLUE_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.BLUE_SHIELD),
|
||||||
PEST_CONTROL_YELLOW_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.YELLOW_SHIELD),
|
PEST_CONTROL_YELLOW_SHIELD(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.YELLOW_SHIELD),
|
||||||
@@ -550,7 +556,12 @@ public enum WidgetInfo
|
|||||||
MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12),
|
MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12),
|
||||||
MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13),
|
MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13),
|
||||||
|
|
||||||
QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB);
|
QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB),
|
||||||
|
|
||||||
|
EQUIPMENT_MELEE_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MELEE_STRENGTH),
|
||||||
|
EQUIPMENT_RANGED_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.RANGED_STRENGTH),
|
||||||
|
EQUIPMENT_MAGIC_DAMAGE(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MAGIC_DAMAGE),
|
||||||
|
EQUIP_YOUR_CHARACTER(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.EQUIP_YOUR_CHARACTER);
|
||||||
|
|
||||||
private final int groupId;
|
private final int groupId;
|
||||||
private final int childId;
|
private final int childId;
|
||||||
|
|||||||
@@ -109,4 +109,15 @@ public interface DailyTasksConfig extends Config
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 8,
|
||||||
|
keyName = "showArrows",
|
||||||
|
name = "Show Claimable Ogre Arrows",
|
||||||
|
description = "Show a message when you can collect ogre arrows from Rantz."
|
||||||
|
)
|
||||||
|
default boolean showArrows()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public class DailyTasksPlugin extends Plugin
|
|||||||
private static final String SAND_MESSAGE = "You have sand waiting to be collected from Bert.";
|
private static final String SAND_MESSAGE = "You have sand waiting to be collected from Bert.";
|
||||||
private static final int SAND_QUEST_COMPLETE = 160;
|
private static final int SAND_QUEST_COMPLETE = 160;
|
||||||
private static final String FLAX_MESSAGE = "You have bowstrings waiting to be converted from flax from the Flax keeper.";
|
private static final String FLAX_MESSAGE = "You have bowstrings waiting to be converted from flax from the Flax keeper.";
|
||||||
|
private static final String ARROWS_MESSAGE = "You have ogre arrows waiting to be collected from Rantz.";
|
||||||
private static final String BONEMEAL_MESSAGE = "You have bonemeal and slime waiting to be collected from Robin.";
|
private static final String BONEMEAL_MESSAGE = "You have bonemeal and slime waiting to be collected from Robin.";
|
||||||
private static final int BONEMEAL_PER_DIARY = 13;
|
private static final int BONEMEAL_PER_DIARY = 13;
|
||||||
private static final String RELOG_MESSAGE = " (May require a relog)";
|
private static final String RELOG_MESSAGE = " (May require a relog)";
|
||||||
@@ -153,22 +154,21 @@ public class DailyTasksPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
checkBonemeal(dailyReset);
|
checkBonemeal(dailyReset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.showArrows())
|
||||||
|
{
|
||||||
|
checkArrows(dailyReset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkHerbBoxes(boolean dailyReset)
|
private void checkHerbBoxes(boolean dailyReset)
|
||||||
{
|
{
|
||||||
if (client.getAccountType() == AccountType.NORMAL
|
if ((client.getAccountType() == AccountType.NORMAL
|
||||||
&& client.getVar(VarPlayer.NMZ_REWARD_POINTS) >= HERB_BOX_COST)
|
&& client.getVar(VarPlayer.NMZ_REWARD_POINTS) >= HERB_BOX_COST)
|
||||||
|
&& (dailyReset || client.getVar(Varbits.DAILY_HERB_BOXES_COLLECTED) < HERB_BOX_MAX))
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DAILY_HERB_BOXES_COLLECTED) < HERB_BOX_MAX)
|
sendChatMessage(HERB_BOX_MESSAGE);
|
||||||
{
|
|
||||||
sendChatMessage(HERB_BOX_MESSAGE);
|
|
||||||
}
|
|
||||||
else if (dailyReset)
|
|
||||||
{
|
|
||||||
sendChatMessage(HERB_BOX_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,61 +189,46 @@ public class DailyTasksPlugin extends Plugin
|
|||||||
|
|
||||||
private void checkEssence(boolean dailyReset)
|
private void checkEssence(boolean dailyReset)
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DIARY_ARDOUGNE_MEDIUM) == 1)
|
if ((client.getVar(Varbits.DIARY_ARDOUGNE_MEDIUM) == 1)
|
||||||
|
&& (dailyReset || client.getVar(Varbits.DAILY_ESSENCE_COLLECTED) == 0))
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DAILY_ESSENCE_COLLECTED) == 0)
|
sendChatMessage(ESSENCE_MESSAGE);
|
||||||
{
|
|
||||||
sendChatMessage(ESSENCE_MESSAGE);
|
|
||||||
}
|
|
||||||
else if (dailyReset)
|
|
||||||
{
|
|
||||||
sendChatMessage(ESSENCE_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRunes(boolean dailyReset)
|
private void checkRunes(boolean dailyReset)
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DIARY_WILDERNESS_EASY) == 1)
|
if ((client.getVar(Varbits.DIARY_WILDERNESS_EASY) == 1)
|
||||||
|
&& (dailyReset || client.getVar(Varbits.DAILY_RUNES_COLLECTED) == 0))
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DAILY_RUNES_COLLECTED) == 0)
|
sendChatMessage(RUNES_MESSAGE);
|
||||||
{
|
|
||||||
sendChatMessage(RUNES_MESSAGE);
|
|
||||||
}
|
|
||||||
else if (dailyReset)
|
|
||||||
{
|
|
||||||
sendChatMessage(RUNES_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSand(boolean dailyReset)
|
private void checkSand(boolean dailyReset)
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.QUEST_THE_HAND_IN_THE_SAND) >= SAND_QUEST_COMPLETE)
|
if ((client.getVar(Varbits.QUEST_THE_HAND_IN_THE_SAND) >= SAND_QUEST_COMPLETE)
|
||||||
|
&& (dailyReset || client.getVar(Varbits.DAILY_SAND_COLLECTED) == 0))
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DAILY_SAND_COLLECTED) == 0)
|
sendChatMessage(SAND_MESSAGE);
|
||||||
{
|
|
||||||
sendChatMessage(SAND_MESSAGE);
|
|
||||||
}
|
|
||||||
else if (dailyReset)
|
|
||||||
{
|
|
||||||
sendChatMessage(SAND_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFlax(boolean dailyReset)
|
private void checkFlax(boolean dailyReset)
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DIARY_KANDARIN_EASY) == 1)
|
if ((client.getVar(Varbits.DIARY_KANDARIN_EASY) == 1)
|
||||||
|
&& (dailyReset || client.getVar(Varbits.DAILY_FLAX_STATE) == 0))
|
||||||
{
|
{
|
||||||
if (client.getVar(Varbits.DAILY_FLAX_STATE) == 0)
|
sendChatMessage(FLAX_MESSAGE);
|
||||||
{
|
}
|
||||||
sendChatMessage(FLAX_MESSAGE);
|
}
|
||||||
}
|
|
||||||
else if (dailyReset)
|
private void checkArrows(boolean dailyReset)
|
||||||
{
|
{
|
||||||
sendChatMessage(FLAX_MESSAGE);
|
if ((client.getVar(Varbits.DIARY_WESTERN_EASY) == 1)
|
||||||
}
|
&& (dailyReset || client.getVar(Varbits.DAILY_ARROWS_STATE) == 0))
|
||||||
|
{
|
||||||
|
sendChatMessage(ARROWS_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,11 +246,7 @@ public class DailyTasksPlugin extends Plugin
|
|||||||
max += BONEMEAL_PER_DIARY;
|
max += BONEMEAL_PER_DIARY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (collected < max)
|
if (dailyReset || collected < max)
|
||||||
{
|
|
||||||
sendChatMessage(BONEMEAL_MESSAGE);
|
|
||||||
}
|
|
||||||
else if (dailyReset)
|
|
||||||
{
|
{
|
||||||
sendChatMessage(BONEMEAL_MESSAGE);
|
sendChatMessage(BONEMEAL_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
|
import net.runelite.api.events.ItemContainerChanged;
|
||||||
|
import net.runelite.api.events.VarbitChanged;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MagicMaxHitCalculator;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MeleeMaxHitCalculator;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.RangeMaxHitCalculator;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
name = "Max Hit",
|
||||||
|
description = "Max Hit Calculator",
|
||||||
|
type = "PVM",
|
||||||
|
enabledByDefault = false
|
||||||
|
)
|
||||||
|
public class MaxHitPlugin extends Plugin
|
||||||
|
{
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onItemContainerChanged(final ItemContainerChanged event)
|
||||||
|
{
|
||||||
|
this.updateMaxHitWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onConfigChanged(final ConfigChanged event)
|
||||||
|
{
|
||||||
|
this.updateMaxHitWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onVarbitChanged(VarbitChanged event)
|
||||||
|
{
|
||||||
|
this.updateMaxHitWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMaxHitWidget()
|
||||||
|
{
|
||||||
|
Widget equipmentStats = client.getWidget(WidgetInfo.EQUIPMENT_INVENTORY_ITEMS_CONTAINER);
|
||||||
|
|
||||||
|
ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||||
|
Item[] equipedItems = new Item[14];
|
||||||
|
|
||||||
|
if (equipmentStats != null && !equipmentStats.isHidden())
|
||||||
|
{
|
||||||
|
if (equipmentContainer != null)
|
||||||
|
{
|
||||||
|
equipedItems = equipmentContainer.getItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
MeleeMaxHitCalculator meleeMaxHitCalculator = new MeleeMaxHitCalculator(this.client, equipedItems);
|
||||||
|
RangeMaxHitCalculator rangeMaxHitCalculator = new RangeMaxHitCalculator(this.client, equipedItems);
|
||||||
|
MagicMaxHitCalculator magicMaxHitCalculator = new MagicMaxHitCalculator(this.client, equipedItems);
|
||||||
|
|
||||||
|
MaxHit maxHit = new MaxHit(meleeMaxHitCalculator.getMaxHit(), rangeMaxHitCalculator.getMaxHit(), magicMaxHitCalculator.getMaxHit());
|
||||||
|
this.setWidgetMaxHit(maxHit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setWidgetMaxHit(MaxHit maxhit)
|
||||||
|
{
|
||||||
|
Widget equipYourCharacter = client.getWidget(WidgetInfo.EQUIP_YOUR_CHARACTER);
|
||||||
|
String maxHitText = "Melee Max Hit: " + maxhit.getMaxMeleeHit();
|
||||||
|
maxHitText += "<br>Range Max Hit: " + maxhit.getMaxRangeHit();
|
||||||
|
maxHitText += "<br>Magic Max Hit: " + maxhit.getMaxMagicHit();
|
||||||
|
|
||||||
|
|
||||||
|
equipYourCharacter.setText(maxHitText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MaxHit
|
||||||
|
{
|
||||||
|
private final double maxMeleeHit;
|
||||||
|
private final double maxRangeHit;
|
||||||
|
private final double maxMagicHit;
|
||||||
|
|
||||||
|
MaxHit(double maxMeleeHit, double maxRangeHit, double maxMagicHit)
|
||||||
|
{
|
||||||
|
this.maxMeleeHit = maxMeleeHit;
|
||||||
|
this.maxRangeHit = maxRangeHit;
|
||||||
|
this.maxMagicHit = maxMagicHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxMeleeHit()
|
||||||
|
{
|
||||||
|
return maxMeleeHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxRangeHit()
|
||||||
|
{
|
||||||
|
return maxRangeHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxMagicHit()
|
||||||
|
{
|
||||||
|
return maxMagicHit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.attackstyle;
|
||||||
|
|
||||||
|
public enum AttackStyle
|
||||||
|
{
|
||||||
|
ACCURATE(0),
|
||||||
|
AGGRESSIVE(3),
|
||||||
|
DEFENSIVE(0),
|
||||||
|
CONTROLLED(1),
|
||||||
|
ACCURATERANGING(3),
|
||||||
|
RANGING(0),
|
||||||
|
LONGRANGE(0),
|
||||||
|
CASTING(0),
|
||||||
|
DEFENSIVE_CASTING(0),
|
||||||
|
OTHER(0);
|
||||||
|
|
||||||
|
private final int maxHitBonus;
|
||||||
|
|
||||||
|
AttackStyle(int maxHitBonus)
|
||||||
|
{
|
||||||
|
this.maxHitBonus = maxHitBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxHitBonus()
|
||||||
|
{
|
||||||
|
return this.maxHitBonus;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.attackstyle;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.runelite.client.plugins.maxhit.attackstyle.AttackStyle.*;
|
||||||
|
|
||||||
|
public enum WeaponType
|
||||||
|
{
|
||||||
|
TYPE_0(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
|
||||||
|
TYPE_1(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
|
||||||
|
TYPE_2(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
|
||||||
|
TYPE_3(ACCURATERANGING, RANGING, null, LONGRANGE),
|
||||||
|
TYPE_4(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
|
||||||
|
TYPE_5(ACCURATERANGING, RANGING, null, LONGRANGE),
|
||||||
|
TYPE_6(AGGRESSIVE, RANGING, DEFENSIVE_CASTING, null),
|
||||||
|
TYPE_7(ACCURATERANGING, 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(ACCURATERANGING, 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 static final Map<Integer, WeaponType> weaponTypes = new HashMap<>();
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for (WeaponType weaponType : values())
|
||||||
|
{
|
||||||
|
weaponTypes.put(weaponType.ordinal(), weaponType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final AttackStyle[] attackStyles;
|
||||||
|
|
||||||
|
WeaponType(AttackStyle... attackStyles)
|
||||||
|
{
|
||||||
|
this.attackStyles = attackStyles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WeaponType getWeaponType(int id)
|
||||||
|
{
|
||||||
|
return weaponTypes.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttackStyle[] getAttackStyles()
|
||||||
|
{
|
||||||
|
return attackStyles;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.EquipmentBonusConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig;
|
||||||
|
|
||||||
|
public class MagicMaxHitCalculator extends MaxHitCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
public MagicMaxHitCalculator(Client client, Item[] equipedItems)
|
||||||
|
{
|
||||||
|
super(client, CombatMethod.MAGIC, equipedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSkillStrengthText(String equipmentText)
|
||||||
|
{
|
||||||
|
return equipmentText.replace("Magic damage: ", "").replace(".", "").replace("%", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Widget equipmentSkillPower()
|
||||||
|
{
|
||||||
|
return this.client.getWidget(WidgetInfo.EQUIPMENT_MAGIC_DAMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCurrentSkillPower()
|
||||||
|
{
|
||||||
|
return this.client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Damage formula based on:
|
||||||
|
* http://services.runescape.com/m=forum/forums.ws?317,318,712,65587452
|
||||||
|
* Section 4.
|
||||||
|
* */
|
||||||
|
@Override
|
||||||
|
public double calculate()
|
||||||
|
{
|
||||||
|
int spellBaseDamage = this.baseDamage;
|
||||||
|
|
||||||
|
if (spellBaseDamage == 0)
|
||||||
|
{
|
||||||
|
int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL);
|
||||||
|
if (autoCastSpellId == 0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellBaseDamageConfig autoCastSpell = SpellBaseDamageConfig.findSpellById(autoCastSpellId);
|
||||||
|
spellBaseDamage = autoCastSpell.getBaseDamage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// a.Find the base maximum damage a spell can deal.
|
||||||
|
// See CustomFormulaConfig for spells based on magic lvl
|
||||||
|
double maxHit = spellBaseDamage;
|
||||||
|
|
||||||
|
// b. Increase the base damage (Chaos Gauntlets)
|
||||||
|
maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SPECIAL);
|
||||||
|
|
||||||
|
// c. The following bonuses stack by adding up. (List of bonus items)
|
||||||
|
maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.EQUIPMENT);
|
||||||
|
|
||||||
|
// d. Round down to the nearest integer.
|
||||||
|
maxHit = Math.floor(maxHit);
|
||||||
|
|
||||||
|
// e. On a slayer task, multiply by 1.15 (imbued)
|
||||||
|
maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SLAYER);
|
||||||
|
|
||||||
|
// f. Round down to the nearest integer.
|
||||||
|
maxHit = Math.floor(maxHit);
|
||||||
|
|
||||||
|
// g. If a fire spell is used, multiply by 1.5 (Tome of fire)
|
||||||
|
maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.MAGIC_SPECIAL);
|
||||||
|
|
||||||
|
// h. Round down to the nearest integer.
|
||||||
|
maxHit = Math.floor(maxHit);
|
||||||
|
|
||||||
|
// i, j. Castle Wars will not be included
|
||||||
|
return maxHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.VarPlayer;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.client.plugins.maxhit.attackstyle.AttackStyle;
|
||||||
|
import net.runelite.client.plugins.maxhit.attackstyle.WeaponType;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.CustomFormulaConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.EquipmentBonusConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.PrayerBonusConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentHelper;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
public abstract class MaxHitCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
final Client client;
|
||||||
|
private final CombatMethod combatMethod;
|
||||||
|
private final Item[] equipedItems;
|
||||||
|
int baseDamage = 0;
|
||||||
|
|
||||||
|
MaxHitCalculator(Client client, CombatMethod combatMethod, Item[] equipedItems)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.combatMethod = combatMethod;
|
||||||
|
this.equipedItems = equipedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String getSkillStrengthText(String equipmentText);
|
||||||
|
|
||||||
|
abstract Widget equipmentSkillPower();
|
||||||
|
|
||||||
|
public abstract double getCurrentSkillPower();
|
||||||
|
|
||||||
|
AttackStyle getAttackStyle()
|
||||||
|
{
|
||||||
|
int equippedWeaponTypeId = client.getVar(Varbits.EQUIPPED_WEAPON_TYPE);
|
||||||
|
int attackStyleId = client.getVar(VarPlayer.ATTACK_STYLE);
|
||||||
|
|
||||||
|
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponTypeId).getAttackStyles();
|
||||||
|
|
||||||
|
if (attackStyleId < attackStyles.length)
|
||||||
|
{
|
||||||
|
AttackStyle attackStyle = attackStyles[attackStyleId];
|
||||||
|
if (attackStyle != null)
|
||||||
|
{
|
||||||
|
return attackStyle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AttackStyle.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getPrayerBonus()
|
||||||
|
{
|
||||||
|
double bonus = 1;
|
||||||
|
for (PrayerBonusConfig prayerBonus : PrayerBonusConfig.values())
|
||||||
|
{
|
||||||
|
boolean prayerActive = client.getVar(prayerBonus.getPrayerVarbit()) == 1;
|
||||||
|
boolean sameCombatMethod = prayerBonus.getCombatMethod() == this.combatMethod;
|
||||||
|
if (prayerActive && sameCombatMethod)
|
||||||
|
{
|
||||||
|
bonus += prayerBonus.getStrengthBonus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
double applyEquipmentBonus(double maxhit, EquipmentBonusConfig.BonusType bonusType)
|
||||||
|
{
|
||||||
|
double bonus = 1;
|
||||||
|
ArrayList<Double> addList = new ArrayList<>();
|
||||||
|
|
||||||
|
ArrayList<EquipmentBonusConfig> equipmentBonuses = EquipmentBonusConfig.getBonusByType(bonusType);
|
||||||
|
|
||||||
|
for (EquipmentBonusConfig equipmentBonus : equipmentBonuses)
|
||||||
|
{
|
||||||
|
EquipmentItemset itemSet = equipmentBonus.getItemset();
|
||||||
|
boolean wearsSet = EquipmentHelper.wearsItemSet(this.equipedItems, itemSet);
|
||||||
|
if (wearsSet && equipmentBonus.meetsRequirements(this.client))
|
||||||
|
{
|
||||||
|
if (equipmentBonus.getOperation() == EquipmentBonusConfig.Operation.MULTIPLY)
|
||||||
|
{
|
||||||
|
bonus += equipmentBonus.getBonus(this.combatMethod);
|
||||||
|
}
|
||||||
|
else if (equipmentBonus.getOperation() == EquipmentBonusConfig.Operation.ADD)
|
||||||
|
{
|
||||||
|
addList.add(equipmentBonus.getBonus(this.combatMethod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maxhit *= bonus;
|
||||||
|
|
||||||
|
maxhit = maxhit + addList.stream().reduce(0.0, Double::sum);
|
||||||
|
|
||||||
|
return maxhit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxHit()
|
||||||
|
{
|
||||||
|
BiFunction<Client, MaxHitCalculator, Double> customFormula = this.getCustomFormula();
|
||||||
|
if (customFormula != null)
|
||||||
|
{
|
||||||
|
return customFormula.apply(this.client, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.calculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BiFunction<Client, MaxHitCalculator, Double> getCustomFormula()
|
||||||
|
{
|
||||||
|
for (CustomFormulaConfig customFormula : CustomFormulaConfig.values())
|
||||||
|
{
|
||||||
|
if (this.combatMethod != customFormula.getRequiredCombatMethod())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean meetsRequirements = customFormula.getRequirements().stream().allMatch(requirement -> requirement.meetsRequirements(this.client));
|
||||||
|
|
||||||
|
if (meetsRequirements)
|
||||||
|
{
|
||||||
|
return customFormula.getCustomFormula();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract double calculate();
|
||||||
|
|
||||||
|
public void setBaseDamage(int baseDamage)
|
||||||
|
{
|
||||||
|
this.baseDamage = baseDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getSkillStrength()
|
||||||
|
{
|
||||||
|
return Double.parseDouble(this.getSkillStrengthText(this.equipmentSkillPower().getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CombatMethod
|
||||||
|
{
|
||||||
|
MELEE,
|
||||||
|
RANGE,
|
||||||
|
MAGIC
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.plugins.maxhit.attackstyle.AttackStyle;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.EquipmentBonusConfig;
|
||||||
|
|
||||||
|
public class MeleeMaxHitCalculator extends MaxHitCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
public MeleeMaxHitCalculator(Client client, Item[] equipedItems)
|
||||||
|
{
|
||||||
|
super(client, CombatMethod.MELEE, equipedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
MeleeMaxHitCalculator(Client client, CombatMethod combatMethod, Item[] equipedItems)
|
||||||
|
{
|
||||||
|
super(client, combatMethod, equipedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSkillStrengthText(String equipmentText)
|
||||||
|
{
|
||||||
|
return equipmentText.replace("Melee strength: ", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Widget equipmentSkillPower()
|
||||||
|
{
|
||||||
|
return this.client.getWidget(WidgetInfo.EQUIPMENT_MELEE_STRENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCurrentSkillPower()
|
||||||
|
{
|
||||||
|
return this.client.getBoostedSkillLevel(Skill.STRENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getEffectiveLevel()
|
||||||
|
{
|
||||||
|
// a. Take the visible strength or ranged level from the skills interface.
|
||||||
|
double skillPower = this.getCurrentSkillPower();
|
||||||
|
|
||||||
|
// b. Multiply the level by the prayer adjustment
|
||||||
|
double effectiveLevel = skillPower * this.getPrayerBonus();
|
||||||
|
|
||||||
|
// c. Round down to the nearest integer.
|
||||||
|
effectiveLevel = Math.floor(effectiveLevel);
|
||||||
|
|
||||||
|
// d. Add the stance bonus from the combat options interface.
|
||||||
|
// Melee:
|
||||||
|
// • Aggressive: +3
|
||||||
|
// • Controlled: +1
|
||||||
|
// Ranged:
|
||||||
|
// * Accurate: +3
|
||||||
|
AttackStyle attackStyle = this.getAttackStyle();
|
||||||
|
effectiveLevel += attackStyle.getMaxHitBonus();
|
||||||
|
|
||||||
|
// e. Add up +8.
|
||||||
|
effectiveLevel += 8;
|
||||||
|
|
||||||
|
// f. Multiply by the void bonus:
|
||||||
|
// • Void melee: multiply by 1.10. Round down.
|
||||||
|
// • Void ranged: multiply by 1.10. Round down.
|
||||||
|
// • Elite void ranged: multiply by 1.125. Round down.
|
||||||
|
effectiveLevel = this.applyEquipmentBonus(effectiveLevel, EquipmentBonusConfig.BonusType.VOID_KNIGHT);
|
||||||
|
|
||||||
|
// g. This is the effective (ranged) strength level. Let this equal 'A' in the formula in
|
||||||
|
return effectiveLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.3 Take the melee or ranged strength bonus from the equipment stats interface and let this equal 'B' in the formula in 3.1.
|
||||||
|
private double getEquipmentBonus()
|
||||||
|
{
|
||||||
|
return this.getSkillStrength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Damage formula based on:
|
||||||
|
* http://services.runescape.com/m=forum/forums.ws?317,318,712,65587452
|
||||||
|
* Section 3.1
|
||||||
|
* */
|
||||||
|
@Override
|
||||||
|
public double calculate()
|
||||||
|
{
|
||||||
|
|
||||||
|
// a. Max hit = 0.5 + A * (B+64) /640 (A is effective level, B is Equipment bonus)
|
||||||
|
double maxHit = 0.5 + this.getEffectiveLevel() * (this.getEquipmentBonus() + 64) / 640;
|
||||||
|
|
||||||
|
// b. Round down the max hit to the nearest integer.
|
||||||
|
maxHit = Math.floor(maxHit);
|
||||||
|
|
||||||
|
// 3.4 Special attacks (not actually taking weapon special attacks into account)
|
||||||
|
// a. Multiply by the bonus of one of the following items (slayer)
|
||||||
|
maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SLAYER);
|
||||||
|
|
||||||
|
// b. Round down the max hit to the nearest integer.
|
||||||
|
maxHit = Math.floor(maxHit);
|
||||||
|
|
||||||
|
// c. Multiply by the bonus of one of the following items
|
||||||
|
maxHit = this.applyEquipmentBonus(maxHit, EquipmentBonusConfig.BonusType.SPECIAL);
|
||||||
|
|
||||||
|
// d. Round down to the nearest integer.
|
||||||
|
maxHit = Math.floor(maxHit);
|
||||||
|
|
||||||
|
return maxHit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
|
||||||
|
public class RangeMaxHitCalculator extends MeleeMaxHitCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
public RangeMaxHitCalculator(Client client, Item[] equipedItems)
|
||||||
|
{
|
||||||
|
super(client, CombatMethod.RANGE, equipedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSkillStrengthText(String equipmentText)
|
||||||
|
{
|
||||||
|
return equipmentText.replace("Ranged strength: ", "").replace(".", "").replace("%", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Widget equipmentSkillPower()
|
||||||
|
{
|
||||||
|
return this.client.getWidget(WidgetInfo.EQUIPMENT_RANGED_STRENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCurrentSkillPower()
|
||||||
|
{
|
||||||
|
return this.client.getBoostedSkillLevel(Skill.RANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.config;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentSlotItem;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.EquipmentItemRequirement;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.EquipmentItemSetRequirement;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.Requirement;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.SpellRequirement;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
public enum CustomFormulaConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
MAGIC_DART(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Arrays.asList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.SLAYERS_STAFF,
|
||||||
|
ItemID.SLAYERS_STAFF_E
|
||||||
|
)))),
|
||||||
|
new SpellRequirement(SpellBaseDamageConfig.MAGIC_DART)
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
return Math.floor((magicLevel / 10.0) + 10.0);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
TRIDENT_OF_SEAS(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Collections.singletonList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.TRIDENT_OF_THE_SEAS_FULL,
|
||||||
|
ItemID.TRIDENT_OF_THE_SEAS,
|
||||||
|
ItemID.TRIDENT_OF_THE_SEAS_E
|
||||||
|
))))
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
|
||||||
|
int baseDamage = (int) Math.floor(magicLevel / 3.0) - 5;
|
||||||
|
calculator.setBaseDamage(baseDamage);
|
||||||
|
|
||||||
|
return calculator.calculate();
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
TRIDENT_OF_SWAMP(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Collections.singletonList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.TRIDENT_OF_THE_SWAMP,
|
||||||
|
ItemID.TRIDENT_OF_THE_SWAMP_E
|
||||||
|
))))
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
|
||||||
|
int baseDamage = (int) Math.floor(magicLevel / 3.0) - 2;
|
||||||
|
calculator.setBaseDamage(baseDamage);
|
||||||
|
|
||||||
|
return calculator.calculate();
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
SWAMP_LIZARD(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Collections.singletonList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.SWAMP_LIZARD
|
||||||
|
))))
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
return Math.floor(0.5 + magicLevel * (64.0 + 56.0) / 640.0);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
ORANGE_SALAMANDER(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Collections.singletonList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ORANGE_SALAMANDER
|
||||||
|
))))
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
return Math.floor(0.5 + magicLevel * (64.0 + 59.0) / 640.0);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
RED_SALAMANDER(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Collections.singletonList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.RED_SALAMANDER
|
||||||
|
))))
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
return Math.floor(0.5 + magicLevel * (64.0 + 77.0) / 640.0);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
BLACK_SALAMANDER(
|
||||||
|
MaxHitCalculator.CombatMethod.MAGIC,
|
||||||
|
new ArrayList<>(Collections.singletonList(
|
||||||
|
new EquipmentItemRequirement(new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.BLACK_SALAMANDER
|
||||||
|
))))
|
||||||
|
)),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int magicLevel = client.getBoostedSkillLevel(Skill.MAGIC);
|
||||||
|
return Math.floor(0.5 + magicLevel * (64.0 + 92.0) / 640.0);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
DHAROK(
|
||||||
|
MaxHitCalculator.CombatMethod.MELEE,
|
||||||
|
new ArrayList<>(Collections.singletonList(new EquipmentItemSetRequirement(new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.DHAROKS_HELM,
|
||||||
|
ItemID.DHAROKS_HELM_100,
|
||||||
|
ItemID.DHAROKS_HELM_75,
|
||||||
|
ItemID.DHAROKS_HELM_50,
|
||||||
|
ItemID.DHAROKS_HELM_25,
|
||||||
|
ItemID.DHAROKS_HELM_0
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.DHAROKS_PLATEBODY,
|
||||||
|
ItemID.DHAROKS_PLATEBODY_100,
|
||||||
|
ItemID.DHAROKS_PLATEBODY_75,
|
||||||
|
ItemID.DHAROKS_PLATEBODY_50,
|
||||||
|
ItemID.DHAROKS_PLATEBODY_25,
|
||||||
|
ItemID.DHAROKS_PLATEBODY_0
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.DHAROKS_PLATELEGS,
|
||||||
|
ItemID.DHAROKS_PLATELEGS_100,
|
||||||
|
ItemID.DHAROKS_PLATELEGS_75,
|
||||||
|
ItemID.DHAROKS_PLATELEGS_50,
|
||||||
|
ItemID.DHAROKS_PLATELEGS_25,
|
||||||
|
ItemID.DHAROKS_PLATELEGS_0
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.DHAROKS_GREATAXE,
|
||||||
|
ItemID.DHAROKS_GREATAXE_100,
|
||||||
|
ItemID.DHAROKS_GREATAXE_75,
|
||||||
|
ItemID.DHAROKS_GREATAXE_50,
|
||||||
|
ItemID.DHAROKS_GREATAXE_25,
|
||||||
|
ItemID.DHAROKS_GREATAXE_0
|
||||||
|
)))
|
||||||
|
))))),
|
||||||
|
(client, calculator) ->
|
||||||
|
{
|
||||||
|
int currentHP = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
||||||
|
int maxHP = client.getRealSkillLevel(Skill.HITPOINTS);
|
||||||
|
int lostHP = maxHP - currentHP;
|
||||||
|
|
||||||
|
double initialMaxHit = calculator.calculate();
|
||||||
|
|
||||||
|
double multiplier = (1.0 + ((lostHP / 100.0) * (maxHP / 100.0)));
|
||||||
|
|
||||||
|
return Math.floor(initialMaxHit * multiplier);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
private final MaxHitCalculator.CombatMethod requiredCombatMethod;
|
||||||
|
private final ArrayList<Requirement> requirements;
|
||||||
|
private final BiFunction<Client, MaxHitCalculator, Double> customFormula;
|
||||||
|
|
||||||
|
CustomFormulaConfig(MaxHitCalculator.CombatMethod requiredCombatMethod, ArrayList<Requirement> requirements, BiFunction<Client, MaxHitCalculator, Double> customFormula)
|
||||||
|
{
|
||||||
|
this.requiredCombatMethod = requiredCombatMethod;
|
||||||
|
this.requirements = requirements;
|
||||||
|
this.customFormula = customFormula;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaxHitCalculator.CombatMethod getRequiredCombatMethod()
|
||||||
|
{
|
||||||
|
return requiredCombatMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiFunction<Client, MaxHitCalculator, Double> getCustomFormula()
|
||||||
|
{
|
||||||
|
return customFormula;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Requirement> getRequirements()
|
||||||
|
{
|
||||||
|
return this.requirements;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.config;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentCombatBonus;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentSlotItem;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.AutocastSpellRequirement;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.Requirement;
|
||||||
|
import net.runelite.client.plugins.maxhit.requirements.SpellBookRequirement;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
public enum EquipmentBonusConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Slayer bonus items
|
||||||
|
*/
|
||||||
|
BLACKMASK(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.BLACK_MASK_10,
|
||||||
|
ItemID.BLACK_MASK_9,
|
||||||
|
ItemID.BLACK_MASK_8,
|
||||||
|
ItemID.BLACK_MASK_7,
|
||||||
|
ItemID.BLACK_MASK_6,
|
||||||
|
ItemID.BLACK_MASK_5,
|
||||||
|
ItemID.BLACK_MASK_4,
|
||||||
|
ItemID.BLACK_MASK_3,
|
||||||
|
ItemID.BLACK_MASK_2,
|
||||||
|
ItemID.BLACK_MASK_1,
|
||||||
|
ItemID.BLACK_MASK
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0, 0)),
|
||||||
|
|
||||||
|
SLAYERHELM(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.SLAYER_HELMET,
|
||||||
|
ItemID.BLACK_SLAYER_HELMET,
|
||||||
|
ItemID.GREEN_SLAYER_HELMET,
|
||||||
|
ItemID.RED_SLAYER_HELMET,
|
||||||
|
ItemID.PURPLE_SLAYER_HELMET,
|
||||||
|
ItemID.TURQUOISE_SLAYER_HELMET,
|
||||||
|
ItemID.HYDRA_SLAYER_HELMET
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0, 0)),
|
||||||
|
|
||||||
|
BLACKMASKI(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.BLACK_MASK_10_I,
|
||||||
|
ItemID.BLACK_MASK_9_I,
|
||||||
|
ItemID.BLACK_MASK_8_I,
|
||||||
|
ItemID.BLACK_MASK_7_I,
|
||||||
|
ItemID.BLACK_MASK_6_I,
|
||||||
|
ItemID.BLACK_MASK_5_I,
|
||||||
|
ItemID.BLACK_MASK_4_I,
|
||||||
|
ItemID.BLACK_MASK_3_I,
|
||||||
|
ItemID.BLACK_MASK_2_I,
|
||||||
|
ItemID.BLACK_MASK_1_I,
|
||||||
|
ItemID.BLACK_MASK_I
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0.15, 0.15)),
|
||||||
|
|
||||||
|
SLAYERHELMI(BonusType.SLAYER, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.SLAYER_HELMET_I,
|
||||||
|
ItemID.BLACK_SLAYER_HELMET_I,
|
||||||
|
ItemID.GREEN_SLAYER_HELMET_I,
|
||||||
|
ItemID.RED_SLAYER_HELMET_I,
|
||||||
|
ItemID.PURPLE_SLAYER_HELMET_I,
|
||||||
|
ItemID.TURQUOISE_SLAYER_HELMET_I,
|
||||||
|
ItemID.HYDRA_SLAYER_HELMET_I
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(((7.0 / 6.0) - 1), 0.15, 0.15)),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Void bonus items
|
||||||
|
* */
|
||||||
|
MELEEVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_MELEE_HELM,
|
||||||
|
ItemID.VOID_MELEE_HELM_11676
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_KNIGHT_TOP,
|
||||||
|
ItemID.VOID_KNIGHT_TOP_10611
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_ROBE
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_GLOVES
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0.1, 0, 0)),
|
||||||
|
|
||||||
|
RANGERVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_RANGER_HELM,
|
||||||
|
ItemID.VOID_RANGER_HELM_11675
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_KNIGHT_TOP,
|
||||||
|
ItemID.VOID_KNIGHT_TOP_10611
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_ROBE
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_GLOVES
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0.1, 0)),
|
||||||
|
|
||||||
|
|
||||||
|
ELITEMELEERVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_MELEE_HELM,
|
||||||
|
ItemID.VOID_MELEE_HELM_11676
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ELITE_VOID_TOP
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ELITE_VOID_ROBE
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_GLOVES
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0.125, 0, 0)),
|
||||||
|
|
||||||
|
|
||||||
|
ELITERANGERVOID(BonusType.VOID_KNIGHT, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_RANGER_HELM,
|
||||||
|
ItemID.VOID_RANGER_HELM_11675
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ELITE_VOID_TOP
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ELITE_VOID_ROBE
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_GLOVES
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0.125, 0)),
|
||||||
|
|
||||||
|
ELITEMAGICVOID(BonusType.EQUIPMENT, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.VOID_MAGE_HELM,
|
||||||
|
ItemID.VOID_MAGE_HELM_11674
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ELITE_VOID_TOP
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ELITE_VOID_ROBE
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.VOID_KNIGHT_GLOVES
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.025)),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special Melee Equipment
|
||||||
|
* */
|
||||||
|
OBISIDIAN(BonusType.SPECIAL, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.OBSIDIAN_HELMET
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.OBSIDIAN_PLATEBODY
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.OBSIDIAN_PLATELEGS
|
||||||
|
))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.TOKTZXILAK,
|
||||||
|
ItemID.TOKTZXILEK,
|
||||||
|
ItemID.TZHAARKETEM,
|
||||||
|
ItemID.TZHAARKETOM,
|
||||||
|
ItemID.TOKTZXILAK_20554
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0.1, 0, 0)),
|
||||||
|
|
||||||
|
BERSERKERNECKLACE(BonusType.SPECIAL, new EquipmentItemset(Arrays.asList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.AMULET, new ArrayList<>(Collections.singletonList(ItemID.BERSERKER_NECKLACE))),
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.TOKTZXILAK,
|
||||||
|
ItemID.TOKTZXILEK,
|
||||||
|
ItemID.TZHAARKETEM,
|
||||||
|
ItemID.TZHAARKETOM,
|
||||||
|
ItemID.TOKTZXILAK_20554
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0.2, 0, 0)),
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Magic Equipment
|
||||||
|
*/
|
||||||
|
ANCESTRAL_HAT(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.HEAD, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ANCESTRAL_HAT
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.02)),
|
||||||
|
|
||||||
|
ANCESTRAL_ROBE_TOP(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.BODY, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ANCESTRAL_ROBE_TOP
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.02)),
|
||||||
|
|
||||||
|
ANCESTRAL_ROBE_BOTTOM(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.LEGS, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.ANCESTRAL_ROBE_BOTTOM
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.02)),
|
||||||
|
|
||||||
|
IMBUED_GOD_CAPE(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.CAPE, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.IMBUED_SARADOMIN_MAX_CAPE,
|
||||||
|
ItemID.IMBUED_SARADOMIN_CAPE,
|
||||||
|
ItemID.IMBUED_ZAMORAK_MAX_CAPE,
|
||||||
|
ItemID.IMBUED_ZAMORAK_CAPE,
|
||||||
|
ItemID.IMBUED_GUTHIX_MAX_CAPE,
|
||||||
|
ItemID.IMBUED_GUTHIX_CAPE
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.02)),
|
||||||
|
|
||||||
|
KODAI_WAND(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.KODAI_WAND
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.15)),
|
||||||
|
|
||||||
|
OCCULT_NECKLACE(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.AMULET, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.OCCULT_NECKLACE,
|
||||||
|
ItemID.OCCULT_NECKLACE_OR
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.10)),
|
||||||
|
|
||||||
|
STAFF_OF_THE_DEAD(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.STAFF_OF_THE_DEAD,
|
||||||
|
ItemID.TOXIC_STAFF_OF_THE_DEAD,
|
||||||
|
ItemID.STAFF_OF_LIGHT
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.15)),
|
||||||
|
|
||||||
|
TORMENTED_BRACELET(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.TORMENTED_BRACELET
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.05)),
|
||||||
|
|
||||||
|
SMOKE_STAFF(BonusType.EQUIPMENT, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.WEAPON, new ArrayList<>(Arrays.asList(
|
||||||
|
ItemID.SMOKE_BATTLESTAFF,
|
||||||
|
ItemID.MYSTIC_SMOKE_STAFF
|
||||||
|
)))
|
||||||
|
)), new EquipmentCombatBonus(0, 0, 0.10), Collections.singletonList(new SpellBookRequirement(SpellBaseDamageConfig.SpellBook.NORMAL))),
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special magic bonusses
|
||||||
|
* */
|
||||||
|
|
||||||
|
CHAOS_GAUNTLETS(BonusType.SPECIAL, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.GLOVES, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.CHAOS_GAUNTLETS
|
||||||
|
))))),
|
||||||
|
new EquipmentCombatBonus(0, 0, 3),
|
||||||
|
Collections.singletonList(
|
||||||
|
new AutocastSpellRequirement(new ArrayList<>(Arrays.asList(
|
||||||
|
SpellBaseDamageConfig.AIR_BOLT,
|
||||||
|
SpellBaseDamageConfig.WATER_BOLT,
|
||||||
|
SpellBaseDamageConfig.EARTH_BOLT,
|
||||||
|
SpellBaseDamageConfig.FIRE_BOLT
|
||||||
|
)))
|
||||||
|
),
|
||||||
|
Operation.ADD
|
||||||
|
),
|
||||||
|
|
||||||
|
TOME_OF_FIRE(BonusType.MAGIC_SPECIAL, new EquipmentItemset(Collections.singletonList(
|
||||||
|
new EquipmentSlotItem(EquipmentInventorySlot.SHIELD, new ArrayList<>(Collections.singletonList(
|
||||||
|
ItemID.TOME_OF_FIRE
|
||||||
|
))))),
|
||||||
|
new EquipmentCombatBonus(0, 0, 0.5),
|
||||||
|
Collections.singletonList(
|
||||||
|
new AutocastSpellRequirement(new ArrayList<>(Arrays.asList(
|
||||||
|
SpellBaseDamageConfig.FIRE_BLAST,
|
||||||
|
SpellBaseDamageConfig.FIRE_BOLT,
|
||||||
|
SpellBaseDamageConfig.FIRE_STRIKE,
|
||||||
|
SpellBaseDamageConfig.FIRE_SURGE,
|
||||||
|
SpellBaseDamageConfig.FIRE_WAVE
|
||||||
|
)))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private static final Map<BonusType, ArrayList<EquipmentBonusConfig>> bonusTypes = new HashMap<>();
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for (EquipmentBonusConfig equipmentBonus : values())
|
||||||
|
{
|
||||||
|
BonusType bonusType = equipmentBonus.bonusType;
|
||||||
|
if (!bonusTypes.containsKey(bonusType))
|
||||||
|
{
|
||||||
|
bonusTypes.put(bonusType, new ArrayList<>());
|
||||||
|
}
|
||||||
|
ArrayList<EquipmentBonusConfig> list = bonusTypes.get(bonusType);
|
||||||
|
list.add(equipmentBonus);
|
||||||
|
bonusTypes.put(bonusType, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final EquipmentItemset itemset;
|
||||||
|
private BonusType bonusType;
|
||||||
|
private EquipmentCombatBonus equipmentCombatBonus;
|
||||||
|
private List<Requirement> requirements = new ArrayList<>();
|
||||||
|
private Operation operation = Operation.MULTIPLY;
|
||||||
|
EquipmentBonusConfig(BonusType bonusType, EquipmentItemset itemset, EquipmentCombatBonus equipmentCombatBonus)
|
||||||
|
{
|
||||||
|
this.bonusType = bonusType;
|
||||||
|
this.itemset = itemset;
|
||||||
|
this.equipmentCombatBonus = equipmentCombatBonus;
|
||||||
|
}
|
||||||
|
EquipmentBonusConfig(BonusType bonusType, EquipmentItemset itemset, EquipmentCombatBonus equipmentCombatBonus, List<Requirement> requirements)
|
||||||
|
{
|
||||||
|
this.bonusType = bonusType;
|
||||||
|
this.itemset = itemset;
|
||||||
|
this.equipmentCombatBonus = equipmentCombatBonus;
|
||||||
|
this.requirements = requirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
EquipmentBonusConfig(BonusType bonusType, EquipmentItemset itemset, EquipmentCombatBonus equipmentCombatBonus, List<Requirement> requirements, Operation operation)
|
||||||
|
{
|
||||||
|
this.bonusType = bonusType;
|
||||||
|
this.itemset = itemset;
|
||||||
|
this.equipmentCombatBonus = equipmentCombatBonus;
|
||||||
|
this.requirements = requirements;
|
||||||
|
this.operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList<EquipmentBonusConfig> getBonusByType(BonusType bonusType)
|
||||||
|
{
|
||||||
|
if (!bonusTypes.containsKey(bonusType))
|
||||||
|
{
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return bonusTypes.get(bonusType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EquipmentItemset getItemset()
|
||||||
|
{
|
||||||
|
return itemset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Operation getOperation()
|
||||||
|
{
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBonus(MaxHitCalculator.CombatMethod combatMethod)
|
||||||
|
{
|
||||||
|
return this.equipmentCombatBonus.getCombatBonus(combatMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean meetsRequirements(Client client)
|
||||||
|
{
|
||||||
|
return requirements.stream().allMatch(requirement -> requirement.meetsRequirements(client));
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum BonusType
|
||||||
|
{
|
||||||
|
EQUIPMENT,
|
||||||
|
SLAYER,
|
||||||
|
VOID_KNIGHT,
|
||||||
|
SPECIAL,
|
||||||
|
MAGIC_SPECIAL
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Operation
|
||||||
|
{
|
||||||
|
ADD,
|
||||||
|
MULTIPLY
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.config;
|
||||||
|
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator;
|
||||||
|
|
||||||
|
public enum PrayerBonusConfig
|
||||||
|
{
|
||||||
|
BURST_OF_STRENGTH(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_BURST_OF_STRENGTH, 0.05),
|
||||||
|
SUPERHUMAN_STRENGTH(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_SUPERHUMAN_STRENGTH, 0.1),
|
||||||
|
ULTIMATE_STRENGTH(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_ULTIMATE_STRENGTH, 0.15),
|
||||||
|
CHIVALRY(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_CHIVALRY, 0.18),
|
||||||
|
PIETY(MaxHitCalculator.CombatMethod.MELEE, Varbits.PRAYER_PIETY, 0.23),
|
||||||
|
|
||||||
|
SHARP_EYE(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_SHARP_EYE, 0.05),
|
||||||
|
HAWK_EYE(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_HAWK_EYE, 0.1),
|
||||||
|
EAGLE_EYE(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_EAGLE_EYE, 0.15),
|
||||||
|
RIGOUR(MaxHitCalculator.CombatMethod.RANGE, Varbits.PRAYER_RIGOUR, 0.23);
|
||||||
|
|
||||||
|
private final MaxHitCalculator.CombatMethod combatMethod;
|
||||||
|
private final Varbits prayerVarbit;
|
||||||
|
private final double strengthBonus;
|
||||||
|
|
||||||
|
PrayerBonusConfig(MaxHitCalculator.CombatMethod combatMethod, Varbits prayerVarbit, double strengthBonus)
|
||||||
|
{
|
||||||
|
this.combatMethod = combatMethod;
|
||||||
|
this.prayerVarbit = prayerVarbit;
|
||||||
|
this.strengthBonus = strengthBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaxHitCalculator.CombatMethod getCombatMethod()
|
||||||
|
{
|
||||||
|
return combatMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Varbits getPrayerVarbit()
|
||||||
|
{
|
||||||
|
return prayerVarbit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getStrengthBonus()
|
||||||
|
{
|
||||||
|
return strengthBonus;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.config;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public enum SpellBaseDamageConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal Spellbook
|
||||||
|
* */
|
||||||
|
AIR_STRIKE(SpellBook.NORMAL, 1, 2),
|
||||||
|
WATER_STRIKE(SpellBook.NORMAL, 2, 4),
|
||||||
|
EARTH_STRIKE(SpellBook.NORMAL, 3, 6),
|
||||||
|
FIRE_STRIKE(SpellBook.NORMAL, 4, 8),
|
||||||
|
|
||||||
|
AIR_BOLT(SpellBook.NORMAL, 5, 9),
|
||||||
|
WATER_BOLT(SpellBook.NORMAL, 6, 10),
|
||||||
|
EARTH_BOLT(SpellBook.NORMAL, 7, 11),
|
||||||
|
FIRE_BOLT(SpellBook.NORMAL, 8, 12),
|
||||||
|
|
||||||
|
WIND_BLAST(SpellBook.NORMAL, 9, 13),
|
||||||
|
WATER_BLAST(SpellBook.NORMAL, 10, 14),
|
||||||
|
EARTH_BLAST(SpellBook.NORMAL, 11, 15),
|
||||||
|
FIRE_BLAST(SpellBook.NORMAL, 12, 16),
|
||||||
|
|
||||||
|
AIR_WAVE(SpellBook.NORMAL, 13, 17),
|
||||||
|
WATER_WAVE(SpellBook.NORMAL, 14, 18),
|
||||||
|
EARTH_WAVE(SpellBook.NORMAL, 15, 19),
|
||||||
|
FIRE_WAVE(SpellBook.NORMAL, 16, 20),
|
||||||
|
|
||||||
|
AIR_SURGE(SpellBook.NORMAL, 48, 21),
|
||||||
|
WATER_SURGE(SpellBook.NORMAL, 49, 22),
|
||||||
|
EARTH_SURGE(SpellBook.NORMAL, 50, 23),
|
||||||
|
FIRE_SURGE(SpellBook.NORMAL, 51, 24),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ancient Spellbook
|
||||||
|
* */
|
||||||
|
SMOKE_RUSH(SpellBook.ANCIENT, 31, 14),
|
||||||
|
SHADOW_RUSH(SpellBook.ANCIENT, 32, 15),
|
||||||
|
BLOOD_RUSH(SpellBook.ANCIENT, 33, 16),
|
||||||
|
ICE_RUSH(SpellBook.ANCIENT, 34, 17),
|
||||||
|
|
||||||
|
SMOKE_BURST(SpellBook.ANCIENT, 35, 18),
|
||||||
|
SHADOW_BURST(SpellBook.ANCIENT, 36, 19),
|
||||||
|
BLOOD_BURST(SpellBook.ANCIENT, 37, 21),
|
||||||
|
ICE_BURST(SpellBook.ANCIENT, 38, 22),
|
||||||
|
|
||||||
|
SMOKE_BLITZ(SpellBook.ANCIENT, 39, 23),
|
||||||
|
SHADOW_BLITZ(SpellBook.ANCIENT, 40, 24),
|
||||||
|
BLOOD_BLITZ(SpellBook.ANCIENT, 41, 25),
|
||||||
|
ICE_BLITZ(SpellBook.ANCIENT, 42, 26),
|
||||||
|
|
||||||
|
SMOKE_BARRAGE(SpellBook.ANCIENT, 43, 27),
|
||||||
|
SHADOW_BARRAGE(SpellBook.ANCIENT, 44, 28),
|
||||||
|
BLOOD_BARRAGE(SpellBook.ANCIENT, 55, 29),
|
||||||
|
ICE_BARRAGE(SpellBook.ANCIENT, 46, 30),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Other spells
|
||||||
|
* */
|
||||||
|
CRUMBLE_UNDEAD(SpellBook.OTHER, 17, 15),
|
||||||
|
IBAN_BLAST(SpellBook.OTHER, 47, 25),
|
||||||
|
FLAMES_OF_ZAMAROK(SpellBook.OTHER, 20, 20),
|
||||||
|
CLAWS_OF_GUTHIX(SpellBook.OTHER, 19, 20),
|
||||||
|
SARADOMIN_STRIKE(SpellBook.OTHER, 52, 20),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Custom Formula spells
|
||||||
|
* */
|
||||||
|
MAGIC_DART(SpellBook.OTHER, 18, 0);
|
||||||
|
|
||||||
|
private final SpellBook spellBook;
|
||||||
|
private final int spellID;
|
||||||
|
private final int baseDamage;
|
||||||
|
|
||||||
|
SpellBaseDamageConfig(SpellBook spellBook, int spellID, int baseDamage)
|
||||||
|
{
|
||||||
|
this.spellBook = spellBook;
|
||||||
|
this.spellID = spellID;
|
||||||
|
this.baseDamage = baseDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpellBaseDamageConfig findSpellById(int spellID)
|
||||||
|
{
|
||||||
|
return Arrays.stream(values()).filter(spell -> spell.getSpellID() == spellID).findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpellID()
|
||||||
|
{
|
||||||
|
return spellID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBaseDamage()
|
||||||
|
{
|
||||||
|
return baseDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpellBook getSpellBook()
|
||||||
|
{
|
||||||
|
return spellBook;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SpellBook
|
||||||
|
{
|
||||||
|
NORMAL,
|
||||||
|
ANCIENT,
|
||||||
|
OTHER
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.equipment;
|
||||||
|
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MaxHitCalculator;
|
||||||
|
|
||||||
|
public class EquipmentCombatBonus
|
||||||
|
{
|
||||||
|
|
||||||
|
private final double meleeBonus;
|
||||||
|
private final double rangeBonus;
|
||||||
|
private final double magicBonus;
|
||||||
|
|
||||||
|
public EquipmentCombatBonus(double meleeBonus, double rangeBonus, double magicBonus)
|
||||||
|
{
|
||||||
|
this.meleeBonus = meleeBonus;
|
||||||
|
this.rangeBonus = rangeBonus;
|
||||||
|
this.magicBonus = magicBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCombatBonus(MaxHitCalculator.CombatMethod combatMethod)
|
||||||
|
{
|
||||||
|
switch (combatMethod)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case MELEE:
|
||||||
|
return this.meleeBonus;
|
||||||
|
case RANGE:
|
||||||
|
return this.rangeBonus;
|
||||||
|
case MAGIC:
|
||||||
|
return this.magicBonus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.equipment;
|
||||||
|
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
|
||||||
|
public class EquipmentHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
public static boolean wearsItemSet(Item[] equipedItems, EquipmentItemset itemSet)
|
||||||
|
{
|
||||||
|
return itemSet.getItems().stream().allMatch(item -> wearsItem(equipedItems, item));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean wearsItem(Item[] equipedItems, EquipmentInventorySlot slot, int itemId)
|
||||||
|
{
|
||||||
|
Item item = equipedItems[slot.getSlotIdx()];
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return item.getId() == itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean wearsItem(Item[] equipedItems, EquipmentSlotItem equipmentSlotItem)
|
||||||
|
{
|
||||||
|
return equipmentSlotItem.getItems().stream().anyMatch(itemId ->
|
||||||
|
wearsItem(equipedItems, equipmentSlotItem.getEquipmentSlot(), itemId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.equipment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EquipmentItemset
|
||||||
|
{
|
||||||
|
private final List<EquipmentSlotItem> items;
|
||||||
|
|
||||||
|
public EquipmentItemset(List<EquipmentSlotItem> items)
|
||||||
|
{
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EquipmentSlotItem> getItems()
|
||||||
|
{
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.equipment;
|
||||||
|
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class EquipmentSlotItem
|
||||||
|
{
|
||||||
|
private final EquipmentInventorySlot equipmentSlot;
|
||||||
|
private final ArrayList<Integer> itemIds;
|
||||||
|
|
||||||
|
public EquipmentSlotItem(EquipmentInventorySlot equipmentSlot, ArrayList<Integer> itemIds)
|
||||||
|
{
|
||||||
|
this.equipmentSlot = equipmentSlot;
|
||||||
|
this.itemIds = itemIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Integer> getItems()
|
||||||
|
{
|
||||||
|
return this.itemIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EquipmentInventorySlot getEquipmentSlot()
|
||||||
|
{
|
||||||
|
return this.equipmentSlot;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.requirements;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class AutocastSpellRequirement implements Requirement
|
||||||
|
{
|
||||||
|
|
||||||
|
private final ArrayList<SpellBaseDamageConfig> autocastSpells;
|
||||||
|
|
||||||
|
public AutocastSpellRequirement(ArrayList<SpellBaseDamageConfig> autocastSpells)
|
||||||
|
{
|
||||||
|
this.autocastSpells = autocastSpells;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean meetsRequirements(Client client)
|
||||||
|
{
|
||||||
|
int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL);
|
||||||
|
|
||||||
|
if (autoCastSpellId == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.autocastSpells.stream().anyMatch(spell -> spell.getSpellID() == autoCastSpellId);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.requirements;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentHelper;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentSlotItem;
|
||||||
|
|
||||||
|
public class EquipmentItemRequirement implements Requirement
|
||||||
|
{
|
||||||
|
private final EquipmentSlotItem item;
|
||||||
|
|
||||||
|
public EquipmentItemRequirement(EquipmentSlotItem item)
|
||||||
|
{
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean meetsRequirements(Client client)
|
||||||
|
{
|
||||||
|
ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||||
|
if (equipmentContainer == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Item[] equipedItems = equipmentContainer.getItems();
|
||||||
|
return EquipmentHelper.wearsItem(equipedItems, this.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.requirements;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentHelper;
|
||||||
|
import net.runelite.client.plugins.maxhit.equipment.EquipmentItemset;
|
||||||
|
|
||||||
|
public class EquipmentItemSetRequirement implements Requirement
|
||||||
|
{
|
||||||
|
private final EquipmentItemset itemSet;
|
||||||
|
|
||||||
|
public EquipmentItemSetRequirement(EquipmentItemset itemSet)
|
||||||
|
{
|
||||||
|
this.itemSet = itemSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean meetsRequirements(Client client)
|
||||||
|
{
|
||||||
|
ItemContainer equipmentContainer = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||||
|
if (equipmentContainer == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Item[] equipedItems = equipmentContainer.getItems();
|
||||||
|
|
||||||
|
return EquipmentHelper.wearsItemSet(equipedItems, this.itemSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.requirements;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
|
||||||
|
public interface Requirement
|
||||||
|
{
|
||||||
|
boolean meetsRequirements(Client client);
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.requirements;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig;
|
||||||
|
|
||||||
|
public class SpellBookRequirement implements Requirement
|
||||||
|
{
|
||||||
|
private final SpellBaseDamageConfig.SpellBook spellBook;
|
||||||
|
|
||||||
|
public SpellBookRequirement(SpellBaseDamageConfig.SpellBook spellBook)
|
||||||
|
{
|
||||||
|
this.spellBook = spellBook;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean meetsRequirements(Client client)
|
||||||
|
{
|
||||||
|
int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL);
|
||||||
|
if (autoCastSpellId == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellBaseDamageConfig autoCastSpell = SpellBaseDamageConfig.findSpellById(autoCastSpellId);
|
||||||
|
return autoCastSpell.getSpellBook() == this.spellBook;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.requirements;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.client.plugins.maxhit.config.SpellBaseDamageConfig;
|
||||||
|
|
||||||
|
public class SpellRequirement implements Requirement
|
||||||
|
{
|
||||||
|
private final SpellBaseDamageConfig spellBaseDamageConfig;
|
||||||
|
|
||||||
|
public SpellRequirement(SpellBaseDamageConfig spellBaseDamageConfig)
|
||||||
|
{
|
||||||
|
this.spellBaseDamageConfig = spellBaseDamageConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean meetsRequirements(Client client)
|
||||||
|
{
|
||||||
|
int autoCastSpellId = client.getVar(Varbits.AUTO_CAST_SPELL);
|
||||||
|
if (autoCastSpellId == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoCastSpellId == this.spellBaseDamageConfig.getSpellID();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -282,4 +282,14 @@ public interface MenuEntrySwapperConfig extends Config
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "swapRogueschests",
|
||||||
|
name = "Rogueschests",
|
||||||
|
description = "Swap Rogueschests from open to Search for traps"
|
||||||
|
)
|
||||||
|
default boolean swapRogueschests()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -544,6 +544,10 @@ public class MenuEntrySwapperPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
swap("pick-lots", option, target, true);
|
swap("pick-lots", option, target, true);
|
||||||
}
|
}
|
||||||
|
else if (config.swapRogueschests() && target.contains("chest"))
|
||||||
|
{
|
||||||
|
swap("search for traps", option, target, true);
|
||||||
|
}
|
||||||
else if (config.shiftClickCustomization() && shiftModifier && !option.equals("use"))
|
else if (config.shiftClickCustomization() && shiftModifier && !option.equals("use"))
|
||||||
{
|
{
|
||||||
Integer customOption = getSwapConfig(eventId);
|
Integer customOption = getSwapConfig(eventId);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,97 +25,220 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.pestcontrol;
|
package net.runelite.client.plugins.pestcontrol;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.BLUE;
|
import net.runelite.api.Client;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.PURPLE;
|
import net.runelite.api.NPC;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.RED;
|
import net.runelite.api.coords.WorldPoint;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.YELLOW;
|
import net.runelite.api.events.GameTick;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class Game
|
public class Game
|
||||||
{
|
{
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
private PestControlPlugin plugin;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Portal bluePortal = new Portal(PortalColor.BLUE, WidgetPortal.BLUE);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Portal purplePortal = new Portal(PortalColor.PURPLE, WidgetPortal.PURPLE);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Portal yellowPortal = new Portal(PortalColor.YELLOW, WidgetPortal.YELLOW);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Portal redPortal = new Portal(PortalColor.RED, WidgetPortal.RED);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int shieldsDropped = 0;
|
||||||
|
|
||||||
// Game starts with all possible rotations
|
// Game starts with all possible rotations
|
||||||
private Rotation[] possibleRotations = Rotation.values();
|
private PortalRotation[] possibleRotations = PortalRotation.values();
|
||||||
// Number of shields dropped
|
|
||||||
private int shieldsDropped;
|
|
||||||
|
|
||||||
@Getter
|
private boolean portalLocationsSet = false;
|
||||||
private final PortalContext purple = new PortalContext(PURPLE);
|
|
||||||
@Getter
|
|
||||||
private final PortalContext blue = new PortalContext(BLUE);
|
|
||||||
@Getter
|
|
||||||
private final PortalContext yellow = new PortalContext(YELLOW);
|
|
||||||
@Getter
|
|
||||||
private final PortalContext red = new PortalContext(RED);
|
|
||||||
|
|
||||||
void fall(String color)
|
|
||||||
|
private Instant startTime = Instant.now();
|
||||||
|
|
||||||
|
public Game(Client client, PestControlPlugin plugin)
|
||||||
{
|
{
|
||||||
switch (color.toLowerCase())
|
this.client = client;
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onGameTick(GameTick gameTickEvent)
|
||||||
|
{
|
||||||
|
if (!portalLocationsSet)
|
||||||
|
{
|
||||||
|
loadPortalLocations();
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetOverlay widgetOverlay = plugin.getWidgetOverlay();
|
||||||
|
|
||||||
|
if (!purplePortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.PURPLE) == 0)
|
||||||
|
{
|
||||||
|
killPortal(purplePortal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yellowPortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.YELLOW) == 0)
|
||||||
|
{
|
||||||
|
killPortal(yellowPortal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!redPortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.RED) == 0)
|
||||||
|
{
|
||||||
|
killPortal(redPortal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bluePortal.isDead() && widgetOverlay.getPortalHitpoints(PortalColor.BLUE) == 0)
|
||||||
|
{
|
||||||
|
killPortal(bluePortal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lowerPortalShield(String portalColor)
|
||||||
|
{
|
||||||
|
switch (portalColor.toLowerCase())
|
||||||
{
|
{
|
||||||
case "purple":
|
case "purple":
|
||||||
fall(purple);
|
lowerPortalShield(purplePortal);
|
||||||
break;
|
break;
|
||||||
case "red":
|
case "red":
|
||||||
fall(red);
|
lowerPortalShield(redPortal);
|
||||||
break;
|
break;
|
||||||
case "yellow":
|
case "yellow":
|
||||||
fall(yellow);
|
lowerPortalShield(yellowPortal);
|
||||||
break;
|
break;
|
||||||
case "blue":
|
case "blue":
|
||||||
fall(blue);
|
lowerPortalShield(bluePortal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fall(PortalContext portal)
|
private void lowerPortalShield(Portal portal)
|
||||||
{
|
{
|
||||||
if (!portal.isShielded())
|
if (!portal.isShielded())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Shield dropped for {}", portal.getPortal());
|
log.debug("Shield dropped for {}", portal.getColor());
|
||||||
|
|
||||||
|
portal.setPortalState(PortalState.ACTIVE);
|
||||||
|
|
||||||
portal.setShielded(false);
|
|
||||||
int shieldDrop = shieldsDropped++;
|
int shieldDrop = shieldsDropped++;
|
||||||
|
|
||||||
// Remove impossible rotations
|
// Remove impossible rotations
|
||||||
List<Rotation> rotations = new ArrayList<>();
|
List<PortalRotation> rotations = new ArrayList<>();
|
||||||
|
|
||||||
for (Rotation rotation : possibleRotations)
|
for (PortalRotation rotation : possibleRotations)
|
||||||
{
|
{
|
||||||
if (rotation.getPortal(shieldDrop) == portal.getPortal())
|
if (rotation.getPortal(this, shieldDrop) == portal)
|
||||||
{
|
{
|
||||||
rotations.add(rotation);
|
rotations.add(rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
possibleRotations = rotations.toArray(new Rotation[rotations.size()]);
|
possibleRotations = rotations.toArray(new PortalRotation[rotations.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void die(PortalContext portal)
|
public void killPortal(Portal portal)
|
||||||
{
|
{
|
||||||
if (portal.isDead())
|
if (portal.isDead())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Portal {} died", portal.getPortal());
|
log.debug("Portal {} died", portal.getColor());
|
||||||
|
|
||||||
portal.setDead(true);
|
portal.setPortalState(PortalState.DEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<Portal> getNextPortals()
|
private boolean loadPortalLocations()
|
||||||
|
{
|
||||||
|
NPC squire = null;
|
||||||
|
|
||||||
|
for (NPC npc : client.getNpcs())
|
||||||
|
{
|
||||||
|
if (PestControlNpc.isIngameSquireId(npc.getId()))
|
||||||
|
{
|
||||||
|
squire = npc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (squire != null)
|
||||||
|
{
|
||||||
|
log.debug("In-game Squire found: {}", squire);
|
||||||
|
setPortalLocations(squire.getWorldLocation());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPortalLocations(WorldPoint squireLocation)
|
||||||
|
{
|
||||||
|
int x = squireLocation.getX();
|
||||||
|
int y = squireLocation.getY();
|
||||||
|
|
||||||
|
purplePortal.setLocation(new WorldPoint(x - 26, y - 15, 0));
|
||||||
|
bluePortal.setLocation(new WorldPoint(x + 26, y - 18, 0));
|
||||||
|
yellowPortal.setLocation(new WorldPoint(x + 15, y - 36, 0));
|
||||||
|
redPortal.setLocation(new WorldPoint(x - 9, y - 37, 0));
|
||||||
|
|
||||||
|
portalLocationsSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Portal> getPortals()
|
||||||
|
{
|
||||||
|
List<Portal> portalList = new ArrayList<Portal>();
|
||||||
|
|
||||||
|
portalList.add(getPurplePortal());
|
||||||
|
portalList.add(getBluePortal());
|
||||||
|
portalList.add(getYellowPortal());
|
||||||
|
portalList.add(getRedPortal());
|
||||||
|
|
||||||
|
return portalList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Portal getPortal(PortalColor portalColor)
|
||||||
|
{
|
||||||
|
if (bluePortal.getColor() == portalColor)
|
||||||
|
{
|
||||||
|
return bluePortal;
|
||||||
|
}
|
||||||
|
if (redPortal.getColor() == portalColor)
|
||||||
|
{
|
||||||
|
return redPortal;
|
||||||
|
}
|
||||||
|
if (purplePortal.getColor() == portalColor)
|
||||||
|
{
|
||||||
|
return purplePortal;
|
||||||
|
}
|
||||||
|
if (yellowPortal.getColor() == portalColor)
|
||||||
|
{
|
||||||
|
return yellowPortal;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Portal> getNextPortals()
|
||||||
{
|
{
|
||||||
List<Portal> portals = new ArrayList<>();
|
List<Portal> portals = new ArrayList<>();
|
||||||
|
|
||||||
for (Rotation rotation : possibleRotations)
|
for (PortalRotation rotation : possibleRotations)
|
||||||
{
|
{
|
||||||
Portal portal = rotation.getPortal(shieldsDropped);
|
Portal portal = rotation.getPortal(this, shieldsDropped);
|
||||||
|
|
||||||
if (portal != null && !portals.contains(portal))
|
if (portal != null && !portals.contains(portal))
|
||||||
{
|
{
|
||||||
@@ -124,4 +248,40 @@ class Game
|
|||||||
|
|
||||||
return portals;
|
return portals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<Portal> getActivePortals()
|
||||||
|
{
|
||||||
|
List<Portal> portals = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Portal portal : getPortals())
|
||||||
|
{
|
||||||
|
if (portal.isActive())
|
||||||
|
{
|
||||||
|
portals.add(portal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return portals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Duration getTimeTillNextPortal()
|
||||||
|
{
|
||||||
|
Instant nextShieldDrop;
|
||||||
|
|
||||||
|
if (shieldsDropped == 4)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shieldsDropped == 0)
|
||||||
|
{
|
||||||
|
nextShieldDrop = Instant.ofEpochSecond(startTime.getEpochSecond() + 17);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextShieldDrop = Instant.ofEpochSecond(startTime.getEpochSecond() + 17 + (30 * shieldsDropped));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Duration.between(Instant.now(), nextShieldDrop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Player;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Tile;
|
||||||
|
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.tooltip.Tooltip;
|
||||||
|
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||||
|
import net.runelite.client.util.ColorUtil;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class GangplankOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final Client client;
|
||||||
|
private final PestControlConfig config;
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
private final TooltipManager tooltipManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GangplankOverlay(Client client, PestControlConfig config, PestControlPlugin plugin, TooltipManager toolTipManager)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.client = client;
|
||||||
|
this.tooltipManager = toolTipManager;
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!plugin.isOnPestControlMainIsland())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player localPlayer = client.getLocalPlayer();
|
||||||
|
|
||||||
|
if (localPlayer == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int combatLevel = localPlayer.getCombatLevel();
|
||||||
|
|
||||||
|
Color noviceCbColor = (combatLevel >= 40) ? Color.GREEN : Color.RED;
|
||||||
|
Color intermediateCbColor = (combatLevel >= 70) ? Color.GREEN : Color.RED;
|
||||||
|
Color veteranCbColor = (combatLevel >= 100) ? Color.GREEN : Color.RED;
|
||||||
|
|
||||||
|
Tile noviceGangplankTile = plugin.getNoviceGangplankTile();
|
||||||
|
Tile intermediateGangplankTile = plugin.getIntermediateGangplankTile();
|
||||||
|
Tile veteranGangplankTile = plugin.getVeteranGangplankTile();
|
||||||
|
|
||||||
|
Point mousePosition = client.getMouseCanvasPosition();
|
||||||
|
String tooltipString = null;
|
||||||
|
|
||||||
|
if (noviceGangplankTile != null)
|
||||||
|
{
|
||||||
|
Polygon polygon = noviceGangplankTile.getGameObjects()[0].getConvexHull();
|
||||||
|
if (polygon != null)
|
||||||
|
{
|
||||||
|
graphics.setColor(noviceCbColor);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.drawPolygon(polygon);
|
||||||
|
graphics.setColor(setColorAlpha(noviceCbColor, 45));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
|
||||||
|
if (polygon.contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
tooltipString = ColorUtil.wrapWithColorTag("Combat 40+", noviceCbColor) + " (3 points)";
|
||||||
|
graphics.setColor(setColorAlpha(noviceCbColor, 65));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intermediateGangplankTile != null)
|
||||||
|
{
|
||||||
|
Polygon polygon = intermediateGangplankTile.getGameObjects()[0].getConvexHull();
|
||||||
|
if (polygon != null)
|
||||||
|
{
|
||||||
|
graphics.setColor(intermediateCbColor);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.drawPolygon(polygon);
|
||||||
|
graphics.setColor(setColorAlpha(intermediateCbColor, 45));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
|
||||||
|
if (polygon.contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
tooltipString = ColorUtil.wrapWithColorTag("Combat 70+", intermediateCbColor) + " (4 points)";
|
||||||
|
graphics.setColor(setColorAlpha(intermediateCbColor, 65));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (veteranGangplankTile != null)
|
||||||
|
{
|
||||||
|
Polygon polygon = veteranGangplankTile.getGameObjects()[0].getConvexHull();
|
||||||
|
if (polygon != null)
|
||||||
|
{
|
||||||
|
graphics.setColor(veteranCbColor);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.drawPolygon(polygon);
|
||||||
|
graphics.setColor(setColorAlpha(veteranCbColor, 45));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
|
||||||
|
if (polygon.contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
tooltipString = ColorUtil.wrapWithColorTag("Combat 100+", veteranCbColor) + " (5 points)";
|
||||||
|
graphics.setColor(setColorAlpha(veteranCbColor, 65));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooltipString != null)
|
||||||
|
{
|
||||||
|
tooltipManager.add(new Tooltip(tooltipString));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color setColorAlpha(Color color, int alpha)
|
||||||
|
{
|
||||||
|
return new Color(
|
||||||
|
color.getRed(),
|
||||||
|
color.getGreen(),
|
||||||
|
color.getBlue(),
|
||||||
|
alpha
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class HintArrowOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final PestControlConfig config;
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HintArrowOverlay(PestControlConfig config, PestControlPlugin plugin, Client client)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (plugin.getGame() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NPC> visibleActivePortals = new ArrayList<>();
|
||||||
|
List<NPC> visibleShieldedPortals = new ArrayList<>();
|
||||||
|
|
||||||
|
for (NPC npc : client.getNpcs())
|
||||||
|
{
|
||||||
|
if (PestControlNpc.isActivePortalId(npc.getId()))
|
||||||
|
{
|
||||||
|
visibleActivePortals.add(npc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!visibleActivePortals.isEmpty())
|
||||||
|
{
|
||||||
|
NPC closestPortalNpc = getClosestNpc(visibleActivePortals);
|
||||||
|
|
||||||
|
if (closestPortalNpc != null)
|
||||||
|
{
|
||||||
|
NPC currentHintArrowTarget = client.getHintArrowNpc();
|
||||||
|
|
||||||
|
if (currentHintArrowTarget == null || currentHintArrowTarget != closestPortalNpc)
|
||||||
|
{
|
||||||
|
client.setHintArrow(closestPortalNpc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Portal closestActivePortal = getClosestPortal(PortalState.ACTIVE);
|
||||||
|
|
||||||
|
if (closestActivePortal != null)
|
||||||
|
{
|
||||||
|
WorldPoint currentHintArrowLocation = client.getHintArrowPoint();
|
||||||
|
WorldPoint closestActivePortalLocation = closestActivePortal.getLocation();
|
||||||
|
|
||||||
|
if (currentHintArrowLocation == null || currentHintArrowLocation != closestActivePortalLocation)
|
||||||
|
{
|
||||||
|
client.setHintArrow(closestActivePortalLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<Portal> nextPortalList = plugin.getGame().getNextPortals();
|
||||||
|
|
||||||
|
if (nextPortalList.size() == 1)
|
||||||
|
{
|
||||||
|
client.setHintArrow(nextPortalList.iterator().next().getLocation());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NPC getClosestNpc(List<NPC> npcList)
|
||||||
|
{
|
||||||
|
WorldPoint currentLocation = client.getLocalPlayer().getWorldLocation();
|
||||||
|
|
||||||
|
NPC closestNpc = null;
|
||||||
|
int currentShortestDistance = 1337;
|
||||||
|
int distanceToNpc;
|
||||||
|
|
||||||
|
for (NPC npc : npcList)
|
||||||
|
{
|
||||||
|
if (closestNpc != null)
|
||||||
|
{
|
||||||
|
distanceToNpc = npc.getWorldLocation().distanceTo(currentLocation);
|
||||||
|
|
||||||
|
if (distanceToNpc < currentShortestDistance)
|
||||||
|
{
|
||||||
|
closestNpc = npc;
|
||||||
|
currentShortestDistance = distanceToNpc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
closestNpc = npc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestNpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Portal getClosestPortal(PortalState portalState)
|
||||||
|
{
|
||||||
|
WorldPoint currentLocation = client.getLocalPlayer().getWorldLocation();
|
||||||
|
|
||||||
|
Portal closestPortal = null;
|
||||||
|
int currentShortestDistance = 1337;
|
||||||
|
int distanceToWorldPoint;
|
||||||
|
|
||||||
|
for (Portal portal : plugin.getGame().getPortals())
|
||||||
|
{
|
||||||
|
if (portal.getPortalState() != portalState)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
distanceToWorldPoint = portal.getLocation().distanceTo(currentLocation);
|
||||||
|
|
||||||
|
if (distanceToWorldPoint < currentShortestDistance)
|
||||||
|
{
|
||||||
|
closestPortal = portal;
|
||||||
|
currentShortestDistance = distanceToWorldPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestPortal;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class NpcHighlightContext
|
||||||
|
{
|
||||||
|
private NpcHighlightStyle npcRenderStyle;
|
||||||
|
private Color color;
|
||||||
|
private boolean showNpcName = false;
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.Perspective;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class NpcHighlightOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final PestControlConfig config;
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
NpcHighlightOverlay(PestControlConfig config, PestControlPlugin plugin, Client client)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (plugin.getGame() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap highlightedNpcList = plugin.getHighlightedNpcList();
|
||||||
|
|
||||||
|
for (NPC npc : client.getNpcs())
|
||||||
|
{
|
||||||
|
if (!highlightedNpcList.containsKey(npc.getId()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
NpcHighlightContext npcHighlightContext = plugin.getHighlightedNpcList().get(npc.getId());
|
||||||
|
|
||||||
|
String name = npcHighlightContext.isShowNpcName() ? npc.getName() : null;
|
||||||
|
Color color = npcHighlightContext.getColor();
|
||||||
|
NpcHighlightStyle highlightStyle = npcHighlightContext.getNpcRenderStyle();
|
||||||
|
|
||||||
|
switch (highlightStyle)
|
||||||
|
{
|
||||||
|
case HULL:
|
||||||
|
{
|
||||||
|
renderHullOverlay(graphics, npc, color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TILE:
|
||||||
|
{
|
||||||
|
renderTileOverlay(graphics, npc, color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BOTH:
|
||||||
|
{
|
||||||
|
renderHullOverlay(graphics, npc, color);
|
||||||
|
renderTileOverlay(graphics, npc, color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name != null)
|
||||||
|
{
|
||||||
|
renderTextOverlay(graphics, npc, name, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderTileOverlay(Graphics2D graphics, NPC npc, Color color)
|
||||||
|
{
|
||||||
|
Polygon polygon;
|
||||||
|
Color fillColor;
|
||||||
|
|
||||||
|
// Double the polygon size if it's a Brawler
|
||||||
|
if (PestControlNpc.isBrawlerId(npc.getId()))
|
||||||
|
{
|
||||||
|
polygon = Perspective.getCanvasTileAreaPoly(client, npc.getLocalLocation(), 2);
|
||||||
|
fillColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), 35);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
polygon = npc.getCanvasTilePoly();
|
||||||
|
fillColor = new Color(0, 0, 0, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (polygon != null)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.drawPolygon(polygon);
|
||||||
|
graphics.setColor(fillColor);
|
||||||
|
graphics.fillPolygon(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderHullOverlay(Graphics2D graphics, NPC npc, Color color)
|
||||||
|
{
|
||||||
|
Polygon objectClickbox = npc.getConvexHull();
|
||||||
|
if (objectClickbox != null)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.draw(objectClickbox);
|
||||||
|
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20));
|
||||||
|
graphics.fill(objectClickbox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderTextOverlay(Graphics2D graphics, NPC npc, String text, Color color)
|
||||||
|
{
|
||||||
|
Point textLocation = npc.getCanvasTextLocation(graphics, text, npc.getLogicalHeight() + 40);
|
||||||
|
if (textLocation != null)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderTextLocation(graphics, textLocation, text, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
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.plugins.pestcontrol.config.HighlightPortalOption;
|
||||||
|
import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle;
|
||||||
|
|
||||||
|
@ConfigGroup("pestcontrol")
|
||||||
|
public interface PestControlConfig extends Config
|
||||||
|
{
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "showHintArrow",
|
||||||
|
name = "Show hint arrows",
|
||||||
|
description = "Show hint arrows to the portals that can be attacked.",
|
||||||
|
position = 1
|
||||||
|
)
|
||||||
|
default boolean showHintArrow()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "showPortalWeakness",
|
||||||
|
name = "Show portal weakness",
|
||||||
|
description = "Show the combat style weakness of the portals. For melee the attack styles are shown: Stab/Crush/Slash",
|
||||||
|
position = 2
|
||||||
|
)
|
||||||
|
default boolean showPortalWeakness()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "highlightGangplanks",
|
||||||
|
name = "Highlight gangplanks",
|
||||||
|
description = "Highlight the boarding gangplanks and show the required combat level.",
|
||||||
|
position = 3
|
||||||
|
)
|
||||||
|
default boolean highlightGangplanks()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "highlightPortals",
|
||||||
|
name = "Highlight portals",
|
||||||
|
description = "Highlight all, active or shielded portals.",
|
||||||
|
position = 4
|
||||||
|
)
|
||||||
|
default HighlightPortalOption portalHighlight()
|
||||||
|
{
|
||||||
|
return HighlightPortalOption.ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "activePortalColor",
|
||||||
|
name = "Active portal color",
|
||||||
|
description = "Color of the portals that can be attacked.",
|
||||||
|
position = 5
|
||||||
|
)
|
||||||
|
default Color activePortalColor()
|
||||||
|
{
|
||||||
|
return Color.GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "shieldedPortalColor",
|
||||||
|
name = "Shielded portal color",
|
||||||
|
description = "Color of the portals that are shielded.",
|
||||||
|
position = 6
|
||||||
|
)
|
||||||
|
default Color shieldedPortalColor()
|
||||||
|
{
|
||||||
|
return Color.BLUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "highlightSpinners",
|
||||||
|
name = "Highlight Spinners",
|
||||||
|
description = "Highlights Spinners. Highlighting them is recommended as Spinners heal the portals.",
|
||||||
|
position = 7
|
||||||
|
)
|
||||||
|
default NpcHighlightStyle highlightSpinners()
|
||||||
|
{
|
||||||
|
return NpcHighlightStyle.BOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "spinnerColor",
|
||||||
|
name = "Spinner color",
|
||||||
|
description = "Color of highlighted Spinners.",
|
||||||
|
position = 8
|
||||||
|
)
|
||||||
|
default Color spinnerColor()
|
||||||
|
{
|
||||||
|
return Color.CYAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "highlightBrawlers",
|
||||||
|
name = "Highlight Brawlers",
|
||||||
|
description = "Highlights Brawlers.",
|
||||||
|
position = 9
|
||||||
|
)
|
||||||
|
default NpcHighlightStyle highlightBrawlers()
|
||||||
|
{
|
||||||
|
return NpcHighlightStyle.TILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "brawlerColor",
|
||||||
|
name = "Brawler color",
|
||||||
|
description = "Color of highlighted Brawlers.",
|
||||||
|
position = 10
|
||||||
|
)
|
||||||
|
default Color brawlerColor()
|
||||||
|
{
|
||||||
|
return Color.ORANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "highlightRepairables",
|
||||||
|
name = "Highlight repairables",
|
||||||
|
description = "Highlight repairable barricades and gates.",
|
||||||
|
position = 11
|
||||||
|
)
|
||||||
|
default boolean highlightRepairables()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "repairableColor",
|
||||||
|
name = "Repairable color",
|
||||||
|
description = "Color of highlighted repairables.",
|
||||||
|
position = 12
|
||||||
|
)
|
||||||
|
/*default Color repairableColor()
|
||||||
|
{
|
||||||
|
return new Color(193, 141, 255);
|
||||||
|
}*/
|
||||||
|
default Color repairableColor()
|
||||||
|
{
|
||||||
|
return Color.YELLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "showPoints",
|
||||||
|
name = "Show points indicator",
|
||||||
|
description = "Always display your points when on the island or in the minigame.",
|
||||||
|
position = 13
|
||||||
|
)
|
||||||
|
default boolean showPoints()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "showTimeTillNextPortal",
|
||||||
|
name = "Show time till next portal",
|
||||||
|
description = "Show a timer that counts down till the next portal is attackable.",
|
||||||
|
position = 14
|
||||||
|
)
|
||||||
|
default boolean showTimeTillNextPortal()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.NpcID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class PestControlNpc
|
||||||
|
{
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> splatterIdSet = ImmutableSet.of(
|
||||||
|
NpcID.SPLATTER,
|
||||||
|
NpcID.SPLATTER_1690,
|
||||||
|
NpcID.SPLATTER_1691,
|
||||||
|
NpcID.SPLATTER_1692,
|
||||||
|
NpcID.SPLATTER_1693
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static final Set<Integer> shifterIdSet = ImmutableSet.of(
|
||||||
|
NpcID.SHIFTER,
|
||||||
|
NpcID.SHIFTER_1695,
|
||||||
|
NpcID.SHIFTER_1696,
|
||||||
|
NpcID.SHIFTER_1697,
|
||||||
|
NpcID.SHIFTER_1698,
|
||||||
|
NpcID.SHIFTER_1699,
|
||||||
|
NpcID.SHIFTER_1700,
|
||||||
|
NpcID.SHIFTER_1701,
|
||||||
|
NpcID.SHIFTER_1702,
|
||||||
|
NpcID.SHIFTER_1703
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> spinnerIdSet = ImmutableSet.of(
|
||||||
|
NpcID.SPINNER,
|
||||||
|
NpcID.SPINNER_1710,
|
||||||
|
NpcID.SPINNER_1711,
|
||||||
|
NpcID.SPINNER_1712,
|
||||||
|
NpcID.SPINNER_1713
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> torcherIdSet = ImmutableSet.of(
|
||||||
|
NpcID.TORCHER,
|
||||||
|
NpcID.TORCHER_1715,
|
||||||
|
NpcID.TORCHER_1716,
|
||||||
|
NpcID.TORCHER_1717,
|
||||||
|
NpcID.TORCHER_1718,
|
||||||
|
NpcID.TORCHER_1719,
|
||||||
|
NpcID.TORCHER_1720,
|
||||||
|
NpcID.TORCHER_1721,
|
||||||
|
NpcID.TORCHER_1722,
|
||||||
|
NpcID.TORCHER_1723
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> defilerIdSet = ImmutableSet.of(
|
||||||
|
NpcID.DEFILER,
|
||||||
|
NpcID.DEFILER_1725,
|
||||||
|
NpcID.DEFILER_1726,
|
||||||
|
NpcID.DEFILER_1727,
|
||||||
|
NpcID.DEFILER_1728,
|
||||||
|
NpcID.DEFILER_1729,
|
||||||
|
NpcID.DEFILER_1730,
|
||||||
|
NpcID.DEFILER_1731,
|
||||||
|
NpcID.DEFILER_1732,
|
||||||
|
NpcID.DEFILER_1733
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> brawlerIdSet = ImmutableSet.of(
|
||||||
|
NpcID.BRAWLER,
|
||||||
|
NpcID.BRAWLER_1735,
|
||||||
|
NpcID.BRAWLER_1736,
|
||||||
|
NpcID.BRAWLER_1737,
|
||||||
|
NpcID.BRAWLER_1738
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> ravagerIdSet = ImmutableSet.of(
|
||||||
|
NpcID.RAVAGER,
|
||||||
|
NpcID.RAVAGER_1705,
|
||||||
|
NpcID.RAVAGER_1706,
|
||||||
|
NpcID.RAVAGER_1707,
|
||||||
|
NpcID.RAVAGER_1708
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> activePortalIdSet = ImmutableSet.of(
|
||||||
|
NpcID.PORTAL_1747, // Novice Purple Active
|
||||||
|
NpcID.PORTAL_1748, // Novice Blue Active
|
||||||
|
NpcID.PORTAL_1749, // Novice Yellow Active
|
||||||
|
NpcID.PORTAL_1750, // Novice Red Active
|
||||||
|
NpcID.PORTAL, // Intermediate Purple Active
|
||||||
|
NpcID.PORTAL_1740, // Intermediate Blue Active
|
||||||
|
NpcID.PORTAL_1741, // Intermediate Yellow Active
|
||||||
|
NpcID.PORTAL_1742 // Intermediate Red Active
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> shieldedPortalIdSet = ImmutableSet.of(
|
||||||
|
NpcID.PORTAL_1751, // Novice Purple Shielded
|
||||||
|
NpcID.PORTAL_1752, // Novice Blue Shielded
|
||||||
|
NpcID.PORTAL_1753, // Novice Yellow Shielded
|
||||||
|
NpcID.PORTAL_1754, // Novice Red Shielded
|
||||||
|
NpcID.PORTAL_1743, // Intermediate Purple Shielded
|
||||||
|
NpcID.PORTAL_1744, // Intermediate Blue Shielded
|
||||||
|
NpcID.PORTAL_1745, // Intermediate Yellow Shielded
|
||||||
|
NpcID.PORTAL_1746 // Intermediate Red Shielded
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> purplePortalIdSet = ImmutableSet.of(
|
||||||
|
NpcID.PORTAL_1747, // Novice Purple Active
|
||||||
|
NpcID.PORTAL_1751, // Novice Purple Shielded
|
||||||
|
NpcID.PORTAL, // Intermediate Purple Active
|
||||||
|
NpcID.PORTAL_1743 // Intermediate Purple Shielded
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> bluePortalIdSet = ImmutableSet.of(
|
||||||
|
NpcID.PORTAL_1748, // Novice Blue Active
|
||||||
|
NpcID.PORTAL_1752, // Novice Blue Shielded
|
||||||
|
NpcID.PORTAL_1740, // Intermediate Blue Active
|
||||||
|
NpcID.PORTAL_1744 // Intermediate Blue Shielded
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> yellowPortalIdSet = ImmutableSet.of(
|
||||||
|
NpcID.PORTAL_1749, // Novice Yellow Active
|
||||||
|
NpcID.PORTAL_1753, // Novice Yellow Shielded
|
||||||
|
NpcID.PORTAL_1741, // Intermediate Yellow Active
|
||||||
|
NpcID.PORTAL_1745 // Intermediate Yellow Shielded
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> redPortalIdSet = ImmutableSet.of(
|
||||||
|
NpcID.PORTAL_1750, // Novice Red Active
|
||||||
|
NpcID.PORTAL_1754, // Novice Red Shielded
|
||||||
|
NpcID.PORTAL_1742, // Intermediate Red Active
|
||||||
|
NpcID.PORTAL_1746 // Intermediate Red Shielded
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> ingameVoidKnightIdSet = ImmutableSet.of(
|
||||||
|
NpcID.VOID_KNIGHT_2950,
|
||||||
|
NpcID.VOID_KNIGHT_2951,
|
||||||
|
NpcID.VOID_KNIGHT_2952,
|
||||||
|
NpcID.VOID_KNIGHT_2953
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Integer ingameSquireId = NpcID.SQUIRE_2949;
|
||||||
|
|
||||||
|
public static boolean isSplatterId(int npcId)
|
||||||
|
{
|
||||||
|
return splatterIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isShifterId(int npcId)
|
||||||
|
{
|
||||||
|
return shifterIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSpinnerId(int npcId)
|
||||||
|
{
|
||||||
|
return brawlerIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isTorcherId(int npcId)
|
||||||
|
{
|
||||||
|
return torcherIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDefilerId(int npcId)
|
||||||
|
{
|
||||||
|
return defilerIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBrawlerId(int npcId)
|
||||||
|
{
|
||||||
|
return brawlerIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRavagerId(int npcId)
|
||||||
|
{
|
||||||
|
return ravagerIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIngameVoidKnightId(int npcId)
|
||||||
|
{
|
||||||
|
return ingameVoidKnightIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIngameSquireId(int npcId)
|
||||||
|
{
|
||||||
|
return ingameSquireId == npcId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPortalId(int npcId)
|
||||||
|
{
|
||||||
|
return (isActivePortalId(npcId) || isShieldedPortalId(npcId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isActivePortalId(int npcId)
|
||||||
|
{
|
||||||
|
return activePortalIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isShieldedPortalId(int npcId)
|
||||||
|
{
|
||||||
|
return shieldedPortalIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPurplePortalId(int npcId)
|
||||||
|
{
|
||||||
|
return purplePortalIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBluePortalId(int npcId)
|
||||||
|
{
|
||||||
|
return bluePortalIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isYellowPortalId(int npcId)
|
||||||
|
{
|
||||||
|
return yellowPortalIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRedPortalId(int npcId)
|
||||||
|
{
|
||||||
|
return redPortalIdSet.contains(npcId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Kronos <https://github.com/KronosDesign>
|
* Copyright (c) 2017, Kronos <https://github.com/KronosDesign>
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,29 +25,47 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.pestcontrol;
|
package net.runelite.client.plugins.pestcontrol;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.inject.Inject;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.ItemID;
|
||||||
import net.runelite.api.NpcID;
|
import net.runelite.api.Tile;
|
||||||
|
import net.runelite.api.TileObject;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
|
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.GameStateChanged;
|
||||||
import net.runelite.api.events.NpcDespawned;
|
import net.runelite.api.events.GameTick;
|
||||||
import net.runelite.api.events.NpcSpawned;
|
import net.runelite.api.events.GroundObjectChanged;
|
||||||
|
import net.runelite.api.events.GroundObjectDespawned;
|
||||||
|
import net.runelite.api.events.GroundObjectSpawned;
|
||||||
|
import net.runelite.api.events.WidgetLoaded;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.plugins.pestcontrol.config.HighlightPortalOption;
|
||||||
|
import net.runelite.client.plugins.pestcontrol.config.NpcHighlightStyle;
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
|
import net.runelite.client.util.Text;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Pest Control",
|
name = "Pest Control",
|
||||||
description = "Show helpful information for the Pest Control minigame",
|
description = "Show helpful information for the Pest Control minigame",
|
||||||
@@ -54,77 +73,598 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
|||||||
)
|
)
|
||||||
public class PestControlPlugin extends Plugin
|
public class PestControlPlugin extends Plugin
|
||||||
{
|
{
|
||||||
private static final Set<Integer> SPINNER_IDS = ImmutableSet.of(
|
private final int NOVICE_GANGPLANK = 14315; // Combat 40+ (3 points)
|
||||||
NpcID.SPINNER,
|
private final int INTERMEDIATE_GANGPLANK = 25631; // Combat 70+ (4 points)
|
||||||
NpcID.SPINNER_1710,
|
private final int VETERAN_GANGPLANK = 25632; // Combat 100+ (5 points)
|
||||||
NpcID.SPINNER_1711,
|
|
||||||
NpcID.SPINNER_1712,
|
|
||||||
NpcID.SPINNER_1713
|
|
||||||
);
|
|
||||||
|
|
||||||
private final Pattern SHIELD_DROP = Pattern.compile("The ([a-z]+), [^ ]+ portal shield has dropped!", Pattern.CASE_INSENSITIVE);
|
private final Pattern SHIELD_DROP_PATTERN = Pattern.compile("The ([a-z]+), [^ ]+ portal shield has dropped!");
|
||||||
|
private final Pattern EXCHANGE_WINDOW_POINTS_PATTERN = Pattern.compile("Points: <col=ffffff>([0-9]+)</col>");
|
||||||
|
private final Pattern BOAT_POINTS_PATTERN = Pattern.compile("Pest Points: ([0-9]+)");
|
||||||
|
private final Pattern AWARDED_PATTERN = Pattern.compile("We've awarded you ([0-9]+) Void Knight Commendation points.");
|
||||||
|
private final Pattern PURCHASE_PATTERN = Pattern.compile("Remaining Void Knight Commendation Points: ([0-9]+)");
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Inject
|
||||||
private List<NPC> spinners = new ArrayList<>();
|
@Getter
|
||||||
|
private Client client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayManager overlayManager;
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private ConfigManager configManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PestControlOverlay overlay;
|
private InfoBoxManager infoBoxManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Getter
|
||||||
|
private ItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Getter
|
||||||
|
private PestControlConfig config;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Getter
|
||||||
|
private WidgetOverlay widgetOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private HintArrowOverlay hintArrowOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private NpcHighlightOverlay npcHighlightOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RepairOverlay repairOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GangplankOverlay gangplankOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TimerOverlay timerOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PortalWeaknessOverlay portalWeaknessOverlay;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Game game;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private HashMap<Integer, NpcHighlightContext> highlightedNpcList = new HashMap<Integer, NpcHighlightContext>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private List<TileObject> highlightedRepairList = new ArrayList<TileObject>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Tile noviceGangplankTile;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Tile intermediateGangplankTile;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Tile veteranGangplankTile;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Integer commendationPoints;
|
||||||
|
|
||||||
|
private String userConfigKey;
|
||||||
|
|
||||||
|
private boolean checkForPointWidgets;
|
||||||
|
|
||||||
|
private boolean pointsRewarded = false;
|
||||||
|
|
||||||
|
private PointsInfoboxCounter pointsInfoboxCounter;
|
||||||
|
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
PestControlConfig provideConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(PestControlConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
overlayManager.add(overlay);
|
loadPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
overlayManager.remove(overlay);
|
unloadPlugin();
|
||||||
spinners.clear();
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onConfigChanged(ConfigChanged configEvent)
|
||||||
|
{
|
||||||
|
if (configEvent.getGroup().equals("pestcontrol"))
|
||||||
|
{
|
||||||
|
unloadPlugin();
|
||||||
|
loadPlugin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean loadLocalUserPoints()
|
||||||
|
{
|
||||||
|
if (userConfigKey != null)
|
||||||
|
{
|
||||||
|
String configKey = "points." + userConfigKey;
|
||||||
|
String pointString = configManager.getConfiguration("pestcontrol", configKey);
|
||||||
|
if (pointString != null)
|
||||||
|
{
|
||||||
|
commendationPoints = Integer.parseInt(pointString);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPlugin()
|
||||||
|
{
|
||||||
|
if (loadLocalUserPoints())
|
||||||
|
{
|
||||||
|
handlePointsInfoboxCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
overlayManager.add(widgetOverlay);
|
||||||
|
|
||||||
|
if (config.highlightSpinners() != NpcHighlightStyle.OFF)
|
||||||
|
{
|
||||||
|
for (Integer npcId : PestControlNpc.getSpinnerIdSet())
|
||||||
|
{
|
||||||
|
highlightedNpcList.put(npcId, new NpcHighlightContext(
|
||||||
|
config.highlightSpinners(),
|
||||||
|
config.spinnerColor(),
|
||||||
|
true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.highlightBrawlers() != NpcHighlightStyle.OFF)
|
||||||
|
{
|
||||||
|
for (Integer npcId : PestControlNpc.getBrawlerIdSet())
|
||||||
|
{
|
||||||
|
highlightedNpcList.put(npcId, new NpcHighlightContext(
|
||||||
|
config.highlightBrawlers(),
|
||||||
|
config.brawlerColor(),
|
||||||
|
false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.portalHighlight() != HighlightPortalOption.OFF)
|
||||||
|
{
|
||||||
|
if (config.portalHighlight() == HighlightPortalOption.ACTIVE ||
|
||||||
|
config.portalHighlight() == HighlightPortalOption.ALL)
|
||||||
|
{
|
||||||
|
for (Integer portalNpcId : PestControlNpc.getActivePortalIdSet())
|
||||||
|
{
|
||||||
|
highlightedNpcList.put(portalNpcId, new NpcHighlightContext(
|
||||||
|
NpcHighlightStyle.HULL,
|
||||||
|
config.activePortalColor(),
|
||||||
|
false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.portalHighlight() == HighlightPortalOption.SHIELDED ||
|
||||||
|
config.portalHighlight() == HighlightPortalOption.ALL)
|
||||||
|
{
|
||||||
|
for (Integer portalNpcId : PestControlNpc.getShieldedPortalIdSet())
|
||||||
|
{
|
||||||
|
highlightedNpcList.put(portalNpcId, new NpcHighlightContext(
|
||||||
|
NpcHighlightStyle.HULL,
|
||||||
|
config.shieldedPortalColor(),
|
||||||
|
false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!highlightedNpcList.isEmpty())
|
||||||
|
{
|
||||||
|
overlayManager.add(npcHighlightOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.highlightRepairables())
|
||||||
|
{
|
||||||
|
overlayManager.add(repairOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.showHintArrow())
|
||||||
|
{
|
||||||
|
overlayManager.add(hintArrowOverlay);
|
||||||
|
|
||||||
|
if (game != null && client.hasHintArrow())
|
||||||
|
{
|
||||||
|
client.clearHintArrow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.highlightGangplanks())
|
||||||
|
{
|
||||||
|
overlayManager.add(gangplankOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.showTimeTillNextPortal())
|
||||||
|
{
|
||||||
|
overlayManager.add(timerOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.showPortalWeakness())
|
||||||
|
{
|
||||||
|
overlayManager.add(portalWeaknessOverlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unloadPlugin()
|
||||||
|
{
|
||||||
|
overlayManager.remove(widgetOverlay);
|
||||||
|
overlayManager.remove(npcHighlightOverlay);
|
||||||
|
overlayManager.remove(repairOverlay);
|
||||||
|
overlayManager.remove(gangplankOverlay);
|
||||||
|
overlayManager.remove(hintArrowOverlay);
|
||||||
|
overlayManager.remove(timerOverlay);
|
||||||
|
overlayManager.remove(portalWeaknessOverlay);
|
||||||
|
|
||||||
|
infoBoxManager.removeInfoBox(pointsInfoboxCounter);
|
||||||
|
pointsInfoboxCounter = null;
|
||||||
|
|
||||||
|
highlightedNpcList.clear();
|
||||||
|
|
||||||
|
if (game != null && config.showHintArrow() && client.hasHintArrow())
|
||||||
|
{
|
||||||
|
client.clearHintArrow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onGameStateChanged(GameStateChanged event)
|
public void onGameStateChanged(GameStateChanged event)
|
||||||
{
|
{
|
||||||
GameState gameState = event.getGameState();
|
// LOGGED_IN also triggers when teleporting to the island
|
||||||
if (gameState == GameState.CONNECTION_LOST || gameState == GameState.LOGIN_SCREEN || gameState == GameState.HOPPING)
|
if (event.getGameState() == GameState.LOGGED_IN)
|
||||||
{
|
{
|
||||||
spinners.clear();
|
handlePointsInfoboxCounter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handlePointsInfoboxCounter()
|
||||||
|
{
|
||||||
|
if (!config.showPoints())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isOnPestControlMainIsland() && !isInPestControlInstance())
|
||||||
|
{
|
||||||
|
infoBoxManager.removeInfoBox(pointsInfoboxCounter);
|
||||||
|
pointsInfoboxCounter = null;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commendationPoints == null)
|
||||||
|
{
|
||||||
|
if (pointsInfoboxCounter != null)
|
||||||
|
{
|
||||||
|
infoBoxManager.removeInfoBox(pointsInfoboxCounter);
|
||||||
|
pointsInfoboxCounter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointsInfoboxCounter != null)
|
||||||
|
{
|
||||||
|
pointsInfoboxCounter.setCount(commendationPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BufferedImage image = itemManager.getImage(ItemID.VOID_SEAL1);
|
||||||
|
pointsInfoboxCounter = new PointsInfoboxCounter(image, this, commendationPoints);
|
||||||
|
pointsInfoboxCounter.setTooltip("Void Knight Commendation Points");
|
||||||
|
infoBoxManager.addInfoBox(pointsInfoboxCounter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void getPointsFromWidgets()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Get points from dialog after the game
|
||||||
|
Widget npcDialog = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT);
|
||||||
|
if (npcDialog != null)
|
||||||
|
{
|
||||||
|
String npcText = Text.sanitizeMultilineText(npcDialog.getText());
|
||||||
|
Matcher matcher = AWARDED_PATTERN.matcher(npcText);
|
||||||
|
|
||||||
|
if (matcher.find())
|
||||||
|
{
|
||||||
|
int newPoints = Integer.parseInt(matcher.group(1));
|
||||||
|
|
||||||
|
if (commendationPoints != null)
|
||||||
|
{
|
||||||
|
newPoints += commendationPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCommendationPoints(newPoints);
|
||||||
|
log.debug("PEST CONTROL [POINTS REWARDED] UPDATE: {}", commendationPoints);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get points from dialog after purchase
|
||||||
|
Widget pestControlDialog = client.getWidget(WidgetInfo.PEST_CONTROL_DIALOG_TEXT);
|
||||||
|
if (pestControlDialog != null)
|
||||||
|
{
|
||||||
|
String pestControlDialogText = Text.sanitizeMultilineText(pestControlDialog.getText());
|
||||||
|
Matcher matcher = PURCHASE_PATTERN.matcher(pestControlDialogText);
|
||||||
|
|
||||||
|
if (matcher.find())
|
||||||
|
{
|
||||||
|
setCommendationPoints(Integer.parseInt(matcher.group(1)));
|
||||||
|
log.debug("PEST CONTROL [DIALOG] POINTS UPDATE: {}", commendationPoints);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get points from exchange window
|
||||||
|
Widget exchangeWindowPointsWidget = client.getWidget(WidgetInfo.PEST_CONTROL_EXCHANGE_WINDOW_POINTS);
|
||||||
|
if (exchangeWindowPointsWidget != null)
|
||||||
|
{
|
||||||
|
String pointsString = exchangeWindowPointsWidget.getText();
|
||||||
|
|
||||||
|
Matcher matcher = EXCHANGE_WINDOW_POINTS_PATTERN.matcher(pointsString);
|
||||||
|
if (matcher.lookingAt())
|
||||||
|
{
|
||||||
|
setCommendationPoints(Integer.parseInt(matcher.group(1)));
|
||||||
|
log.debug("PEST CONTROL [EXCHANGE WINDOW] POINTS UPDATE: {}", commendationPoints);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get points in boat
|
||||||
|
// NOTE: The boat info widget is still active right after the game
|
||||||
|
// We should therefor only check for point updates if there are no dialogs
|
||||||
|
Widget boatPointsWidget = client.getWidget(WidgetInfo.PEST_CONTROL_BOAT_INFO_POINTS);
|
||||||
|
if (boatPointsWidget != null && npcDialog == null && pestControlDialog == null)
|
||||||
|
{
|
||||||
|
String pointsString = boatPointsWidget.getText();
|
||||||
|
Matcher matcher = BOAT_POINTS_PATTERN.matcher(pointsString);
|
||||||
|
|
||||||
|
if (matcher.lookingAt())
|
||||||
|
{
|
||||||
|
log.debug(matcher.toString());
|
||||||
|
log.debug("MATCHER GROUP 1: {}", matcher.group(1));
|
||||||
|
setCommendationPoints(Integer.parseInt(matcher.group(1)));
|
||||||
|
log.debug("PEST CONTROL [BOAT] POINTS UPDATE: {}", commendationPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommendationPoints(int newPoints)
|
||||||
|
{
|
||||||
|
if (userConfigKey == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commendationPoints == null || commendationPoints != newPoints)
|
||||||
|
{
|
||||||
|
commendationPoints = newPoints;
|
||||||
|
|
||||||
|
configManager.setConfiguration(
|
||||||
|
"pestcontrol",
|
||||||
|
"points." + userConfigKey,
|
||||||
|
String.valueOf(commendationPoints)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePointsInfoboxCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameTick(GameTick gameTickEvent)
|
||||||
|
{
|
||||||
|
// Check for widgets on main island
|
||||||
|
if (game == null && isOnPestControlMainIsland())
|
||||||
|
{
|
||||||
|
// This must be synchronized for some reason
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
if (checkForPointWidgets)
|
||||||
|
{
|
||||||
|
checkForPointWidgets = false;
|
||||||
|
getPointsFromWidgets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the points of the user
|
||||||
|
if (userConfigKey == null)
|
||||||
|
{
|
||||||
|
String username = client.getUsername();
|
||||||
|
|
||||||
|
if (username == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userConfigKey = String.valueOf(username.hashCode());
|
||||||
|
|
||||||
|
log.debug("USER CONFIG SCOPE: {}", userConfigKey);
|
||||||
|
|
||||||
|
if (loadLocalUserPoints())
|
||||||
|
{
|
||||||
|
handlePointsInfoboxCounter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the game has started
|
||||||
|
if (game == null && isInPestControlInstance())
|
||||||
|
{
|
||||||
|
log.debug("Pest control game has started");
|
||||||
|
game = new Game(client, this);
|
||||||
|
pointsRewarded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we are in a game
|
||||||
|
if (game == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we left the game
|
||||||
|
if (!isInPestControlInstance())
|
||||||
|
{
|
||||||
|
if (game != null)
|
||||||
|
{
|
||||||
|
log.debug("Pest control game has ended");
|
||||||
|
game = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
game.onGameTick(gameTickEvent);
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onChatMessage(ChatMessage chatMessage)
|
public void onChatMessage(ChatMessage chatMessage)
|
||||||
{
|
{
|
||||||
if (overlay.getGame() != null && chatMessage.getType() == ChatMessageType.GAMEMESSAGE)
|
if (game != null && chatMessage.getType() == ChatMessageType.GAMEMESSAGE)
|
||||||
{
|
{
|
||||||
Matcher matcher = SHIELD_DROP.matcher(chatMessage.getMessage());
|
Matcher matcher = SHIELD_DROP_PATTERN.matcher(chatMessage.getMessage());
|
||||||
if (matcher.lookingAt())
|
if (matcher.lookingAt())
|
||||||
{
|
{
|
||||||
overlay.getGame().fall(matcher.group(1));
|
game.lowerPortalShield(matcher.group(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onNpcSpawned(NpcSpawned event)
|
public void onWidgetLoaded(WidgetLoaded event)
|
||||||
{
|
{
|
||||||
final NPC npc = event.getNpc();
|
if (game != null)
|
||||||
if (SPINNER_IDS.contains(npc.getId()))
|
|
||||||
{
|
{
|
||||||
spinners.add(npc);
|
log.debug(event.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOnPestControlMainIsland() && game == null)
|
||||||
|
{
|
||||||
|
checkForPointWidgets = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unlistTileObject(TileObject tileObject)
|
||||||
|
{
|
||||||
|
int tileObjectId = tileObject.getId();
|
||||||
|
|
||||||
|
if (PestControlRepairObject.isRepairableBarricadeId(tileObjectId) ||
|
||||||
|
PestControlRepairObject.isRepairableGateId(tileObjectId))
|
||||||
|
{
|
||||||
|
highlightedRepairList.remove(tileObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tileObjectId)
|
||||||
|
{
|
||||||
|
case NOVICE_GANGPLANK:
|
||||||
|
{
|
||||||
|
noviceGangplankTile = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INTERMEDIATE_GANGPLANK:
|
||||||
|
{
|
||||||
|
intermediateGangplankTile = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VETERAN_GANGPLANK:
|
||||||
|
{
|
||||||
|
veteranGangplankTile = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTileObject(Tile tile, TileObject tileObject)
|
||||||
|
{
|
||||||
|
int tileObjectId = tileObject.getId();
|
||||||
|
|
||||||
|
if (PestControlRepairObject.isRepairableBarricadeId(tileObjectId) ||
|
||||||
|
PestControlRepairObject.isRepairableGateId(tileObjectId))
|
||||||
|
{
|
||||||
|
highlightedRepairList.add(tileObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tileObjectId)
|
||||||
|
{
|
||||||
|
case NOVICE_GANGPLANK:
|
||||||
|
{
|
||||||
|
noviceGangplankTile = tile;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INTERMEDIATE_GANGPLANK:
|
||||||
|
{
|
||||||
|
intermediateGangplankTile = tile;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VETERAN_GANGPLANK:
|
||||||
|
{
|
||||||
|
veteranGangplankTile = tile;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onNpcDespawned(NpcDespawned event)
|
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||||
{
|
{
|
||||||
spinners.remove(event.getNpc());
|
handleTileObject(event.getTile(), event.getGameObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameObjectChanged(GameObjectChanged event)
|
||||||
|
{
|
||||||
|
unlistTileObject(event.getPrevious());
|
||||||
|
handleTileObject(event.getTile(), event.getGameObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameObjectDespawned(GameObjectDespawned event)
|
||||||
|
{
|
||||||
|
unlistTileObject(event.getGameObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGroundObjectSpawned(GroundObjectSpawned event)
|
||||||
|
{
|
||||||
|
handleTileObject(event.getTile(), event.getGroundObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGroundObjectChanged(GroundObjectChanged event)
|
||||||
|
{
|
||||||
|
unlistTileObject(event.getPrevious());
|
||||||
|
handleTileObject(event.getTile(), event.getGroundObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGroundObjectDespawned(GroundObjectDespawned event)
|
||||||
|
{
|
||||||
|
unlistTileObject(event.getGroundObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInPestControlInstance()
|
||||||
|
{
|
||||||
|
return client.getWidget(WidgetInfo.PEST_CONTROL_BLUE_SHIELD) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnPestControlMainIsland()
|
||||||
|
{
|
||||||
|
return client.getLocalPlayer().getWorldLocation().getRegionID() == 10537;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.ObjectID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class PestControlRepairObject
|
||||||
|
{
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> repairableBarricades = ImmutableSet.of(
|
||||||
|
//ObjectID.BARRICADE_14224,
|
||||||
|
ObjectID.BARRICADE_14227,
|
||||||
|
ObjectID.BARRICADE_14228,
|
||||||
|
ObjectID.BARRICADE_14229,
|
||||||
|
ObjectID.BARRICADE_14230,
|
||||||
|
ObjectID.BARRICADE_14231,
|
||||||
|
ObjectID.BARRICADE_14232
|
||||||
|
);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Set<Integer> repairableGates = ImmutableSet.of(
|
||||||
|
ObjectID.GATE_14238,
|
||||||
|
ObjectID.GATE_14239,
|
||||||
|
ObjectID.GATE_14240,
|
||||||
|
ObjectID.GATE_14241,
|
||||||
|
ObjectID.GATE_14242,
|
||||||
|
ObjectID.GATE_14243,
|
||||||
|
ObjectID.GATE_14244,
|
||||||
|
ObjectID.GATE_14245,
|
||||||
|
ObjectID.GATE_14246,
|
||||||
|
ObjectID.GATE_14247,
|
||||||
|
ObjectID.GATE_14248
|
||||||
|
);
|
||||||
|
|
||||||
|
public static boolean isRepairableBarricadeId(int objectId)
|
||||||
|
{
|
||||||
|
return repairableBarricades.contains(objectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRepairableGateId(int objectId)
|
||||||
|
{
|
||||||
|
return repairableGates.contains(objectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRepairableId(int objectId)
|
||||||
|
{
|
||||||
|
return isRepairableBarricadeId(objectId) || isRepairableGateId(objectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||||
|
|
||||||
|
public class PointsInfoboxCounter extends Counter
|
||||||
|
{
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
|
||||||
|
PointsInfoboxCounter(BufferedImage image, PestControlPlugin plugin, int count)
|
||||||
|
{
|
||||||
|
super(image, plugin, count);
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -23,22 +24,39 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.pestcontrol;
|
package net.runelite.client.plugins.pestcontrol;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.Setter;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
@Getter
|
||||||
@ToString
|
@Setter
|
||||||
enum Portal
|
class Portal
|
||||||
{
|
{
|
||||||
PURPLE(WidgetInfo.PEST_CONTROL_PURPLE_SHIELD, WidgetInfo.PEST_CONTROL_PURPLE_HEALTH, WidgetInfo.PEST_CONTROL_PURPLE_ICON),
|
private PortalColor color;
|
||||||
BLUE(WidgetInfo.PEST_CONTROL_BLUE_SHIELD, WidgetInfo.PEST_CONTROL_BLUE_HEALTH, WidgetInfo.PEST_CONTROL_BLUE_ICON),
|
private WidgetPortal widget;
|
||||||
YELLOW(WidgetInfo.PEST_CONTROL_YELLOW_SHIELD, WidgetInfo.PEST_CONTROL_YELLOW_HEALTH, WidgetInfo.PEST_CONTROL_YELLOW_ICON),
|
private WorldPoint location;
|
||||||
RED(WidgetInfo.PEST_CONTROL_RED_SHIELD, WidgetInfo.PEST_CONTROL_RED_HEALTH, WidgetInfo.PEST_CONTROL_RED_ICON);
|
|
||||||
|
|
||||||
private final WidgetInfo shield;
|
private PortalState portalState = PortalState.SHIELDED;
|
||||||
private final WidgetInfo hitpoints;
|
|
||||||
private final WidgetInfo icon;
|
public Portal(PortalColor color, WidgetPortal widget)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
this.widget = widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShielded()
|
||||||
|
{
|
||||||
|
return portalState == PortalState.SHIELDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead()
|
||||||
|
{
|
||||||
|
return portalState == PortalState.DEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return (!isShielded() && !isDead());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2019, Yani <yani@xenokore.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -25,15 +25,12 @@
|
|||||||
package net.runelite.client.plugins.pestcontrol;
|
package net.runelite.client.plugins.pestcontrol;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
public enum PortalColor
|
||||||
class PortalContext
|
|
||||||
{
|
{
|
||||||
private final Portal portal;
|
BLUE,
|
||||||
private boolean isShielded = true;
|
PURPLE,
|
||||||
private boolean isDead;
|
YELLOW,
|
||||||
|
RED
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,12 +25,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.pestcontrol;
|
package net.runelite.client.plugins.pestcontrol;
|
||||||
|
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.BLUE;
|
import static net.runelite.client.plugins.pestcontrol.PortalColor.BLUE;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.PURPLE;
|
import static net.runelite.client.plugins.pestcontrol.PortalColor.PURPLE;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.RED;
|
import static net.runelite.client.plugins.pestcontrol.PortalColor.RED;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.YELLOW;
|
import static net.runelite.client.plugins.pestcontrol.PortalColor.YELLOW;
|
||||||
|
|
||||||
enum Rotation
|
enum PortalRotation
|
||||||
{
|
{
|
||||||
PBYR(PURPLE, BLUE, YELLOW, RED),
|
PBYR(PURPLE, BLUE, YELLOW, RED),
|
||||||
PYBR(PURPLE, YELLOW, BLUE, RED),
|
PYBR(PURPLE, YELLOW, BLUE, RED),
|
||||||
@@ -38,23 +39,23 @@ enum Rotation
|
|||||||
YRPB(YELLOW, RED, PURPLE, BLUE),
|
YRPB(YELLOW, RED, PURPLE, BLUE),
|
||||||
YPRB(YELLOW, PURPLE, RED, BLUE);
|
YPRB(YELLOW, PURPLE, RED, BLUE);
|
||||||
|
|
||||||
private final Portal[] portals;
|
private final PortalColor[] portals;
|
||||||
|
|
||||||
Rotation(Portal first, Portal second, Portal third, Portal fourth)
|
PortalRotation(PortalColor first, PortalColor second, PortalColor third, PortalColor fourth)
|
||||||
{
|
{
|
||||||
portals = new Portal[]
|
portals = new PortalColor[]
|
||||||
{
|
{
|
||||||
first, second, third, fourth
|
first, second, third, fourth
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Portal getPortal(int index)
|
public Portal getPortal(Game game, int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= portals.length)
|
if (index < 0 || index >= portals.length)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return portals[index];
|
return game.getPortal(portals[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
public enum PortalState
|
||||||
|
{
|
||||||
|
ACTIVE,
|
||||||
|
SHIELDED,
|
||||||
|
DEAD
|
||||||
|
}
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.awt.AlphaComposite;
|
||||||
|
import java.awt.Composite;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.Perspective;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.game.SkillIconManager;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class PortalWeaknessOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private int zOffset = 100;
|
||||||
|
|
||||||
|
private final PestControlConfig config;
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
private BufferedImage magicImage;
|
||||||
|
private BufferedImage rangedImage;
|
||||||
|
private BufferedImage stabImage;
|
||||||
|
private BufferedImage slashImage;
|
||||||
|
private BufferedImage crushImage;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PortalWeaknessOverlay(
|
||||||
|
PestControlConfig config,
|
||||||
|
PestControlPlugin plugin,
|
||||||
|
Client client,
|
||||||
|
ItemManager itemManager,
|
||||||
|
SkillIconManager skillIconManager
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
this.magicImage = skillIconManager.getSkillImage(Skill.MAGIC);
|
||||||
|
this.rangedImage = skillIconManager.getSkillImage(Skill.RANGED);
|
||||||
|
|
||||||
|
this.stabImage = itemManager.getImage(ItemID.WHITE_DAGGER);
|
||||||
|
this.slashImage = itemManager.getImage(ItemID.WHITE_SCIMITAR);
|
||||||
|
this.crushImage = itemManager.getImage(ItemID.WHITE_WARHAMMER);
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point getPortalPoint(Portal portal)
|
||||||
|
{
|
||||||
|
WorldPoint portalLocation = portal.getLocation();
|
||||||
|
LocalPoint localLocation = LocalPoint.fromWorld(client, portalLocation);
|
||||||
|
|
||||||
|
if (localLocation == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can use any image here as it's only needed to calculate the position
|
||||||
|
Point imageLocation = Perspective.getCanvasImageLocation(client, localLocation, magicImage, zOffset);
|
||||||
|
|
||||||
|
if (imageLocation != null)
|
||||||
|
{
|
||||||
|
return imageLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderPortalWeakness(Graphics2D graphics, Portal portal, BufferedImage image)
|
||||||
|
{
|
||||||
|
Point portalPoint = getPortalPoint(portal);
|
||||||
|
|
||||||
|
if (portalPoint != null)
|
||||||
|
{
|
||||||
|
Composite originalComposite = graphics.getComposite();
|
||||||
|
Composite translucentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
|
||||||
|
graphics.setComposite(translucentComposite);
|
||||||
|
|
||||||
|
OverlayUtil.renderImageLocation(graphics, portalPoint, image);
|
||||||
|
|
||||||
|
graphics.setComposite(originalComposite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderDoublePortalWeakness(
|
||||||
|
Graphics2D graphics,
|
||||||
|
Portal portal,
|
||||||
|
BufferedImage imageLeft,
|
||||||
|
BufferedImage imageRight
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Point portalPoint = getPortalPoint(portal);
|
||||||
|
|
||||||
|
if (portalPoint != null)
|
||||||
|
{
|
||||||
|
Point portalLeft = new Point(
|
||||||
|
portalPoint.getX() - (imageLeft.getWidth() / 2) - 5,
|
||||||
|
portalPoint.getY()
|
||||||
|
);
|
||||||
|
|
||||||
|
Point portalRight = new Point(
|
||||||
|
portalPoint.getX() + (imageRight.getWidth() / 2) + 5,
|
||||||
|
portalPoint.getY()
|
||||||
|
);
|
||||||
|
|
||||||
|
Composite originalComposite = graphics.getComposite();
|
||||||
|
Composite translucentComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f);
|
||||||
|
graphics.setComposite(translucentComposite);
|
||||||
|
|
||||||
|
OverlayUtil.renderImageLocation(graphics, portalLeft, imageLeft);
|
||||||
|
OverlayUtil.renderImageLocation(graphics, portalPoint, imageRight);
|
||||||
|
|
||||||
|
graphics.setComposite(originalComposite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
Game game = plugin.getGame();
|
||||||
|
|
||||||
|
if (game == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Portal portal : game.getPortals())
|
||||||
|
{
|
||||||
|
if (!portal.isDead())
|
||||||
|
{
|
||||||
|
switch (portal.getColor())
|
||||||
|
{
|
||||||
|
case BLUE:
|
||||||
|
{
|
||||||
|
renderPortalWeakness(graphics, portal, magicImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case YELLOW:
|
||||||
|
{
|
||||||
|
renderDoublePortalWeakness(graphics, portal, stabImage, slashImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RED:
|
||||||
|
{
|
||||||
|
renderPortalWeakness(graphics, portal, crushImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PURPLE:
|
||||||
|
{
|
||||||
|
renderPortalWeakness(graphics, portal, rangedImage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Area;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Constants;
|
||||||
|
import net.runelite.api.GameObject;
|
||||||
|
import net.runelite.api.GroundObject;
|
||||||
|
import net.runelite.api.Player;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Scene;
|
||||||
|
import net.runelite.api.Tile;
|
||||||
|
import net.runelite.api.WallObject;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
|
||||||
|
public class RepairOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final PestControlConfig config;
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
private static final int MAX_DISTANCE = 2400;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RepairOverlay(PestControlConfig config, PestControlPlugin plugin, Client client)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (plugin.getGame() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point mousePosition = client.getMouseCanvasPosition();
|
||||||
|
Scene scene = client.getScene();
|
||||||
|
Color color = config.repairableColor();
|
||||||
|
Tile[][][] tiles = scene.getTiles();
|
||||||
|
int z = client.getPlane();
|
||||||
|
|
||||||
|
for (int x = 0; x < Constants.SCENE_SIZE; ++x)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < Constants.SCENE_SIZE; ++y)
|
||||||
|
{
|
||||||
|
Tile tile = tiles[z][x][y];
|
||||||
|
|
||||||
|
if (tile == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = client.getLocalPlayer();
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render GameObjects
|
||||||
|
GameObject[] gameObjects = tile.getGameObjects();
|
||||||
|
if (gameObjects != null)
|
||||||
|
{
|
||||||
|
for (GameObject gameObject : gameObjects)
|
||||||
|
{
|
||||||
|
if (gameObject == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PestControlRepairObject.isRepairableId(gameObject.getId()))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (player.getLocalLocation().distanceTo(gameObject.getLocalLocation()) <= MAX_DISTANCE)
|
||||||
|
{
|
||||||
|
renderObjectOverlay(graphics, gameObject.getClickbox(), color, mousePosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render GameObject
|
||||||
|
GroundObject groundObject = tile.getGroundObject();
|
||||||
|
if (groundObject != null)
|
||||||
|
{
|
||||||
|
if (groundObject == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PestControlRepairObject.isRepairableId(groundObject.getId()))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (player.getLocalLocation().distanceTo(groundObject.getLocalLocation()) <= MAX_DISTANCE)
|
||||||
|
{
|
||||||
|
renderObjectOverlay(graphics, groundObject.getClickbox(), color, mousePosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render WallObject
|
||||||
|
WallObject wallObject = tile.getWallObject();
|
||||||
|
if (wallObject != null)
|
||||||
|
{
|
||||||
|
if (wallObject == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PestControlRepairObject.isRepairableId(wallObject.getId()))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (player.getLocalLocation().distanceTo(wallObject.getLocalLocation()) <= MAX_DISTANCE)
|
||||||
|
{
|
||||||
|
renderObjectOverlay(graphics, wallObject.getClickbox(), color, mousePosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*if(plugin.getGame() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point mousePosition = client.getMouseCanvasPosition();
|
||||||
|
|
||||||
|
List<TileObject> repairList = plugin.getHighlightedRepairList();
|
||||||
|
|
||||||
|
for(TileObject tileObject: repairList)
|
||||||
|
{
|
||||||
|
//tileObject.getWorldLocation().distanceTo(client.getLocalPlayer().getWorldLocation());
|
||||||
|
|
||||||
|
Polygon polygon = tileObject.getCanvasTilePoly();
|
||||||
|
|
||||||
|
if(polygon != null)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.drawPolygon(polygon);
|
||||||
|
graphics.setColor(setColorAlpha(color, 40));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
|
||||||
|
if(polygon.contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
graphics.setColor(setColorAlpha(color, 65));
|
||||||
|
graphics.fill(polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderObjectOverlay(Graphics2D graphics, Area area, Color color, Point mousePosition)
|
||||||
|
{
|
||||||
|
if (area == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.setColor(color);
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.draw(area);
|
||||||
|
graphics.setColor(setColorAlpha(color, 50));
|
||||||
|
graphics.fill(area);
|
||||||
|
|
||||||
|
if (area.contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
graphics.setColor(setColorAlpha(color, 60));
|
||||||
|
graphics.fill(area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color setColorAlpha(Color color, int alpha)
|
||||||
|
{
|
||||||
|
return new Color(
|
||||||
|
color.getRed(),
|
||||||
|
color.getGreen(),
|
||||||
|
color.getBlue(),
|
||||||
|
alpha
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.time.Duration;
|
||||||
|
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.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;
|
||||||
|
|
||||||
|
public class TimerOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private final PestControlConfig config;
|
||||||
|
private final PestControlPlugin plugin;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TimerOverlay(PestControlConfig config, PestControlPlugin plugin, Client client)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (plugin.getGame() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget timeWidget = client.getWidget(WidgetInfo.PEST_CONTROL_INFO_TIME);
|
||||||
|
|
||||||
|
if (timeWidget == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = timeWidget.getCanvasLocation().getX() + 38;
|
||||||
|
int y = timeWidget.getCanvasLocation().getY() + 11;
|
||||||
|
|
||||||
|
Duration timeTillNextPortal = plugin.getGame().getTimeTillNextPortal();
|
||||||
|
|
||||||
|
if (timeTillNextPortal != null)
|
||||||
|
{
|
||||||
|
String firstOrNext = (plugin.getGame().getShieldsDropped() == 0) ? "first" : "next";
|
||||||
|
String string = String.format("- %s portal: %ds", firstOrNext, timeTillNextPortal.getSeconds());
|
||||||
|
|
||||||
|
OverlayUtil.renderTextLocation(graphics, new Point(x, y), string, new Color(204, 204, 204));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Kronos <https://github.com/KronosDesign>
|
* Copyright (c) 2017, Kronos <https://github.com/KronosDesign>
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -31,151 +32,107 @@ import java.awt.FontMetrics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.BLUE;
|
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.PURPLE;
|
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.RED;
|
|
||||||
import static net.runelite.client.plugins.pestcontrol.Portal.YELLOW;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
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.OverlayPosition;
|
||||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PestControlOverlay extends Overlay
|
public class WidgetOverlay extends Overlay
|
||||||
{
|
{
|
||||||
private final PestControlPlugin plugin;
|
|
||||||
private final Client client;
|
private final Client client;
|
||||||
|
|
||||||
// Pest control game
|
private final PestControlPlugin plugin;
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private Game game;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PestControlOverlay(PestControlPlugin plugin, Client client)
|
public WidgetOverlay(Client client, PestControlPlugin plugin)
|
||||||
{
|
{
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPortalHitpoints(PortalColor color)
|
||||||
|
{
|
||||||
|
if (plugin.getGame() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetInfo healthWidgetInfo = null;
|
||||||
|
|
||||||
|
switch (color)
|
||||||
|
{
|
||||||
|
case RED:
|
||||||
|
{
|
||||||
|
healthWidgetInfo = WidgetPortal.RED.getHitpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BLUE:
|
||||||
|
{
|
||||||
|
healthWidgetInfo = WidgetPortal.BLUE.getHitpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PURPLE:
|
||||||
|
{
|
||||||
|
healthWidgetInfo = WidgetPortal.PURPLE.getHitpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case YELLOW:
|
||||||
|
{
|
||||||
|
healthWidgetInfo = WidgetPortal.YELLOW.getHitpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (healthWidgetInfo == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget healthWidget = client.getWidget(healthWidgetInfo);
|
||||||
|
|
||||||
|
if (healthWidget == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.parseInt(healthWidget.getText().trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
// See if we are in a game or not
|
if (plugin.getGame() == null)
|
||||||
if (client.getWidget(WidgetInfo.PEST_CONTROL_BLUE_SHIELD) == null)
|
|
||||||
{
|
{
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
log.debug("Pest control game has ended");
|
|
||||||
game = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game == null)
|
for (Portal portal : plugin.getGame().getNextPortals())
|
||||||
{
|
|
||||||
log.debug("Pest control game has started");
|
|
||||||
game = new Game();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSpinners(graphics);
|
|
||||||
renderPortalWidgets(graphics);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderSpinners(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
for (NPC npc : plugin.getSpinners())
|
|
||||||
{
|
|
||||||
OverlayUtil.renderActorOverlay(graphics, npc, npc.getName(), Color.CYAN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderPortalWidgets(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
PortalContext purple = game.getPurple();
|
|
||||||
PortalContext blue = game.getBlue();
|
|
||||||
PortalContext yellow = game.getYellow();
|
|
||||||
PortalContext red = game.getRed();
|
|
||||||
|
|
||||||
Widget purpleHealth = client.getWidget(PURPLE.getHitpoints());
|
|
||||||
Widget blueHealth = client.getWidget(BLUE.getHitpoints());
|
|
||||||
Widget yellowHealth = client.getWidget(YELLOW.getHitpoints());
|
|
||||||
Widget redHealth = client.getWidget(RED.getHitpoints());
|
|
||||||
|
|
||||||
// Check for dead portals
|
|
||||||
if (isZero(purpleHealth))
|
|
||||||
{
|
|
||||||
game.die(purple);
|
|
||||||
}
|
|
||||||
if (isZero(blueHealth))
|
|
||||||
{
|
|
||||||
game.die(blue);
|
|
||||||
}
|
|
||||||
if (isZero(yellowHealth))
|
|
||||||
{
|
|
||||||
game.die(yellow);
|
|
||||||
}
|
|
||||||
if (isZero(redHealth))
|
|
||||||
{
|
|
||||||
game.die(red);
|
|
||||||
}
|
|
||||||
|
|
||||||
// display "ATK" overlay on recorded portals without shields
|
|
||||||
renderAttack(graphics, purple);
|
|
||||||
renderAttack(graphics, blue);
|
|
||||||
renderAttack(graphics, yellow);
|
|
||||||
renderAttack(graphics, red);
|
|
||||||
|
|
||||||
// display "NEXT" overlay on predicted portals
|
|
||||||
for (Portal portal : game.getNextPortals())
|
|
||||||
{
|
{
|
||||||
renderWidgetOverlay(graphics, portal, "NEXT", Color.ORANGE);
|
renderWidgetOverlay(graphics, portal, "NEXT", Color.ORANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderProgressWidget(graphics);
|
for (Portal portal : plugin.getGame().getActivePortals())
|
||||||
}
|
|
||||||
|
|
||||||
private void renderProgressWidget(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0);
|
|
||||||
Rectangle2D bounds = bar.getBounds().getBounds2D();
|
|
||||||
|
|
||||||
Widget prgs = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_PROGRESS).getChild(0);
|
|
||||||
int perc = (int) ((prgs.getBounds().getWidth() / bounds.getWidth()) * 100);
|
|
||||||
|
|
||||||
Color color = Color.GREEN;
|
|
||||||
if (perc < 25)
|
|
||||||
{
|
{
|
||||||
color = Color.RED;
|
renderWidgetOverlay(graphics, portal, "ATT", Color.RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
String text = String.valueOf(perc) + "%";
|
renderProgressWidget(graphics);
|
||||||
|
|
||||||
FontMetrics fm = graphics.getFontMetrics();
|
return null;
|
||||||
Rectangle2D textBounds = fm.getStringBounds(text, graphics);
|
|
||||||
int x = (int) (bounds.getX() - textBounds.getWidth());
|
|
||||||
int y = (int) (bounds.getY() + fm.getHeight() - 2);
|
|
||||||
|
|
||||||
graphics.setColor(Color.BLACK);
|
|
||||||
graphics.drawString(text, x + 1, y + 1);
|
|
||||||
graphics.setColor(color);
|
|
||||||
graphics.drawString(text, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderWidgetOverlay(Graphics2D graphics, Portal portal, String text, Color color)
|
private void renderWidgetOverlay(Graphics2D graphics, Portal portal, String text, Color color)
|
||||||
{
|
{
|
||||||
Widget shield = client.getWidget(portal.getShield());
|
Widget shield = client.getWidget(portal.getWidget().getShield());
|
||||||
Widget icon = client.getWidget(portal.getIcon());
|
Widget icon = client.getWidget(portal.getWidget().getIcon());
|
||||||
Widget hp = client.getWidget(portal.getHitpoints());
|
Widget hp = client.getWidget(portal.getWidget().getHitpoints());
|
||||||
|
|
||||||
Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0);
|
Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0);
|
||||||
|
|
||||||
@@ -199,6 +156,45 @@ public class PestControlOverlay extends Overlay
|
|||||||
graphics.drawString(text, x, y + 4);
|
graphics.drawString(text, x, y + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderProgressWidget(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
String text;
|
||||||
|
int percentage;
|
||||||
|
|
||||||
|
Widget bar = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_BAR).getChild(0);
|
||||||
|
Rectangle2D bounds = bar.getBounds().getBounds2D();
|
||||||
|
|
||||||
|
Widget prgs = client.getWidget(WidgetInfo.PEST_CONTROL_ACTIVITY_PROGRESS).getChild(0);
|
||||||
|
|
||||||
|
// At 0% the inner widget changes and your progress will not increase anymore
|
||||||
|
if ((int) (prgs.getBounds().getX()) - bounds.getX() != 2)
|
||||||
|
{
|
||||||
|
percentage = 0;
|
||||||
|
text = "FAILED";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
percentage = (int) ((prgs.getBounds().getWidth() / bounds.getWidth()) * 100);
|
||||||
|
text = String.valueOf(percentage) + "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
Color color = Color.GREEN;
|
||||||
|
if (percentage < 25)
|
||||||
|
{
|
||||||
|
color = Color.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
FontMetrics fm = graphics.getFontMetrics();
|
||||||
|
Rectangle2D textBounds = fm.getStringBounds(text, graphics);
|
||||||
|
int x = (int) (bounds.getX() - textBounds.getWidth() - 4);
|
||||||
|
int y = (int) (bounds.getY() + fm.getHeight() - 2);
|
||||||
|
|
||||||
|
graphics.setColor(Color.BLACK);
|
||||||
|
graphics.drawString(text, x + 1, y + 1);
|
||||||
|
graphics.setColor(color);
|
||||||
|
graphics.drawString(text, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
private static Rectangle2D union(Rectangle2D src1, Rectangle2D src2)
|
private static Rectangle2D union(Rectangle2D src1, Rectangle2D src2)
|
||||||
{
|
{
|
||||||
double x1 = Math.min(src1.getMinX(), src2.getMinX());
|
double x1 = Math.min(src1.getMinX(), src2.getMinX());
|
||||||
@@ -211,19 +207,4 @@ public class PestControlOverlay extends Overlay
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderAttack(Graphics2D graphics, PortalContext portal)
|
|
||||||
{
|
|
||||||
if (portal.isShielded() || portal.isDead())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderWidgetOverlay(graphics, portal.getPortal(), "ATK", Color.RED);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isZero(Widget widget)
|
|
||||||
{
|
|
||||||
return widget.getText().trim().equals("0");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.pestcontrol;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
enum WidgetPortal
|
||||||
|
{
|
||||||
|
PURPLE(WidgetInfo.PEST_CONTROL_PURPLE_SHIELD, WidgetInfo.PEST_CONTROL_PURPLE_HEALTH, WidgetInfo.PEST_CONTROL_PURPLE_ICON),
|
||||||
|
BLUE(WidgetInfo.PEST_CONTROL_BLUE_SHIELD, WidgetInfo.PEST_CONTROL_BLUE_HEALTH, WidgetInfo.PEST_CONTROL_BLUE_ICON),
|
||||||
|
YELLOW(WidgetInfo.PEST_CONTROL_YELLOW_SHIELD, WidgetInfo.PEST_CONTROL_YELLOW_HEALTH, WidgetInfo.PEST_CONTROL_YELLOW_ICON),
|
||||||
|
RED(WidgetInfo.PEST_CONTROL_RED_SHIELD, WidgetInfo.PEST_CONTROL_RED_HEALTH, WidgetInfo.PEST_CONTROL_RED_ICON);
|
||||||
|
|
||||||
|
private final WidgetInfo shield;
|
||||||
|
private final WidgetInfo hitpoints;
|
||||||
|
private final WidgetInfo icon;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum HighlightPortalOption
|
||||||
|
{
|
||||||
|
OFF("Off"),
|
||||||
|
ACTIVE("Active"),
|
||||||
|
SHIELDED("Shielded"),
|
||||||
|
ALL("All");
|
||||||
|
|
||||||
|
private final String option;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Yani <yani@xenokore.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.pestcontrol.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum NpcHighlightStyle
|
||||||
|
{
|
||||||
|
OFF("Off"),
|
||||||
|
TILE("Tile"),
|
||||||
|
HULL("Hull"),
|
||||||
|
BOTH("Hull + Tile");
|
||||||
|
|
||||||
|
private final String style;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,6 +59,9 @@ import net.runelite.api.Varbits;
|
|||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.VarbitChanged;
|
import net.runelite.api.events.VarbitChanged;
|
||||||
|
import net.runelite.api.events.WidgetHiddenChanged;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import net.runelite.client.callback.ClientThread;
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.chat.ChatColorType;
|
import net.runelite.client.chat.ChatColorType;
|
||||||
import net.runelite.client.chat.ChatMessageBuilder;
|
import net.runelite.client.chat.ChatMessageBuilder;
|
||||||
@@ -126,6 +129,9 @@ public class RaidsPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private RaidsOverlay overlay;
|
private RaidsOverlay overlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RaidsPointsOverlay pointsOverlay;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private LayoutSolver layoutSolver;
|
private LayoutSolver layoutSolver;
|
||||||
|
|
||||||
@@ -177,6 +183,7 @@ public class RaidsPlugin extends Plugin
|
|||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
overlayManager.add(overlay);
|
overlayManager.add(overlay);
|
||||||
|
overlayManager.add(pointsOverlay);
|
||||||
updateLists();
|
updateLists();
|
||||||
clientThread.invokeLater(() -> checkRaidPresence(true));
|
clientThread.invokeLater(() -> checkRaidPresence(true));
|
||||||
}
|
}
|
||||||
@@ -185,10 +192,17 @@ public class RaidsPlugin extends Plugin
|
|||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
overlayManager.remove(overlay);
|
overlayManager.remove(overlay);
|
||||||
|
overlayManager.remove(pointsOverlay);
|
||||||
infoBoxManager.removeInfoBox(timer);
|
infoBoxManager.removeInfoBox(timer);
|
||||||
inRaidChambers = false;
|
inRaidChambers = false;
|
||||||
raid = null;
|
raid = null;
|
||||||
timer = null;
|
timer = null;
|
||||||
|
|
||||||
|
final Widget widget = client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX);
|
||||||
|
if (widget != null)
|
||||||
|
{
|
||||||
|
widget.setHidden(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -209,6 +223,22 @@ public class RaidsPlugin extends Plugin
|
|||||||
clientThread.invokeLater(() -> checkRaidPresence(true));
|
clientThread.invokeLater(() -> checkRaidPresence(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onWidgetHiddenChanged(WidgetHiddenChanged event)
|
||||||
|
{
|
||||||
|
if (!inRaidChambers || event.isHidden())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget widget = event.getWidget();
|
||||||
|
|
||||||
|
if (widget == client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX))
|
||||||
|
{
|
||||||
|
widget.setHidden(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onVarbitChanged(VarbitChanged event)
|
public void onVarbitChanged(VarbitChanged event)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Kamiel
|
||||||
|
* 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.raids;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import static net.runelite.client.plugins.raids.RaidsPlugin.POINTS_FORMAT;
|
||||||
|
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.LineComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
|
||||||
|
public class RaidsPointsOverlay extends Overlay
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RaidsPlugin plugin;
|
||||||
|
|
||||||
|
private final PanelComponent panel = new PanelComponent();
|
||||||
|
|
||||||
|
private static final NumberFormat UNIQUE_FORMAT = NumberFormat.getPercentInstance(Locale.ENGLISH);
|
||||||
|
static
|
||||||
|
{
|
||||||
|
UNIQUE_FORMAT.setMaximumFractionDigits(2);
|
||||||
|
UNIQUE_FORMAT.setMinimumFractionDigits(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RaidsPointsOverlay(RaidsPlugin plugin)
|
||||||
|
{
|
||||||
|
super(plugin);
|
||||||
|
setPosition(OverlayPosition.TOP_RIGHT);
|
||||||
|
setPriority(OverlayPriority.HIGH);
|
||||||
|
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Raids overlay"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (!plugin.isInRaidChambers())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalPoints = client.getVar(Varbits.TOTAL_POINTS);
|
||||||
|
int personalPoints = client.getVar(Varbits.PERSONAL_POINTS);
|
||||||
|
int partySize = client.getVar(Varbits.RAID_PARTY_SIZE);
|
||||||
|
double uniqueChance = totalPoints / 867500f;
|
||||||
|
|
||||||
|
panel.getChildren().clear();
|
||||||
|
panel.getChildren().add(LineComponent.builder()
|
||||||
|
.left("Total:")
|
||||||
|
.right(POINTS_FORMAT.format(totalPoints))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
panel.getChildren().add(LineComponent.builder()
|
||||||
|
.left(client.getLocalPlayer().getName() + ":")
|
||||||
|
.right(POINTS_FORMAT.format(personalPoints))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
|
||||||
|
if (partySize > 1)
|
||||||
|
{
|
||||||
|
panel.getChildren().add(LineComponent.builder()
|
||||||
|
.left("Party size:")
|
||||||
|
.right(String.valueOf(partySize))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.getChildren().add(LineComponent.builder()
|
||||||
|
.left("Unique:")
|
||||||
|
.right(UNIQUE_FORMAT.format(uniqueChance))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
if (partySize > 1)
|
||||||
|
{
|
||||||
|
double personalChance = uniqueChance * (personalPoints / totalPoints);
|
||||||
|
|
||||||
|
panel.getChildren().add(LineComponent.builder()
|
||||||
|
.left("Personal:")
|
||||||
|
.right(UNIQUE_FORMAT.format(personalChance))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel.render(graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 179 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.testing.fieldbinder.Bind;
|
||||||
|
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.testconfig.MagicMaxHitConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.testconfig.MaxHitConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.testconfig.MeleeMaxHitConfig;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.testconfig.RangeMaxHitConfig;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class MaxHitCalculatorTest
|
||||||
|
{
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
protected Client client;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp()
|
||||||
|
{
|
||||||
|
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void calculate()
|
||||||
|
{
|
||||||
|
testMaxHitConfig(MeleeMaxHitConfig.values());
|
||||||
|
testMaxHitConfig(RangeMaxHitConfig.values());
|
||||||
|
testMaxHitConfig(MagicMaxHitConfig.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testMaxHitConfig(MaxHitConfig[] maxHitConfigs)
|
||||||
|
{
|
||||||
|
for (MaxHitConfig maxHitConfig : maxHitConfigs)
|
||||||
|
{
|
||||||
|
maxHitConfig.test(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators.testconfig;
|
||||||
|
|
||||||
|
import net.runelite.api.*;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MagicMaxHitCalculator;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public enum MagicMaxHitConfig implements MaxHitConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
TRIDENT_SLAYER(new int[] {75, 83, 99}, 0, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.SLAYER_HELMET_I),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.OCCULT_NECKLACE),
|
||||||
|
mockItem(ItemID.TRIDENT_OF_THE_SEAS),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, new int[] {25, 27, 34}),
|
||||||
|
|
||||||
|
TRIDENT_OF_SEAS(new int[] {75, 83, 99}, 0, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_GLORY),
|
||||||
|
mockItem(ItemID.TRIDENT_OF_THE_SEAS),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, new int[] {20, 22, 28}),
|
||||||
|
|
||||||
|
TRIDENT_OF_SWAMP(new int[] {75, 83, 99}, 0, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_GLORY),
|
||||||
|
mockItem(ItemID.TRIDENT_OF_THE_SWAMP),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, new int[] {23, 25, 31}),
|
||||||
|
|
||||||
|
MAGIC_DART(new int[] {75, 83, 99}, 18, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_GLORY),
|
||||||
|
mockItem(ItemID.SLAYERS_STAFF),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, new int[] {17, 18, 19}),
|
||||||
|
|
||||||
|
|
||||||
|
FIRE_BOLT(75, 8, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.SLAYER_HELMET_I),
|
||||||
|
mockItem(ItemID.IMBUED_SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.OCCULT_NECKLACE),
|
||||||
|
mockItem(ItemID.STAFF_OF_THE_DEAD),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.TOME_OF_FIRE),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.CHAOS_GAUNTLETS),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, 31),
|
||||||
|
|
||||||
|
|
||||||
|
WIND_BLAST(75, 9, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_GLORY),
|
||||||
|
mockItem(ItemID.STAFF_OF_AIR),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, 13),
|
||||||
|
|
||||||
|
|
||||||
|
EARTH_WAVE(75, 15, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.OCCULT_NECKLACE),
|
||||||
|
mockItem(ItemID.STAFF_OF_EARTH),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.TOME_OF_FIRE),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, 20),
|
||||||
|
|
||||||
|
FLAMES_OF_ZAMORAK(75, 20, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_GLORY),
|
||||||
|
mockItem(ItemID.STAFF_OF_THE_DEAD),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, 23),
|
||||||
|
|
||||||
|
SARADOMIN_STRIKE(75, 52, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.MYSTIC_HAT),
|
||||||
|
mockItem(ItemID.SARADOMIN_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_GLORY),
|
||||||
|
mockItem(ItemID.STAFF_OF_LIGHT),
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_TOP),
|
||||||
|
mockItem(ItemID.BROODOO_SHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_ROBE_BOTTOM),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.MYSTIC_GLOVES),
|
||||||
|
mockItem(ItemID.WIZARD_BOOTS),
|
||||||
|
mockItem(ItemID.RING_OF_WEALTH)
|
||||||
|
}, 23),
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
private final int[] magicLevels;
|
||||||
|
private final int spellId;
|
||||||
|
private final Item[] equipedItems;
|
||||||
|
private final int[] expectedMaxHits;
|
||||||
|
|
||||||
|
MagicMaxHitConfig(int magicLevel, int spellId, Item[] equipedItems, int expectedMaxHit)
|
||||||
|
{
|
||||||
|
this.magicLevels = new int[] {magicLevel};
|
||||||
|
this.spellId = spellId;
|
||||||
|
this.equipedItems = equipedItems;
|
||||||
|
this.expectedMaxHits = new int[] {expectedMaxHit};
|
||||||
|
}
|
||||||
|
|
||||||
|
MagicMaxHitConfig(int[] magicLevels, int spellId, Item[] equipedItems, int[] expectedMaxHits)
|
||||||
|
{
|
||||||
|
this.magicLevels = magicLevels;
|
||||||
|
this.spellId = spellId;
|
||||||
|
this.equipedItems = equipedItems;
|
||||||
|
this.expectedMaxHits = expectedMaxHits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Item mockItem(int itemId)
|
||||||
|
{
|
||||||
|
Item item = mock(Item.class);
|
||||||
|
when(item.getId()).thenReturn(itemId);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test(Client client)
|
||||||
|
{
|
||||||
|
int[] magicLevels = this.magicLevels;
|
||||||
|
for (int i = 0, magicLevelsLength = magicLevels.length; i < magicLevelsLength; i++)
|
||||||
|
{
|
||||||
|
int magicLevel = magicLevels[i];
|
||||||
|
int expectedMaxHit = this.expectedMaxHits[i];
|
||||||
|
|
||||||
|
// Mock equipment container
|
||||||
|
ItemContainer equipmentContainer = mock(ItemContainer.class);
|
||||||
|
when(equipmentContainer.getItems())
|
||||||
|
.thenReturn(this.equipedItems);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipmentContainer);
|
||||||
|
|
||||||
|
// Mock Varbits
|
||||||
|
when(client.getBoostedSkillLevel(Skill.MAGIC)).thenReturn(magicLevel);
|
||||||
|
when(client.getVar(Varbits.AUTO_CAST_SPELL)).thenReturn(this.spellId);
|
||||||
|
|
||||||
|
// Test
|
||||||
|
MagicMaxHitCalculator maxHitCalculator = new MagicMaxHitCalculator(client, this.equipedItems);
|
||||||
|
assertEquals(this.toString(), expectedMaxHit, maxHitCalculator.getMaxHit(), 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators.testconfig;
|
||||||
|
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
|
||||||
|
public interface MaxHitConfig
|
||||||
|
{
|
||||||
|
void test(Client client);
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators.testconfig;
|
||||||
|
|
||||||
|
import net.runelite.api.*;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.plugins.maxhit.attackstyle.WeaponType;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.MeleeMaxHitCalculator;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public enum MeleeMaxHitConfig implements MaxHitConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
DRAGON_SCIMITAR(new int[] {75, 83, 99}, 66, WeaponType.TYPE_9, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.IRON_FULL_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.DRAGON_SCIMITAR),
|
||||||
|
mockItem(ItemID.IRON_PLATEBODY),
|
||||||
|
mockItem(ItemID.IRON_KITESHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.IRON_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {17, 19, 22}),
|
||||||
|
|
||||||
|
DRAGON_SCIMITAR_DEFENDER(new int[] {75, 83, 99}, 76, WeaponType.TYPE_9, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.IRON_FULL_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.DRAGON_SCIMITAR),
|
||||||
|
mockItem(ItemID.IRON_PLATEBODY),
|
||||||
|
mockItem(ItemID.DRAGON_DEFENDER),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.IRON_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {19, 21, 24}),
|
||||||
|
|
||||||
|
DRAGON_SCIMITAR_COMPLETE(new int[] {75, 83, 99}, 108, WeaponType.TYPE_9, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.SLAYER_HELMET),
|
||||||
|
mockItem(ItemID.FIRE_CAPE),
|
||||||
|
mockItem(ItemID.AMULET_OF_FURY),
|
||||||
|
mockItem(ItemID.DRAGON_SCIMITAR),
|
||||||
|
mockItem(ItemID.FIGHTER_TORSO),
|
||||||
|
mockItem(ItemID.DRAGON_DEFENDER),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.IRON_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.BARROWS_GLOVES),
|
||||||
|
mockItem(ItemID.DRAGON_BOOTS),
|
||||||
|
mockItem(ItemID.BERSERKER_RING)
|
||||||
|
}, new int[] {26, 29, 35}),
|
||||||
|
|
||||||
|
OBSIDIAN_SET(new int[] {75, 83, 99}, 61, WeaponType.TYPE_17, 2, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.OBSIDIAN_HELMET),
|
||||||
|
mockItem(ItemID.OBSIDIAN_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.TOKTZXILAK),
|
||||||
|
mockItem(ItemID.OBSIDIAN_PLATEBODY),
|
||||||
|
mockItem(ItemID.TOKTZKETXIL),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.OBSIDIAN_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {18, 19, 23}),
|
||||||
|
|
||||||
|
DHAROK_SET(new int[] {75, 75, 75, 83, 83, 83, 99, 99, 99}, 105, WeaponType.TYPE_1, 1,
|
||||||
|
new int[][] {{99, 99}, {1, 99}, {32, 75}, {99, 99}, {1, 99}, {32, 75}, {99, 99}, {1, 99}, {32, 75}},
|
||||||
|
new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.DHAROKS_HELM_100),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.DHAROKS_GREATAXE_100),
|
||||||
|
mockItem(ItemID.DHAROKS_PLATEBODY_100),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.DHAROKS_PLATELEGS_100),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {23, 45, 30, 25, 49, 33, 29, 57, 38}),
|
||||||
|
|
||||||
|
VOID_SET(new int[] {75, 83, 99}, 66, WeaponType.TYPE_9, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.VOID_MELEE_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.DRAGON_SCIMITAR),
|
||||||
|
mockItem(ItemID.VOID_KNIGHT_TOP),
|
||||||
|
mockItem(ItemID.IRON_KITESHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.VOID_KNIGHT_ROBE),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.VOID_KNIGHT_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {19, 21, 25}),
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
private final int[] strengthLevels;
|
||||||
|
private final WeaponType weaponType;
|
||||||
|
private final int attackStyleId;
|
||||||
|
private final Item[] equipedItems;
|
||||||
|
private final int[] expectedMaxHits;
|
||||||
|
private final int[][] hitpoints;
|
||||||
|
private final int meleeEquipmentStrength;
|
||||||
|
|
||||||
|
MeleeMaxHitConfig(int[] strengthLevels, int meleeEquipmentStrength, WeaponType weaponType, int attackStyleId, int[][] hitpoints, Item[] equipedItems, int[] expectedMaxHits)
|
||||||
|
{
|
||||||
|
this.strengthLevels = strengthLevels;
|
||||||
|
this.meleeEquipmentStrength = meleeEquipmentStrength;
|
||||||
|
this.weaponType = weaponType;
|
||||||
|
this.attackStyleId = attackStyleId;
|
||||||
|
this.hitpoints = hitpoints;
|
||||||
|
this.equipedItems = equipedItems;
|
||||||
|
this.expectedMaxHits = expectedMaxHits;
|
||||||
|
}
|
||||||
|
|
||||||
|
MeleeMaxHitConfig(int[] strengthLevels, int meleeEquipmentStrength, WeaponType weaponType, int attackStyleId, Item[] equipedItems, int[] expectedMaxHits)
|
||||||
|
{
|
||||||
|
this.strengthLevels = strengthLevels;
|
||||||
|
this.hitpoints = new int[strengthLevels.length][2];
|
||||||
|
this.meleeEquipmentStrength = meleeEquipmentStrength;
|
||||||
|
this.weaponType = weaponType;
|
||||||
|
this.attackStyleId = attackStyleId;
|
||||||
|
this.equipedItems = equipedItems;
|
||||||
|
this.expectedMaxHits = expectedMaxHits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Item mockItem(int itemId)
|
||||||
|
{
|
||||||
|
Item item = mock(Item.class);
|
||||||
|
when(item.getId()).thenReturn(itemId);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test(Client client)
|
||||||
|
{
|
||||||
|
int[] strengthLevels = this.strengthLevels;
|
||||||
|
for (int i = 0, strengthLevelsLength = strengthLevels.length; i < strengthLevelsLength; i++)
|
||||||
|
{
|
||||||
|
int strengthLevel = strengthLevels[i];
|
||||||
|
int[] hitpoints = this.hitpoints[i];
|
||||||
|
int expectedMaxHit = this.expectedMaxHits[i];
|
||||||
|
|
||||||
|
// Mock equipment container
|
||||||
|
ItemContainer equipmentContainer = mock(ItemContainer.class);
|
||||||
|
when(equipmentContainer.getItems())
|
||||||
|
.thenReturn(this.equipedItems);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipmentContainer);
|
||||||
|
|
||||||
|
// Mock equipment strength
|
||||||
|
Widget equipmentWidget = mock(Widget.class);
|
||||||
|
when(client.getWidget(WidgetInfo.EQUIPMENT_MELEE_STRENGTH)).thenReturn(equipmentWidget);
|
||||||
|
when(equipmentWidget.getText()).thenReturn("Melee strength: " + this.meleeEquipmentStrength);
|
||||||
|
|
||||||
|
// Mock Varbits
|
||||||
|
when(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)).thenReturn(this.weaponType.ordinal());
|
||||||
|
when(client.getVar(VarPlayer.ATTACK_STYLE)).thenReturn(this.attackStyleId);
|
||||||
|
|
||||||
|
// Mock strength
|
||||||
|
when(client.getBoostedSkillLevel(Skill.STRENGTH)).thenReturn(strengthLevel);
|
||||||
|
|
||||||
|
// Mock hitpoints
|
||||||
|
when(client.getBoostedSkillLevel(Skill.HITPOINTS)).thenReturn(hitpoints[0]);
|
||||||
|
when(client.getRealSkillLevel(Skill.HITPOINTS)).thenReturn(hitpoints[1]);
|
||||||
|
|
||||||
|
// Test
|
||||||
|
MeleeMaxHitCalculator maxHitCalculator = new MeleeMaxHitCalculator(client, this.equipedItems);
|
||||||
|
assertEquals(this.toString(), expectedMaxHit, maxHitCalculator.getMaxHit(), 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Bartvollebregt <https://github.com/Bartvollebregt>
|
||||||
|
* 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.maxhit.calculators.testconfig;
|
||||||
|
|
||||||
|
import net.runelite.api.*;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.plugins.maxhit.attackstyle.WeaponType;
|
||||||
|
import net.runelite.client.plugins.maxhit.calculators.RangeMaxHitCalculator;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public enum RangeMaxHitConfig implements MaxHitConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
MAGIC_SHORTBOW(new int[] {75, 83, 99}, 49, WeaponType.TYPE_3, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.IRON_FULL_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.MAGIC_SHORTBOW),
|
||||||
|
mockItem(ItemID.IRON_PLATEBODY),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.IRON_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING),
|
||||||
|
mockItem(ItemID.RUNE_ARROW)
|
||||||
|
}, new int[] {15, 16, 19}),
|
||||||
|
|
||||||
|
RUNE_CROSSBOW(new int[] {75, 83, 99}, 115, WeaponType.TYPE_5, 0, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.IRON_FULL_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.RUNE_CROSSBOW),
|
||||||
|
mockItem(ItemID.IRON_PLATEBODY),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.IRON_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING),
|
||||||
|
mockItem(ItemID.RUNITE_BOLTS)
|
||||||
|
}, new int[] {24, 26, 31}),
|
||||||
|
|
||||||
|
BLOwPIPE(new int[] {75, 83, 99}, 50, WeaponType.TYPE_19, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.IRON_FULL_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.TOXIC_BLOWPIPE),
|
||||||
|
mockItem(ItemID.IRON_PLATEBODY),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.IRON_PLATELEGS),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.LEATHER_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {15, 16, 19}),
|
||||||
|
|
||||||
|
VOID_SET(new int[] {75, 83, 99}, 115, WeaponType.TYPE_5, 1, new Item[]
|
||||||
|
{
|
||||||
|
mockItem(ItemID.VOID_RANGER_HELM),
|
||||||
|
mockItem(ItemID.BLACK_CAPE),
|
||||||
|
mockItem(ItemID.GOLD_NECKLACE),
|
||||||
|
mockItem(ItemID.RUNE_CROSSBOW),
|
||||||
|
mockItem(ItemID.VOID_KNIGHT_TOP),
|
||||||
|
mockItem(ItemID.IRON_KITESHIELD),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.VOID_KNIGHT_ROBE),
|
||||||
|
null,
|
||||||
|
mockItem(ItemID.VOID_KNIGHT_GLOVES),
|
||||||
|
mockItem(ItemID.LEATHER_BOOTS),
|
||||||
|
mockItem(ItemID.GOLD_RING)
|
||||||
|
}, new int[] {26, 28, 33}),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int[] rangeLevels;
|
||||||
|
private final WeaponType weaponType;
|
||||||
|
private final int attackStyleId;
|
||||||
|
private final Item[] equipedItems;
|
||||||
|
private final int[] expectedMaxHits;
|
||||||
|
private final int ammoEquipmentStrength;
|
||||||
|
|
||||||
|
RangeMaxHitConfig(int[] rangeLevels, int ammoEquipmentStrength, WeaponType weaponType, int attackStyleId, Item[] equipedItems, int[] expectedMaxHits)
|
||||||
|
{
|
||||||
|
this.rangeLevels = rangeLevels;
|
||||||
|
this.ammoEquipmentStrength = ammoEquipmentStrength;
|
||||||
|
this.weaponType = weaponType;
|
||||||
|
this.attackStyleId = attackStyleId;
|
||||||
|
this.equipedItems = equipedItems;
|
||||||
|
this.expectedMaxHits = expectedMaxHits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Item mockItem(int itemId)
|
||||||
|
{
|
||||||
|
Item item = mock(Item.class);
|
||||||
|
when(item.getId()).thenReturn(itemId);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test(Client client)
|
||||||
|
{
|
||||||
|
int[] rangeLevels = this.rangeLevels;
|
||||||
|
for (int i = 0, rangeLevelsLength = rangeLevels.length; i < rangeLevelsLength; i++)
|
||||||
|
{
|
||||||
|
int rangeLevel = rangeLevels[i];
|
||||||
|
int expectedMaxHit = this.expectedMaxHits[i];
|
||||||
|
|
||||||
|
// Mock equipment container
|
||||||
|
ItemContainer equipmentContainer = mock(ItemContainer.class);
|
||||||
|
when(equipmentContainer.getItems())
|
||||||
|
.thenReturn(this.equipedItems);
|
||||||
|
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipmentContainer);
|
||||||
|
|
||||||
|
// Mock equipment strength
|
||||||
|
Widget equipmentWidget = mock(Widget.class);
|
||||||
|
when(client.getWidget(WidgetInfo.EQUIPMENT_RANGED_STRENGTH)).thenReturn(equipmentWidget);
|
||||||
|
when(equipmentWidget.getText()).thenReturn("Ranged strength: " + this.ammoEquipmentStrength);
|
||||||
|
|
||||||
|
// Mock Varbits
|
||||||
|
when(client.getVar(Varbits.EQUIPPED_WEAPON_TYPE)).thenReturn(this.weaponType.ordinal());
|
||||||
|
when(client.getVar(VarPlayer.ATTACK_STYLE)).thenReturn(this.attackStyleId);
|
||||||
|
|
||||||
|
// Mock strength
|
||||||
|
when(client.getBoostedSkillLevel(Skill.RANGED)).thenReturn(rangeLevel);
|
||||||
|
|
||||||
|
// Test
|
||||||
|
RangeMaxHitCalculator maxHitCalculator = new RangeMaxHitCalculator(client, this.equipedItems);
|
||||||
|
assertEquals(this.toString(), expectedMaxHit, maxHitCalculator.getMaxHit(), 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user