Merge branch 'master' of https://github.com/runelite-extended/runelite
# Conflicts: # runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -7,4 +7,8 @@ project.properties
|
||||
.idea/
|
||||
.project
|
||||
.settings/
|
||||
.classpath
|
||||
.classpath
|
||||
runelite-client/src/main/resources/META-INF/MANIFEST.MF
|
||||
git
|
||||
classes/artifacts/client_jar/run.bat
|
||||
classes/artifacts/client_jar/client.jar
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.runelite.api.coords.WorldPoint;
|
||||
*/
|
||||
public interface Actor extends Renderable
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the combat level of the actor.
|
||||
*
|
||||
@@ -246,4 +247,10 @@ public interface Actor extends Renderable
|
||||
* @param overheadText the overhead text
|
||||
*/
|
||||
void setOverheadText(String overheadText);
|
||||
|
||||
/**
|
||||
* Used by the "Tick Counter Plugin
|
||||
*/
|
||||
int getActionFrame();
|
||||
int getActionFrameCycle();
|
||||
}
|
||||
|
||||
@@ -154,10 +154,26 @@ public final class AnimationID
|
||||
public static final int PISCARILIUS_CRANE_REPAIR = 7199;
|
||||
public static final int HOME_MAKE_TABLET = 4067;
|
||||
|
||||
//block animations for players and perhaps npcs as well?
|
||||
public static final int BLOCK_DEFENDER = 4177;
|
||||
public static final int BLOCK_NO_SHIELD = 420;
|
||||
public static final int BLOCK_SHIELD = 1156;
|
||||
public static final int BLOCK_SWORD = 388;
|
||||
public static final int BLOCK_UNARMED = 424;
|
||||
|
||||
// NPC animations
|
||||
public static final int TZTOK_JAD_MAGIC_ATTACK = 2656;
|
||||
public static final int TZTOK_JAD_RANGE_ATTACK = 2652;
|
||||
public static final int HELLHOUND_DEFENCE = 6566;
|
||||
public static final int VORKATH_WAKE_UP = 7950;
|
||||
public static final int VORKATH_DEATH = 7949;
|
||||
public static final int VORKATH_SLASH_ATTACK = 7951;
|
||||
public static final int VORKATH_ATTACK = 7952;
|
||||
public static final int VORKATH_FIRE_BOMB_ATTACK = 7960;
|
||||
public static final int VORKATH_ACID_ATTACK = 7957;
|
||||
public static final int BLACKJACK_KO = 838;
|
||||
public static final int VETION_EARTHQUAKE = 5507;
|
||||
public static final int ZULRAH_DEATH = 5804;
|
||||
|
||||
// Farming
|
||||
public static final int FARMING_HARVEST_FRUIT_TREE = 2280;
|
||||
@@ -194,4 +210,7 @@ public final class AnimationID
|
||||
|
||||
// POH Animations
|
||||
public static final int INCENSE_BURNER = 3687;
|
||||
}
|
||||
public static final int LOW_LEVEL_MAGIC_ATTACK = 1162;
|
||||
public static final int HIGH_LEVEL_MAGIC_ATTACK = 1167;
|
||||
public static final int BLOWPIPE_ATTACK = 5061;
|
||||
}
|
||||
@@ -52,7 +52,8 @@ public enum VarPlayer
|
||||
IN_RAID_PARTY(1427),
|
||||
|
||||
NMZ_REWARD_POINTS(1060),
|
||||
|
||||
|
||||
ATTACKING_PLAYER(1075),
|
||||
/**
|
||||
* -1 : Poison immune
|
||||
* Normal poison damage is ceil( this / 5.0f )
|
||||
|
||||
@@ -480,7 +480,16 @@ public enum Varbits
|
||||
/**
|
||||
* The active tab within the quest interface
|
||||
*/
|
||||
QUEST_TAB(8168);
|
||||
QUEST_TAB(8168),
|
||||
|
||||
/**
|
||||
* Temple Trekking
|
||||
*/
|
||||
TREK_POINTS(1955),
|
||||
TREK_STARTED(1956),
|
||||
TREK_EVENT(1958),
|
||||
TREK_STATUS(6719);
|
||||
|
||||
|
||||
/**
|
||||
* The raw varbit ID.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Davis Cook <https://github.com/daviscook477>
|
||||
* 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.api.events;
|
||||
|
||||
/**
|
||||
* an event posted when a cannonball is fired
|
||||
*/
|
||||
public class CannonballFired
|
||||
{
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import net.runelite.api.PlayerComposition;
|
||||
*/
|
||||
public enum KitType
|
||||
{
|
||||
HELMET(0),
|
||||
CAPE(1),
|
||||
AMULET(2),
|
||||
WEAPON(3),
|
||||
@@ -45,7 +46,9 @@ public enum KitType
|
||||
HEAD(8),
|
||||
HANDS(9),
|
||||
BOOTS(10),
|
||||
JAW(11);
|
||||
JAW(11),
|
||||
RING(12),
|
||||
AMMUNITION(13);
|
||||
|
||||
/**
|
||||
* Raw equipment index.
|
||||
|
||||
@@ -129,6 +129,7 @@ public class WidgetID
|
||||
public static final int SKILLS_GROUP_ID = 320;
|
||||
public static final int QUESTTAB_GROUP_ID = 629;
|
||||
public static final int MUSIC_GROUP_ID = 239;
|
||||
public static final int MUSICTAB_GROUP_ID = 239;
|
||||
public static final int BARROWS_PUZZLE_GROUP_ID = 25;
|
||||
|
||||
static class WorldMap
|
||||
@@ -701,16 +702,152 @@ public class WidgetID
|
||||
static class StandardSpellBook
|
||||
{
|
||||
static final int LUMBRIDGE_HOME_TELEPORT = 4;
|
||||
static final int WIND_STRIKE = 5;
|
||||
static final int CONFUSE = 6;
|
||||
static final int ENCHANT_CROSSBOW_BOLT = 7;
|
||||
static final int WATER_STRIKE = 8;
|
||||
static final int LVL_1_ENCHANT = 9;
|
||||
static final int EARTH_STRIKE = 10;
|
||||
static final int WEAKEN = 11;
|
||||
static final int FIRE_STRIKE = 12;
|
||||
static final int BONES_TO_BANANAS = 13;
|
||||
static final int WIND_BOLT = 14;
|
||||
static final int CURSE = 15;
|
||||
static final int BIND = 16;
|
||||
static final int LOW_LEVEL_ALCHEMY = 17;
|
||||
static final int WATER_BOLT = 18;
|
||||
static final int VARROCK_TELEPORT = 19;
|
||||
static final int LVL_2_ENCHANT = 20;
|
||||
static final int EARTH_BOLT = 21;
|
||||
static final int LUMBRIDGE_TELEPORT = 22;
|
||||
static final int TELEKINETIC_GRAB = 23;
|
||||
static final int FIRE_BOLT = 24;
|
||||
static final int FALADOR_TELEPORT = 25;
|
||||
static final int CRUMBLE_UNDEAD = 26;
|
||||
static final int TELEPORT_TO_HOUSE = 27;
|
||||
static final int WIND_BLAST = 28;
|
||||
static final int SUPERHEAT_ITEM = 29;
|
||||
static final int CAMELOT_TELEPORT = 30;
|
||||
static final int WATER_BLAST = 31;
|
||||
static final int LVL_3_ENCHANT = 32;
|
||||
static final int IBAN_BLAST = 33;
|
||||
static final int SNARE = 34;
|
||||
static final int MAGIC_DART = 35;
|
||||
static final int ARDOUGNE_TELEPORT = 36;
|
||||
static final int EARTH_BLAST = 37;
|
||||
static final int HIGH_LEVEL_ALCHEMY = 38;
|
||||
static final int CHARGE_WATER_ORB = 39;
|
||||
static final int LVL_4_ENCHANT = 40;
|
||||
static final int WATCHTOWER_TELEPORT = 41;
|
||||
static final int FIRE_BLAST = 42;
|
||||
static final int CHARGE_EARTH_ORB = 43;
|
||||
static final int BONES_TO_PEACHES = 44;
|
||||
static final int SARADOMIN_STRIKE = 45;
|
||||
static final int CLAWS_OF_GUTHIX = 46;
|
||||
static final int FLAMES_OF_ZAMORAK = 47;
|
||||
static final int TROLLHEIM_TELEPORT = 48;
|
||||
static final int WIND_WAVE = 49;
|
||||
static final int HARGE_FIRE_ORB = 50;
|
||||
static final int TELEPORT_TO_APE_ATOLL = 51;
|
||||
static final int WATER_WAVE = 52;
|
||||
static final int CHARGE_AIR_ORB = 53;
|
||||
static final int VULNERABILITY = 54;
|
||||
static final int LVL_5_ENCHANT = 55;
|
||||
static final int TELEPORT_TO_KOUREND = 56;
|
||||
static final int EARTH_WAVE = 57;
|
||||
static final int ENFEEBLE = 58;
|
||||
static final int TELEOTHER_LUMBRIDGE = 59;
|
||||
static final int FIRE_WAVE = 60;
|
||||
static final int ENTANGLE = 61;
|
||||
static final int STUN = 62;
|
||||
static final int CHARGE = 63;
|
||||
static final int WIND_SURGE = 64;
|
||||
static final int TELEOTHER_FALADOR = 65;
|
||||
static final int WATER_SURGE = 66;
|
||||
static final int TELE_BLOCK = 67;
|
||||
static final int BOUNTY_TARGET_TELEPORT = 68;
|
||||
static final int LVL_6_ENCHANT = 69;
|
||||
static final int TELEOTHER_CAMELOT = 70;
|
||||
static final int EARTH_SURGE = 71;
|
||||
static final int LVL_7_ENCHANT = 72;
|
||||
static final int FIRE_SURGE = 73;
|
||||
}
|
||||
|
||||
static class AncientSpellBook
|
||||
{
|
||||
static class AncientSpellBook {
|
||||
static final int BOUNTY_TARGET_TELEPORT = 68;
|
||||
static final int ICE_RUSH = 74;
|
||||
static final int ICE_BLITZ = 75;
|
||||
static final int ICE_BURST = 76;
|
||||
static final int ICE_BARRAGE = 77;
|
||||
static final int BLOOD_RUSH = 78;
|
||||
static final int BLOOD_BLITZ = 79;
|
||||
static final int BLOOD_BURST = 80;
|
||||
static final int BLOOD_BARRAGE = 81;
|
||||
static final int SMOKE_RUSH = 82;
|
||||
static final int SMOKE_BLITZ = 83;
|
||||
static final int SMOKE_BURST = 84;
|
||||
static final int SMOKE_BARRAGE = 85;
|
||||
static final int SHADOW_RUSH = 86;
|
||||
static final int SHADOW_BLITZ = 87;
|
||||
static final int SHADOW_BURST = 88;
|
||||
static final int SHADOW_BARRAGE = 89;
|
||||
static final int PADDEWWA_TELEPORT = 90;
|
||||
static final int SENNTISTEN_TELEPORT = 91;
|
||||
static final int KHARYRLL_TELEPORT = 92;
|
||||
static final int LASSAR_TELEPORT = 93;
|
||||
static final int DAREEYAK_TELEPORT = 94;
|
||||
static final int CARRALLANGER_TELEPORT = 95;
|
||||
static final int ANNAKARL_TELEPORT = 96;
|
||||
static final int GHORROCK_TELEPORT = 97;
|
||||
static final int EDGEVILLE_HOME_TELEPORT = 98;
|
||||
}
|
||||
|
||||
static class LunarSpellBook
|
||||
{
|
||||
static class LunarSpellBook {
|
||||
static final int BOUNTY_TARGET_TELEPORT = 68;
|
||||
static final int LUNAR_HOME_TELEPORT = 99;
|
||||
static final int BAKE_PIE = 100;
|
||||
static final int CURE_PLANT = 101;
|
||||
static final int MONSTER_EXAMINE = 102;
|
||||
static final int NPC_CONTACT = 103;
|
||||
static final int CURE_OTHER = 104;
|
||||
static final int HUMIDIFY = 105;
|
||||
static final int MOONCLAN_TELEPORT = 106;
|
||||
static final int TELE_GROUP_MOONCLAN = 107;
|
||||
static final int CURE_ME = 108;
|
||||
static final int HUNTER_KIT = 109;
|
||||
static final int WATERBIRTH_TELEPORT = 110;
|
||||
static final int TELE_GROUP_WATERBIRTH = 111;
|
||||
static final int CURE_GROUP = 112;
|
||||
static final int STAT_SPY = 113;
|
||||
static final int BARBARIAN_TELEPORT = 114;
|
||||
static final int TELE_GROUP_BARBARIAN = 115;
|
||||
static final int SUPERGLASS_MAKE = 116;
|
||||
static final int TAN_LEATHER = 117;
|
||||
static final int KHAZARD_TELEPORT = 118;
|
||||
static final int TELE_GROUP_KHAZARD = 119;
|
||||
static final int DREAM = 120;
|
||||
static final int STRING_JEWELLERY = 121;
|
||||
static final int STAT_RESTORE_POT_SHARE = 122;
|
||||
static final int MAGIC_IMBUE = 123;
|
||||
static final int FERTILE_SOIL = 124;
|
||||
static final int BOOST_POTION_SHARE = 125;
|
||||
static final int FISHING_GUILD_TELEPORT = 126;
|
||||
static final int TELE_GROUP_FISHING_GUILD = 127;
|
||||
static final int PLANK_MAKE = 128;
|
||||
static final int CATHERBY_TELEPORT = 129;
|
||||
static final int TELE_GROUP_CATHERBY = 130;
|
||||
static final int RECHARGE_DRAGONSTONE = 131;
|
||||
static final int ICE_PLATEAU_TELEPORT = 132;
|
||||
static final int TELE_GROUP_ICE_PLATEAU = 133;
|
||||
static final int ENERGY_TRANSFER = 134;
|
||||
static final int HEAL_OTHER = 135;
|
||||
static final int VENGEANCE_OTHER = 136;
|
||||
static final int VENGEANCE = 137;
|
||||
static final int HEAL_GROUP = 138;
|
||||
static final int SPELLBOOK_SWAP = 139;
|
||||
static final int GEOMANCY = 140;
|
||||
static final int SPIN_FLAX = 141;
|
||||
static final int OURANIA_TELEPORT = 142;
|
||||
}
|
||||
|
||||
static class ArceuusSpellBook
|
||||
|
||||
@@ -450,10 +450,56 @@ public enum WidgetInfo
|
||||
|
||||
MINIGAME_TELEPORT_BUTTON(WidgetID.MINIGAME_TAB_ID, WidgetID.Minigames.TELEPORT_BUTTON),
|
||||
|
||||
/* STANDARD SPELL BOOK WIDGETS*/
|
||||
SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.LUMBRIDGE_HOME_TELEPORT),
|
||||
SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.EDGEVILLE_HOME_TELEPORT),
|
||||
SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BIND),
|
||||
SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.SNARE),
|
||||
SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.ENTANGLE),
|
||||
SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.TELE_BLOCK),
|
||||
SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.FIRE_SURGE),
|
||||
SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BOUNTY_TARGET_TELEPORT),
|
||||
/* END OF STANDARD SPELL BOOK WIDGETS*/
|
||||
|
||||
/* LUNAR SPELL BOOK WIDGETS*/
|
||||
SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.LUNAR_HOME_TELEPORT),
|
||||
SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE_OTHER),
|
||||
SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE),
|
||||
SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.BOUNTY_TARGET_TELEPORT),
|
||||
/* LUNA SPELL BOOK WIDGETS*/
|
||||
|
||||
/* ARCEUUS SPELL BOOK WIDGETS*/
|
||||
SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT),
|
||||
/* END OF ARCEUUS SPELL BOOK WIDGETS*/
|
||||
|
||||
/* ANCIENT SPELL BOOK WIDGETS*/
|
||||
SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_RUSH),
|
||||
SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BLITZ),
|
||||
SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BURST),
|
||||
SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BARRAGE),
|
||||
SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_RUSH),
|
||||
SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BLITZ),
|
||||
SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BURST),
|
||||
SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BARRAGE),
|
||||
SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_RUSH),
|
||||
SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BLITZ),
|
||||
SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BURST),
|
||||
SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BARRAGE),
|
||||
SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_RUSH),
|
||||
SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BLITZ),
|
||||
SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BURST),
|
||||
SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BARRAGE),
|
||||
SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.PADDEWWA_TELEPORT),
|
||||
SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SENNTISTEN_TELEPORT),
|
||||
SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.KHARYRLL_TELEPORT),
|
||||
SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.LASSAR_TELEPORT),
|
||||
SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.DAREEYAK_TELEPORT),
|
||||
SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.CARRALLANGER_TELEPORT),
|
||||
SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ANNAKARL_TELEPORT),
|
||||
SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.GHORROCK_TELEPORT),
|
||||
SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.EDGEVILLE_HOME_TELEPORT),
|
||||
SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BOUNTY_TARGET_TELEPORT),
|
||||
|
||||
/* END OF ANCIENT SPELL BOOK WIDGETS*/
|
||||
|
||||
PVP_SKULL_CONTAINER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL_CONTAINER),
|
||||
PVP_WORLD_SAFE_ZONE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SAFE_ZONE),
|
||||
@@ -477,6 +523,20 @@ public enum WidgetInfo
|
||||
QUESTLIST_FREE_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.FREE_CONTAINER),
|
||||
QUESTLIST_MEMBERS_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MEMBERS_CONTAINER),
|
||||
QUESTLIST_MINIQUEST_CONTAINER(WidgetID.QUESTLIST_GROUP_ID, WidgetID.QuestList.MINIQUEST_CONTAINER),
|
||||
|
||||
MUSICTAB_INTERFACE(WidgetID.MUSICTAB_GROUP_ID, 1),
|
||||
MUSICTAB_SONG_BOX(WidgetID.MUSICTAB_GROUP_ID, 2),
|
||||
MUSICTAB_ALL_SONGS(WidgetID.MUSICTAB_GROUP_ID, 3),
|
||||
MUSICTAB_SCROLLBAR(WidgetID.MUSICTAB_GROUP_ID, 4),
|
||||
MUSICTAB_PLAYING(WidgetID.MUSICTAB_GROUP_ID, 5),
|
||||
MUSICTAB_CURRENT_SONG_NAME(WidgetID.MUSICTAB_GROUP_ID, 6),
|
||||
MUSICTAB_AUTO_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 7),
|
||||
MUSICTAB_AUTO_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 8),
|
||||
MUSICTAB_MANUAL_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 9),
|
||||
MUSICTAB_MANUAL_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 10),
|
||||
MUSICTAB_LOOP_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 11),
|
||||
MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12),
|
||||
MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13),
|
||||
|
||||
QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package net.runelite.api.widgets;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.runelite.api.Point;
|
||||
|
||||
@@ -34,55 +35,34 @@ import net.runelite.api.Point;
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
@Getter
|
||||
public class WidgetItem
|
||||
{
|
||||
private final int id;
|
||||
private final int quantity;
|
||||
private final int index;
|
||||
private final Rectangle canvasBounds;
|
||||
|
||||
/**
|
||||
* Gets the ID of the item represented.
|
||||
* The ID of the item represented.
|
||||
*
|
||||
* @return the items ID
|
||||
* @see net.runelite.api.ItemID
|
||||
*/
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private final int id;
|
||||
/**
|
||||
* Gets the quantity of the represented item.
|
||||
*
|
||||
* @return the items quantity
|
||||
* The quantity of the represented item.
|
||||
*/
|
||||
public int getQuantity()
|
||||
{
|
||||
return quantity;
|
||||
}
|
||||
|
||||
private final int quantity;
|
||||
/**
|
||||
* Gets the index position of this WidgetItem inside its parents
|
||||
* The index position of this WidgetItem inside its parents
|
||||
* WidgetItem array.
|
||||
*
|
||||
* @return the index in the parent widget
|
||||
* @see Widget#getWidgetItems()
|
||||
*/
|
||||
public int getIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
private final int index;
|
||||
/**
|
||||
* Gets the area where the widget is drawn on the canvas.
|
||||
*
|
||||
* @return the occupied area of the widget
|
||||
* The area where the widget is drawn on the canvas.
|
||||
*/
|
||||
public Rectangle getCanvasBounds()
|
||||
{
|
||||
return canvasBounds;
|
||||
}
|
||||
private final Rectangle canvasBounds;
|
||||
/**
|
||||
* The widget which contains this item.
|
||||
*/
|
||||
private final Widget widget;
|
||||
|
||||
/**
|
||||
* Gets the upper-left coordinate of where the widget is being drawn
|
||||
|
||||
@@ -1,414 +1,419 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2016-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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.5.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>client</artifactId>
|
||||
<name>RuneLite Client</name>
|
||||
|
||||
<properties>
|
||||
<guice.version>4.1.0</guice.version>
|
||||
<jogl.version>2.3.2</jogl.version>
|
||||
|
||||
<jarsigner.skip>true</jarsigner.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jopt-simple</groupId>
|
||||
<artifactId>jopt-simple</artifactId>
|
||||
<version>5.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
<classifier>no_aop</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.pushingpixels</groupId>
|
||||
<artifactId>substance</artifactId>
|
||||
<version>8.0.02</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.pushingpixels</groupId>
|
||||
<artifactId>trident</artifactId>
|
||||
<version>1.5.00</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.sigpipe</groupId>
|
||||
<artifactId>jbsdiff</artifactId>
|
||||
<version>1.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.tukaani</groupId>
|
||||
<artifactId>xz</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- net.runelite:discord also has this -->
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>4.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-platform</artifactId>
|
||||
<version>4.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.rs</groupId>
|
||||
<artifactId>runescape-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>client-patch</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>http-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>discord</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>orange-extensions</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.10.19</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-testlib</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-grapher</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.24.1-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xeustechnologies</groupId>
|
||||
<artifactId>jcl-core</artifactId>
|
||||
<version>2.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>logback.xml</exclude>
|
||||
</excludes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>logback.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<nonFilteredFileExtensions>
|
||||
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>png</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
|
||||
</nonFilteredFileExtensions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<shadedClassifierName>shaded</shadedClassifierName>
|
||||
|
||||
<filters>
|
||||
<!-- include runtime apis -->
|
||||
<filter>
|
||||
<!-- net.runelite:client-patch and net.runelite:api -->
|
||||
<artifact>net.runelite:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>net.runelite.rs:runescape-api</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>net.runelite.pushingpixels:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>com.google.guava:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>ch.qos.logback:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.jogamp.jogl:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.jogamp.gluegen:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
</filters>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>net.runelite.client.RuneLite</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Strip jar before signing -->
|
||||
<plugin>
|
||||
<groupId>io.github.zlika</groupId>
|
||||
<artifactId>reproducible-build-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jarsigner-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign</id>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<skip>${jarsigner.skip}</skip>
|
||||
<keystore>${jarsigner.keystore}</keystore>
|
||||
<alias>${jarsigner.alias}</alias>
|
||||
<storepass>${jarsigner.storepass}</storepass>
|
||||
<keypass>${jarsigner.keypass}</keypass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>script-assembler-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<goals>
|
||||
<goal>assemble</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<scriptDirectory>src/main/scripts</scriptDirectory>
|
||||
<outputDirectory>${project.build.outputDirectory}/runelite</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>build-index</id>
|
||||
<goals>
|
||||
<goal>build-index</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<archiveOverlayDirectory>${project.build.outputDirectory}/runelite</archiveOverlayDirectory>
|
||||
<indexFile>${project.build.outputDirectory}/runelite/index</indexFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2016-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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.5.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>client</artifactId>
|
||||
<name>RuneLite Client</name>
|
||||
|
||||
<properties>
|
||||
<guice.version>4.1.0</guice.version>
|
||||
<jogl.version>2.3.2</jogl.version>
|
||||
|
||||
<jarsigner.skip>true</jarsigner.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jopt-simple</groupId>
|
||||
<artifactId>jopt-simple</artifactId>
|
||||
<version>5.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
<classifier>no_aop</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.pushingpixels</groupId>
|
||||
<artifactId>substance</artifactId>
|
||||
<version>8.0.02</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.pushingpixels</groupId>
|
||||
<artifactId>trident</artifactId>
|
||||
<version>1.5.00</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-windows-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-amd64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt</artifactId>
|
||||
<version>${jogl.version}</version>
|
||||
<classifier>natives-linux-i586</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.sigpipe</groupId>
|
||||
<artifactId>jbsdiff</artifactId>
|
||||
<version>1.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.tukaani</groupId>
|
||||
<artifactId>xz</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- net.runelite:discord also has this -->
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>4.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-platform</artifactId>
|
||||
<version>4.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.rs</groupId>
|
||||
<artifactId>runescape-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>client-patch</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>http-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>discord</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>orange-extensions</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.10.19</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-testlib</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-grapher</artifactId>
|
||||
<version>${guice.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.24.1-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xeustechnologies</groupId>
|
||||
<artifactId>jcl-core</artifactId>
|
||||
<version>2.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>17.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>logback.xml</exclude>
|
||||
</excludes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>logback.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<nonFilteredFileExtensions>
|
||||
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>png</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
|
||||
</nonFilteredFileExtensions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<shadedClassifierName>shaded</shadedClassifierName>
|
||||
|
||||
<filters>
|
||||
<!-- include runtime apis -->
|
||||
<filter>
|
||||
<!-- net.runelite:client-patch and net.runelite:api -->
|
||||
<artifact>net.runelite:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>net.runelite.rs:runescape-api</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>net.runelite.pushingpixels:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>com.google.guava:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>ch.qos.logback:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.jogamp.jogl:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.jogamp.gluegen:*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
</filters>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>net.runelite.client.RuneLite</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Strip jar before signing -->
|
||||
<plugin>
|
||||
<groupId>io.github.zlika</groupId>
|
||||
<artifactId>reproducible-build-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jarsigner-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign</id>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<skip>${jarsigner.skip}</skip>
|
||||
<keystore>${jarsigner.keystore}</keystore>
|
||||
<alias>${jarsigner.alias}</alias>
|
||||
<storepass>${jarsigner.storepass}</storepass>
|
||||
<keypass>${jarsigner.keypass}</keypass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>script-assembler-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<goals>
|
||||
<goal>assemble</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<scriptDirectory>src/main/scripts</scriptDirectory>
|
||||
<outputDirectory>${project.build.outputDirectory}/runelite</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>build-index</id>
|
||||
<goals>
|
||||
<goal>build-index</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<archiveOverlayDirectory>${project.build.outputDirectory}/runelite</archiveOverlayDirectory>
|
||||
<indexFile>${project.build.outputDirectory}/runelite/index</indexFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.aoewarnings;
|
||||
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class AoeProjectile
|
||||
{
|
||||
private final Instant startTime;
|
||||
private final LocalPoint targetPoint;
|
||||
private final AoeProjectileInfo aoeProjectileInfo;
|
||||
|
||||
public AoeProjectile(Instant startTime, LocalPoint targetPoint, AoeProjectileInfo aoeProjectileInfo)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
this.targetPoint = targetPoint;
|
||||
this.aoeProjectileInfo = aoeProjectileInfo;
|
||||
}
|
||||
|
||||
public Instant getStartTime()
|
||||
{
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public LocalPoint getTargetPoint()
|
||||
{
|
||||
return targetPoint;
|
||||
}
|
||||
|
||||
public AoeProjectileInfo getAoeProjectileInfo()
|
||||
{
|
||||
return aoeProjectileInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.api.ProjectileID;
|
||||
|
||||
public enum AoeProjectileInfo
|
||||
{
|
||||
LIZARDMAN_SHAMAN_AOE(ProjectileID.LIZARDMAN_SHAMAN_AOE, 3000, 3),
|
||||
CRAZY_ARCHAEOLOGIST_AOE(ProjectileID.CRAZY_ARCHAEOLOGIST_AOE, 3000, 3),
|
||||
ICE_DEMON_RANGED_AOE(ProjectileID.ICE_DEMON_RANGED_AOE, 3000, 3),
|
||||
/**
|
||||
* When you don't have pray range on ice demon does an ice barrage
|
||||
*/
|
||||
ICE_DEMON_ICE_BARRAGE_AOE(ProjectileID.ICE_DEMON_ICE_BARRAGE_AOE, 3000, 3),
|
||||
/**
|
||||
* The AOE when vasa first starts
|
||||
*/
|
||||
VASA_AWAKEN_AOE(ProjectileID.VASA_AWAKEN_AOE, 4500, 3),
|
||||
VASA_RANGED_AOE(ProjectileID.VASA_RANGED_AOE, 3000, 3),
|
||||
TEKTON_METEOR_AOE(ProjectileID.TEKTON_METEOR_AOE, 4000, 3),
|
||||
|
||||
/**
|
||||
* The AOEs of Vorkath
|
||||
*/
|
||||
VORKATH_BOMB(ProjectileID.VORKATH_BOMB_AOE, 2400, 3),
|
||||
VORKATH_POISON_POOL(ProjectileID.VORKATH_POISON_POOL_AOE, 1800, 1),
|
||||
VORKATH_SPAWN(ProjectileID.VORKATH_SPAWN_AOE, 3000, 1), //extra tick because hard to see otherwise
|
||||
VORKATH_TICK_FIRE(ProjectileID.VORKATH_TICK_FIRE_AOE, 600, 1),
|
||||
|
||||
/**
|
||||
* the AOEs of Galvek
|
||||
*/
|
||||
GALVEK_MINE(ProjectileID.GALVEK_MINE, 3600, 3),
|
||||
GALVEK_BOMB(ProjectileID.GALVEK_BOMB, 2400, 3),
|
||||
|
||||
DAWN_FREEZE(ProjectileID.DAWN_FREEZE, 3000, 3),
|
||||
DUSK_CEILING(ProjectileID.DUSK_CEILING, 3000, 3),
|
||||
|
||||
/**
|
||||
* the AOE of Vet'ion
|
||||
*/
|
||||
VETION_LIGHTNING(ProjectileID.VETION_LIGHTNING, 3000, 1),
|
||||
|
||||
/**
|
||||
* the AOE of Chaos Fanatic
|
||||
*/
|
||||
CHAOS_FANATIC(ProjectileID.CHAOS_FANATIC_AOE, 3000, 1),
|
||||
|
||||
/**
|
||||
* the AOE of the Corporeal Beast
|
||||
*/
|
||||
|
||||
CORPOREAL_BEAST(ProjectileID.CORPOREAL_BEAST_AOE, 3000, 1),
|
||||
CORPOREAL_BEAST_DARK_CORE(ProjectileID.CORPOREAL_BEAST_DARK_CORE_AOE, 3000, 3),
|
||||
|
||||
/**
|
||||
* the AOEs of The Great Olm
|
||||
* missing ids and length, please help
|
||||
*/
|
||||
OLM_FALLING_CRYSTAL(1357, 3000, 3),
|
||||
OLM_BURNING(1349, 2400, 1),
|
||||
OLM_FALLING_CRYSTAL_TRAIL(1352, 2400, 1),
|
||||
OLM_ACID_TRAIL(1354, 2400, 1),
|
||||
OLM_FIRE_LINE(1347, 2400, 1),
|
||||
|
||||
/**
|
||||
* the AOE of the Wintertodt snow that falls
|
||||
*/
|
||||
WINTERTODT_SNOW_FALL(1310, 4000, 3);
|
||||
|
||||
|
||||
/**
|
||||
* The id of the projectile to trigger this AoE warning
|
||||
*/
|
||||
private final int id;
|
||||
|
||||
/**
|
||||
* How long the indicator should last for this AoE warning This might
|
||||
* need to be a bit longer than the projectile actually takes to land as
|
||||
* there is a fade effect on the warning
|
||||
*/
|
||||
private final Duration lifeTime;
|
||||
|
||||
/**
|
||||
* The size of the splash radius of the AoE warning Ex. Lizardman shaman
|
||||
* AoE is a 3x3, so aoeSize = 3
|
||||
*/
|
||||
private final int aoeSize;
|
||||
|
||||
private static final Map<Integer, AoeProjectileInfo> map = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for (AoeProjectileInfo aoe : values())
|
||||
{
|
||||
map.put(aoe.id, aoe);
|
||||
}
|
||||
}
|
||||
|
||||
AoeProjectileInfo(int id, int lifeTimeMillis, int aoeSize)
|
||||
{
|
||||
this.id = id;
|
||||
this.lifeTime = Duration.ofMillis(lifeTimeMillis);
|
||||
this.aoeSize = aoeSize;
|
||||
}
|
||||
|
||||
public Duration getLifeTime()
|
||||
{
|
||||
return lifeTime;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getAoeSize()
|
||||
{
|
||||
return aoeSize;
|
||||
}
|
||||
|
||||
public static AoeProjectileInfo getById(int id)
|
||||
{
|
||||
return map.get(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("aoe")
|
||||
public interface AoeWarningConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "enabled",
|
||||
name = "AoE Warnings Enabled",
|
||||
description = "Configures whether or not AoE Projectile Warnings plugin is displayed"
|
||||
)
|
||||
default boolean enabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lizardmanaoe",
|
||||
name = "Lizardman Shamans",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans is displayed"
|
||||
)
|
||||
default boolean isShamansEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "archaeologistaoe",
|
||||
name = "Crazy Archaeologist",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Archaeologist is displayed"
|
||||
)
|
||||
default boolean isArchaeologistEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "icedemon",
|
||||
name = "Ice Demon",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Ice Demon is displayed"
|
||||
)
|
||||
default boolean isIceDemonEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vasa",
|
||||
name = "Vasa",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vasa is displayed"
|
||||
)
|
||||
default boolean isVasaEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tekton",
|
||||
name = "Tekton",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Tekton is displayed"
|
||||
)
|
||||
default boolean isTektonEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vorkath",
|
||||
name = "Vorkath",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vorkath are displayed"
|
||||
)
|
||||
default boolean isVorkathEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "galvek",
|
||||
name = "Galvek",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Galvek are displayed"
|
||||
)
|
||||
default boolean isGalvekEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gargboss",
|
||||
name = "Gargoyle Boss",
|
||||
description = "Configs whether or not AoE Projectile Warnings for Dawn/Dusk are displayed"
|
||||
)
|
||||
default boolean isGargBossEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vetion",
|
||||
name = "Vet'ion",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vet'ion are displayed"
|
||||
)
|
||||
default boolean isVetionEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "chaosfanatic",
|
||||
name = "Chaos Fanatic",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic are displayed"
|
||||
)
|
||||
default boolean isChaosFanaticEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "olm",
|
||||
name = "Great Olm",
|
||||
description = "Configures whether or not AoE Projectile Warnings for The Great Olm are displayed"
|
||||
)
|
||||
default boolean isOlmEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bombDisplay",
|
||||
name = "Display crystal phase bomb tracker",
|
||||
description = "Display a timer and colour-coded AoE for Olm's crystal-phase bombs."
|
||||
)
|
||||
default boolean bombDisplay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "corp",
|
||||
name = "Corporeal Beast",
|
||||
description = "Configures whether or not AoE Projectile Warnings for the Corporeal Beast are displayed"
|
||||
)
|
||||
default boolean isCorpEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "wintertodt",
|
||||
name = "Wintertodt Snow Fall",
|
||||
description = "Configures whether or not AOE Projectile Warnings for the Wintertodt snow fall are displayed"
|
||||
)
|
||||
default boolean isWintertodtEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "outline",
|
||||
name = "Display Outline",
|
||||
description = "Configures whether or not AoE Projectile Warnings have an outline"
|
||||
)
|
||||
default boolean isOutlineEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lightning",
|
||||
name = "Show Lightning Trails",
|
||||
description = "Show Lightning Trails"
|
||||
)
|
||||
default boolean LightningTrail()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fade",
|
||||
name = "Fade Warnings",
|
||||
description = "Configures whether or not AoE Projectile Warnings fade over time"
|
||||
)
|
||||
default boolean isFadeEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.aoewarnings;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class AoeWarningOverlay extends Overlay
|
||||
{
|
||||
private static final int FILL_START_ALPHA = 25;
|
||||
private static final int OUTLINE_START_ALPHA = 255;
|
||||
|
||||
private final Client client;
|
||||
private final AoeWarningPlugin plugin;
|
||||
private final AoeWarningConfig config;
|
||||
|
||||
@Inject
|
||||
public AoeWarningOverlay(@Nullable Client client, AoeWarningPlugin plugin, AoeWarningConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!config.enabled())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (WorldPoint point : plugin.getLightningTrail())
|
||||
{
|
||||
drawTile(graphics, point, new Color(0,150,200), 2, 150, 50);
|
||||
}
|
||||
for (WorldPoint point : plugin.getAcidTrail())
|
||||
{
|
||||
drawTile(graphics, point, new Color(69, 241, 44), 2, 150, 50);
|
||||
}
|
||||
for (WorldPoint point : plugin.getCrystalSpike())
|
||||
{
|
||||
drawTile(graphics, point, new Color(255, 0, 84), 2, 150, 50);
|
||||
}
|
||||
|
||||
Instant now = Instant.now();
|
||||
Map<Projectile, AoeProjectile> projectiles = plugin.getProjectiles();
|
||||
for (Iterator<AoeProjectile> it = projectiles.values().iterator(); it.hasNext();)
|
||||
{
|
||||
AoeProjectile aoeProjectile = it.next();
|
||||
|
||||
if (now.isAfter(aoeProjectile.getStartTime().plus(aoeProjectile.getAoeProjectileInfo().getLifeTime())))
|
||||
{
|
||||
it.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, aoeProjectile.getTargetPoint(), aoeProjectile.getAoeProjectileInfo().getAoeSize());
|
||||
if (tilePoly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// how far through the projectiles lifetime between 0-1.
|
||||
double progress = (System.currentTimeMillis() - aoeProjectile.getStartTime().toEpochMilli()) / (double) aoeProjectile.getAoeProjectileInfo().getLifeTime().toMillis();
|
||||
|
||||
int fillAlpha, outlineAlpha;
|
||||
if (config.isFadeEnabled())
|
||||
{
|
||||
fillAlpha = (int) ((1 - progress) * FILL_START_ALPHA);//alpha drop off over lifetime
|
||||
outlineAlpha = (int) ((1 - progress) * OUTLINE_START_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
fillAlpha = FILL_START_ALPHA;
|
||||
outlineAlpha = OUTLINE_START_ALPHA;
|
||||
}
|
||||
|
||||
if (fillAlpha < 0)
|
||||
{
|
||||
fillAlpha = 0;
|
||||
}
|
||||
if (outlineAlpha < 0)
|
||||
{
|
||||
outlineAlpha = 0;
|
||||
}
|
||||
|
||||
if (fillAlpha > 255)
|
||||
{
|
||||
fillAlpha = 255;
|
||||
}
|
||||
if (outlineAlpha > 255)
|
||||
{
|
||||
outlineAlpha = 255;//Make sure we don't pass in an invalid alpha
|
||||
}
|
||||
|
||||
if (config.isOutlineEnabled())
|
||||
{
|
||||
graphics.setColor(new Color(0, 150, 200, outlineAlpha));
|
||||
graphics.drawPolygon(tilePoly);
|
||||
}
|
||||
|
||||
graphics.setColor(new Color(0, 150, 200, fillAlpha));
|
||||
graphics.fillPolygon(tilePoly);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) {
|
||||
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
if (point.distanceTo(playerLocation) >= 32) {
|
||||
return;
|
||||
}
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, point);
|
||||
if (lp == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
if (poly == null) {
|
||||
return;
|
||||
}
|
||||
//OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(strokeWidth));
|
||||
graphics.draw(poly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(poly);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GraphicID;
|
||||
import net.runelite.api.GraphicsObject;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.GraphicsObjectCreated;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!AoE Warnings</font>",
|
||||
description = "Shows the final destination for AoE Attack projectiles",
|
||||
tags = {"bosses", "combat", "pve", "overlay"}
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class AoeWarningPlugin extends Plugin
|
||||
{
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private AoeWarningOverlay coreOverlay;
|
||||
|
||||
@Inject
|
||||
public AoeWarningConfig config;
|
||||
|
||||
@Inject
|
||||
private BombOverlay bombOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Getter
|
||||
private final Map<WorldPoint, CrystalBomb> bombs = new HashMap<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> LightningTrail = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> AcidTrail = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<WorldPoint> CrystalSpike = new ArrayList<>();
|
||||
|
||||
|
||||
@Provides
|
||||
AoeWarningConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(AoeWarningConfig.class);
|
||||
}
|
||||
|
||||
|
||||
private final Map<Projectile, AoeProjectile> projectiles = new HashMap<>();
|
||||
|
||||
public Map<Projectile, AoeProjectile> getProjectiles()
|
||||
{
|
||||
return projectiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(coreOverlay);
|
||||
overlayManager.add(bombOverlay);
|
||||
LightningTrail.clear();
|
||||
AcidTrail.clear();
|
||||
CrystalSpike.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(coreOverlay);
|
||||
overlayManager.remove(bombOverlay);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProjectileMoved(ProjectileMoved event)
|
||||
{
|
||||
Projectile projectile = event.getProjectile();
|
||||
|
||||
int projectileId = projectile.getId();
|
||||
AoeProjectileInfo aoeProjectileInfo = AoeProjectileInfo.getById(projectileId);
|
||||
if (aoeProjectileInfo != null && isConfigEnabledForProjectileId(projectileId))
|
||||
{
|
||||
LocalPoint targetPoint = event.getPosition();
|
||||
AoeProjectile aoeProjectile = new AoeProjectile(Instant.now(), targetPoint, aoeProjectileInfo);
|
||||
projectiles.put(projectile, aoeProjectile);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject gameObject = event.getGameObject();
|
||||
final WorldPoint bombLocation = gameObject.getWorldLocation();
|
||||
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
bombs.put(bombLocation, new CrystalBomb(gameObject, client.getTickCount()));
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
AcidTrail.add(bombLocation);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
//todo
|
||||
CrystalSpike.add(bombLocation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
WorldPoint bombLocation = gameObject.getWorldLocation();
|
||||
switch (gameObject.getId())
|
||||
{
|
||||
case ObjectID.CRYSTAL_BOMB:
|
||||
//might as well check the ObjectID to save some time.
|
||||
purgeBombs(bombs);
|
||||
break;
|
||||
case ObjectID.ACID_POOL:
|
||||
AcidTrail.remove(bombLocation);
|
||||
break;
|
||||
case ObjectID.SMALL_CRYSTALS:
|
||||
//todo
|
||||
CrystalSpike.remove(bombLocation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged delta)
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
purgeBombs(bombs);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (config.LightningTrail())
|
||||
{
|
||||
LightningTrail.clear();
|
||||
for (GraphicsObject o : client.getGraphicsObjects())
|
||||
{
|
||||
if (o.getId() == 1356)
|
||||
{
|
||||
LightningTrail.add(WorldPoint.fromLocal(client, o.getLocation()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<WorldPoint, CrystalBomb>> it = bombs.entrySet().iterator();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
Map.Entry<WorldPoint, CrystalBomb> entry = it.next();
|
||||
CrystalBomb bomb = entry.getValue();
|
||||
bomb.bombClockUpdate();
|
||||
//bombClockUpdate smooths the shown timer; not using this results in 1.2 --> .6 vs. 1.2 --> 1.1, etc.
|
||||
}
|
||||
}
|
||||
|
||||
private void purgeBombs(Map<WorldPoint, CrystalBomb> bombs)
|
||||
{
|
||||
Iterator<Map.Entry<WorldPoint, CrystalBomb>> it = bombs.entrySet().iterator();
|
||||
Tile[][][] tiles = client.getScene().getTiles();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
Map.Entry<WorldPoint, CrystalBomb> entry = it.next();
|
||||
WorldPoint world = entry.getKey();
|
||||
LocalPoint local = LocalPoint.fromWorld(client, world);
|
||||
Tile tile = tiles[world.getPlane()][local.getSceneX()][local.getSceneY()];
|
||||
GameObject[] objects = tile.getGameObjects();
|
||||
boolean containsObjects = false;
|
||||
|
||||
for (GameObject object : objects)
|
||||
{
|
||||
if (object != null)
|
||||
{
|
||||
containsObjects = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containsObjects)
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isConfigEnabledForProjectileId(int projectileId)
|
||||
{
|
||||
AoeProjectileInfo projectileInfo = AoeProjectileInfo.getById(projectileId);
|
||||
if (projectileInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (projectileInfo)
|
||||
{
|
||||
case LIZARDMAN_SHAMAN_AOE:
|
||||
return config.isShamansEnabled();
|
||||
case CRAZY_ARCHAEOLOGIST_AOE:
|
||||
return config.isArchaeologistEnabled();
|
||||
case ICE_DEMON_RANGED_AOE:
|
||||
case ICE_DEMON_ICE_BARRAGE_AOE:
|
||||
return config.isIceDemonEnabled();
|
||||
case VASA_AWAKEN_AOE:
|
||||
case VASA_RANGED_AOE:
|
||||
return config.isVasaEnabled();
|
||||
case TEKTON_METEOR_AOE:
|
||||
return config.isTektonEnabled();
|
||||
case VORKATH_BOMB:
|
||||
case VORKATH_POISON_POOL:
|
||||
case VORKATH_SPAWN:
|
||||
case VORKATH_TICK_FIRE:
|
||||
return config.isVorkathEnabled();
|
||||
case VETION_LIGHTNING:
|
||||
return config.isVetionEnabled();
|
||||
case CHAOS_FANATIC:
|
||||
return config.isChaosFanaticEnabled();
|
||||
case GALVEK_BOMB:
|
||||
case GALVEK_MINE:
|
||||
return config.isGalvekEnabled();
|
||||
case DAWN_FREEZE:
|
||||
case DUSK_CEILING:
|
||||
return config.isGargBossEnabled();
|
||||
case OLM_FALLING_CRYSTAL:
|
||||
case OLM_BURNING:
|
||||
case OLM_FALLING_CRYSTAL_TRAIL:
|
||||
case OLM_ACID_TRAIL:
|
||||
case OLM_FIRE_LINE:
|
||||
return config.isOlmEnabled();
|
||||
case CORPOREAL_BEAST:
|
||||
case CORPOREAL_BEAST_DARK_CORE:
|
||||
return config.isCorpEnabled();
|
||||
case WINTERTODT_SNOW_FALL:
|
||||
return config.isWintertodtEnabled();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2018, PallasDieKatze (Pallas Cat)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.plugins.aoewarnings.CrystalBomb;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import javax.inject.Inject;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Color;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.BasicStroke;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class BombOverlay extends Overlay
|
||||
{
|
||||
|
||||
private static final String SAFE = "#00cc00";
|
||||
//safe
|
||||
private static final String CAUTION = "#ffff00";
|
||||
//1 tile in range (minor damage)
|
||||
private static final String WARNING = "#ff9933";
|
||||
//2 tiles in range (moderate damage)
|
||||
private static final String DANGER = "#ff6600";
|
||||
//3 tiles in range/adjacent to bomb (major damage)
|
||||
private static final String LETHAL = "#cc0000";
|
||||
//On the bomb, using it as a makeshift space launch vehicle. (massive damage)
|
||||
|
||||
private static final int BOMB_AOE = 7;
|
||||
private static final int BOMB_DETONATE_TIME = 8;
|
||||
//This is in ticks. It should be 10, but it varies from 8 to 11.
|
||||
private static final double ESTIMATED_TICK_LENGTH = .6;
|
||||
//Thank you Woox & co. for this assumption. .6 seconds/tick.
|
||||
|
||||
|
||||
//Utilized from the npc highlight code for formatting text being displayed on the client canvas.
|
||||
private static final NumberFormat TIME_LEFT_FORMATTER =
|
||||
DecimalFormat.getInstance(Locale.US);
|
||||
|
||||
static
|
||||
{
|
||||
((DecimalFormat) TIME_LEFT_FORMATTER).applyPattern("#0.0");
|
||||
}
|
||||
|
||||
private final Client client;
|
||||
private final AoeWarningConfig config;
|
||||
private final AoeWarningPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public BombOverlay(Client client, AoeWarningPlugin plugin, AoeWarningConfig config)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.bombDisplay())
|
||||
{
|
||||
drawBombs(graphics);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawBombs(Graphics2D graphics)
|
||||
//I can condense drawDangerZone into this. Ambivalent though.
|
||||
{
|
||||
Iterator<Map.Entry<WorldPoint, CrystalBomb>> it = plugin.getBombs().entrySet().iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
Map.Entry<WorldPoint, CrystalBomb> entry = it.next();
|
||||
CrystalBomb bomb = entry.getValue();
|
||||
drawDangerZone(graphics, bomb);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDangerZone(Graphics2D graphics, CrystalBomb bomb)
|
||||
{
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
LocalPoint localLoc = LocalPoint.fromWorld(client, bomb.getWorldLocation());
|
||||
double distance_x = Math.abs(bomb.getWorldLocation().getX() - localPlayer.getWorldLocation().getX());
|
||||
double distance_y = Math.abs(bomb.getWorldLocation().getY() - localPlayer.getWorldLocation().getY());
|
||||
Color color_code = Color.decode(SAFE);
|
||||
//defaults to this unless conditionals met below.
|
||||
|
||||
if (distance_x < 1 && distance_y < 1)
|
||||
{
|
||||
color_code = Color.decode(LETHAL);
|
||||
}
|
||||
else if (distance_x < 2 && distance_y < 2)
|
||||
{
|
||||
color_code = Color.decode(DANGER);
|
||||
}
|
||||
else if (distance_x < 3 && distance_y < 3)
|
||||
{
|
||||
color_code = Color.decode(WARNING);
|
||||
}
|
||||
else if (distance_x < 4 && distance_y < 4)
|
||||
{
|
||||
color_code = Color.decode(CAUTION);
|
||||
}
|
||||
LocalPoint CenterPoint = new LocalPoint(localLoc.getX() + 0, localLoc.getY() + 0);
|
||||
Polygon poly = Perspective.getCanvasTileAreaPoly(client, CenterPoint, BOMB_AOE);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
//manually generating the polygon so as to assign a custom alpha value. Request adtl' arg for alpha maybe?
|
||||
graphics.setColor(color_code);
|
||||
graphics.setStroke(new BasicStroke(1));
|
||||
graphics.drawPolygon(poly);
|
||||
graphics.setColor(new Color(0, 0, 0, 10));
|
||||
graphics.fillPolygon(poly);
|
||||
}
|
||||
|
||||
Instant now = Instant.now();
|
||||
double timeLeft = ((BOMB_DETONATE_TIME - (client.getTickCount() -
|
||||
bomb.getTickStarted())) * ESTIMATED_TICK_LENGTH) -
|
||||
(now.toEpochMilli() - bomb.getLastClockUpdate().toEpochMilli()) / 1000.0;
|
||||
//divided by 1000.00 because of milliseconds :)
|
||||
|
||||
timeLeft = Math.max(0.0, timeLeft);
|
||||
String bombTimerString = TIME_LEFT_FORMATTER.format(timeLeft);
|
||||
int textWidth = graphics.getFontMetrics().stringWidth(bombTimerString);
|
||||
int textHeight = graphics.getFontMetrics().getAscent();
|
||||
Point canvasPoint = Perspective.localToCanvas(client, localLoc.getX(),
|
||||
localLoc.getY(), bomb.getWorldLocation().getPlane());
|
||||
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX() - textWidth / 2,
|
||||
canvasPoint.getY() + textHeight / 2);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, bombTimerString, color_code);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, PallasDieKatze (Pallas Cat)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import java.time.Instant;
|
||||
|
||||
@Slf4j
|
||||
public class CrystalBomb
|
||||
{
|
||||
@Getter
|
||||
private Instant plantedOn;
|
||||
|
||||
@Getter
|
||||
private Instant lastClockUpdate;
|
||||
|
||||
@Getter
|
||||
private int objectId;
|
||||
|
||||
@Getter
|
||||
private int tickStarted;
|
||||
//
|
||||
|
||||
@Getter
|
||||
private WorldPoint worldLocation;
|
||||
|
||||
public CrystalBomb(GameObject gameObject, int startTick)
|
||||
{
|
||||
this.plantedOn = Instant.now();
|
||||
this.objectId = gameObject.getId();
|
||||
this.worldLocation = gameObject.getWorldLocation();
|
||||
this.tickStarted = startTick;
|
||||
}
|
||||
|
||||
public void bombClockUpdate()
|
||||
{
|
||||
lastClockUpdate = Instant.now();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* 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.batools;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("BATools")
|
||||
public interface BAToolsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "defTimer",
|
||||
name = "Defender Tick Timer",
|
||||
description = "Shows the current cycle tick of runners."
|
||||
)
|
||||
default boolean defTimer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "calls",
|
||||
name = "Remove Incorrect Calls",
|
||||
description = "Remove incorrect calls."
|
||||
)
|
||||
default boolean calls()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapLadder",
|
||||
name = "Swap ladder option",
|
||||
description = "Swap Climb-down with Quick-start in the wave lobbies"
|
||||
)
|
||||
default boolean swapLadder()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerCodes",
|
||||
name = "Healer Codes",
|
||||
description = "Overlay to show healer codes"
|
||||
)
|
||||
default boolean healerCodes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerMenuOption",
|
||||
name = "Healer menu options",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean healerMenuOption()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "antiDrag",
|
||||
name = "Anti Drag",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean antiDrag()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "antiDragDelay",
|
||||
name = "Anti Drag Delay",
|
||||
description = "asd"
|
||||
)
|
||||
default int antiDragDelay()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "eggBoi",
|
||||
name = "Collector helper",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean eggBoi()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "osHelp",
|
||||
name = "Shift OS",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean osHelp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
|
||||
public class BAToolsOverlay extends Overlay
|
||||
{
|
||||
private static final Color RED = new Color(221, 44, 0);
|
||||
private static final Color GREEN = new Color(0, 200, 83);
|
||||
private static final Color ORANGE = new Color(255, 109, 0);
|
||||
private static final Color YELLOW = new Color(255, 214, 0);
|
||||
private static final Color CYAN = new Color(0, 184, 212);
|
||||
private static final Color BLUE = new Color(41, 98, 255);
|
||||
private static final Color DEEP_PURPLE = new Color(98, 0, 234);
|
||||
private static final Color PURPLE = new Color(170, 0, 255);
|
||||
private static final Color GRAY = new Color(158, 158, 158);
|
||||
|
||||
private final BAToolsConfig config;
|
||||
private Client client;
|
||||
private BAToolsPlugin plugin;
|
||||
|
||||
@Inject
|
||||
public BAToolsOverlay(Client client, BAToolsPlugin plugin, BAToolsConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if(!config.healerCodes())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Healer healer : plugin.getHealers().values())
|
||||
{
|
||||
NPCComposition composition = healer.getNpc().getComposition();
|
||||
Color color = composition.getCombatLevel() > 1 ? YELLOW : ORANGE;
|
||||
if (composition.getConfigs() != null)
|
||||
{
|
||||
NPCComposition transformedComposition = composition.transform();
|
||||
if (transformedComposition == null)
|
||||
{
|
||||
color = GRAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
composition = transformedComposition;
|
||||
}
|
||||
}
|
||||
int timeLeft = healer.getLastFoodTime() - (int)Duration.between(plugin.getWave_start(), Instant.now()).getSeconds();
|
||||
timeLeft = timeLeft < 1 ? 0 : timeLeft;
|
||||
|
||||
if(healer.getFoodRemaining() > 1)
|
||||
{
|
||||
color = GREEN;
|
||||
}
|
||||
else if(healer.getFoodRemaining() == 1)
|
||||
{
|
||||
if(timeLeft > 0)
|
||||
{
|
||||
color = RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = GREEN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String text = String.format("%d %d",
|
||||
healer.getFoodRemaining(),
|
||||
timeLeft);
|
||||
|
||||
|
||||
|
||||
OverlayUtil.renderActorOverlay(graphics, healer.getNpc(), text, color);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* Copyright (c) 2018, Jacob M <https://github.com/jacoblairm>
|
||||
* 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.batools;
|
||||
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.HitsplatApplied;
|
||||
import net.runelite.api.events.InteractingChanged;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "BA Tools",
|
||||
description = "Custom tools for Barbarian Assault",
|
||||
tags = {"minigame", "overlay", "timer"}
|
||||
)
|
||||
public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
int inGameBit = 0;
|
||||
int tickNum;
|
||||
int pastCall = 0;
|
||||
private int currentWave = 1;
|
||||
private static final int BA_WAVE_NUM_INDEX = 2;
|
||||
private final List<MenuEntry> entries = new ArrayList<>();
|
||||
private HashMap<Integer, Instant> foodPressed = new HashMap<>();
|
||||
private CycleCounter counter;
|
||||
private Actor lastInteracted;
|
||||
|
||||
private boolean shiftDown;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private BAToolsConfig config;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private BAToolsOverlay overlay;
|
||||
|
||||
@Getter
|
||||
private Map<NPC, Healer> healers;
|
||||
|
||||
@Getter
|
||||
private Instant wave_start;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
|
||||
@Provides
|
||||
BAToolsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BAToolsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
healers = new HashMap<>();
|
||||
wave_start = Instant.now();
|
||||
lastInteracted = null;
|
||||
foodPressed.clear();
|
||||
client.setInventoryDragDelay(config.antiDragDelay());
|
||||
keyManager.registerKeyListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
removeCounter();
|
||||
healers.clear();
|
||||
inGameBit = 0;
|
||||
lastInteracted = null;
|
||||
overlayManager.remove(overlay);
|
||||
client.setInventoryDragDelay(5);
|
||||
keyManager.unregisterKeyListener(this);
|
||||
shiftDown = false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
switch (event.getGroupId())
|
||||
{
|
||||
case WidgetID.BA_REWARD_GROUP_ID:
|
||||
{
|
||||
Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT);
|
||||
|
||||
if (rewardWidget != null && rewardWidget.getText().contains("<br>5"))
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (config.antiDrag())
|
||||
{
|
||||
client.setInventoryDragDelay(config.antiDragDelay());
|
||||
}
|
||||
|
||||
Widget callWidget = getWidget();
|
||||
|
||||
if (callWidget != null)
|
||||
{
|
||||
if (callWidget.getTextColor() != pastCall && callWidget.getTextColor() == 16316664)
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
pastCall = callWidget.getTextColor();
|
||||
}
|
||||
if (inGameBit == 1)
|
||||
{
|
||||
if (tickNum > 9)
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
if (counter == null)
|
||||
{
|
||||
addCounter();
|
||||
}
|
||||
//counter.setText(String.valueOf(tickNum));
|
||||
counter.setCount(tickNum);
|
||||
if (config.defTimer())
|
||||
{
|
||||
log.info("" + tickNum++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Widget getWidget()
|
||||
{
|
||||
if (client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_DEF_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_ATK_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_COLL_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
int inGame = client.getVar(Varbits.IN_GAME_BA);
|
||||
|
||||
if (inGameBit != inGame)
|
||||
{
|
||||
if (inGameBit == 1)
|
||||
{
|
||||
pastCall = 0;
|
||||
removeCounter();
|
||||
foodPressed.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
addCounter();
|
||||
}
|
||||
}
|
||||
|
||||
inGameBit = inGame;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (event.getType() == ChatMessageType.CONSOLE
|
||||
&& event.getMessage().startsWith("---- Wave:"))
|
||||
{
|
||||
String[] message = event.getMessage().split(" ");
|
||||
currentWave = Integer.parseInt(message[BA_WAVE_NUM_INDEX]);
|
||||
wave_start = Instant.now();
|
||||
healers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
if (isNpcHealer(npc.getId()))
|
||||
{
|
||||
if (checkNewSpawn(npc) || Duration.between(wave_start, Instant.now()).getSeconds() < 16)
|
||||
{
|
||||
int spawnNumber = healers.size();
|
||||
healers.put(npc, new Healer(npc, spawnNumber, currentWave));
|
||||
log.info("spawn number: " + spawnNumber + " on wave " + currentWave);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onHitsplatApplied(HitsplatApplied hitsplatApplied)
|
||||
{
|
||||
Actor actor = hitsplatApplied.getActor();
|
||||
|
||||
if (healers.isEmpty() && !(actor instanceof NPC) && lastInteracted == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Healer healer : healers.values())
|
||||
{
|
||||
if (healer.getNpc() == actor && actor == lastInteracted)
|
||||
{
|
||||
healer.setFoodRemaining(healer.getFoodRemaining() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (healers.remove(event.getNpc()) != null && healers.isEmpty())
|
||||
{
|
||||
healers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractingChanged(InteractingChanged event)
|
||||
{
|
||||
Actor opponent = event.getTarget();
|
||||
|
||||
if (opponent != null && opponent instanceof NPC && isNpcHealer(((NPC) opponent).getId()) && event.getSource() != client.getLocalPlayer())
|
||||
{
|
||||
lastInteracted = opponent;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNpcHealer(int npcId)
|
||||
{
|
||||
return npcId == NpcID.PENANCE_HEALER ||
|
||||
npcId == NpcID.PENANCE_HEALER_5766 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5767 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5768 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5769 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5770 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5771 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5772 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5773 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5774;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (config.calls() && getWidget() != null && event.getTarget().endsWith("horn") && !event.getTarget().contains("Unicorn"))
|
||||
{
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
Widget callWidget = getWidget();
|
||||
String call = Calls.getOption(callWidget.getText());
|
||||
MenuEntry correctCall = null;
|
||||
|
||||
entries.clear();
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
String option = entry.getOption();
|
||||
if (option.equals(call))
|
||||
{
|
||||
correctCall = entry;
|
||||
}
|
||||
else if (!option.startsWith("Tell-"))
|
||||
{
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (correctCall != null) //&& callWidget.getTextColor()==16316664)
|
||||
{
|
||||
entries.add(correctCall);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
}
|
||||
else if (config.calls() && event.getTarget().endsWith("horn"))
|
||||
{
|
||||
entries.clear();
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
|
||||
String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder"))
|
||||
{
|
||||
swap("quick-start", option, target, true);
|
||||
}
|
||||
|
||||
if (inGameBit == 1 && config.healerMenuOption() && event.getTarget().contains("Penance Healer"))
|
||||
{
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
|
||||
String targett = lastEntry.getTarget();
|
||||
|
||||
if (foodPressed.containsKey(lastEntry.getIdentifier()))
|
||||
{
|
||||
lastEntry.setTarget(lastEntry.getTarget().split("\\(")[0] + "(" + Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() + ")");
|
||||
if (Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() > 20)
|
||||
{
|
||||
lastEntry.setTarget(lastEntry.getTarget().replace("<col=ffff00>", "<col=2bff63>"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastEntry.setTarget(targett.replace("<col=ffff00>", "<col=2bff63>"));
|
||||
|
||||
}
|
||||
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
|
||||
if (client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT) != null && inGameBit == 1 && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown)
|
||||
{
|
||||
String[] currentCall = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT).getText().split(" ");
|
||||
log.info("1 " + currentCall[0]);
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry correctEgg = null;
|
||||
entries.clear();
|
||||
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if (entry.getTarget().contains(currentCall[0]) && entry.getOption().equals("Take"))
|
||||
{
|
||||
correctEgg = entry;
|
||||
}
|
||||
}
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
if (client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT) != null && inGameBit == 1 && config.osHelp() && event.getTarget().equals("<col=ffff>Healer item machine") && shiftDown)
|
||||
{
|
||||
String[] currentCall = client.getWidget(WidgetInfo.BA_HEAL_LISTEN_TEXT).getText().split(" ");
|
||||
|
||||
if (!currentCall[0].contains("Pois."))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry correctEgg = null;
|
||||
entries.clear();
|
||||
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if (entry.getOption().equals("Take-" + currentCall[1]))
|
||||
{
|
||||
correctEgg = entry;
|
||||
}
|
||||
}
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[entries.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String currentCall = client.getWidget(WidgetInfo.BA_HEAL_CALL_TEXT).getText();
|
||||
String target = event.getMenuTarget();
|
||||
|
||||
if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer")))
|
||||
|| (currentCall.equals("Pois. Meat") && (target.contains("Poisoned meat") && target.contains("->") && target.contains("Penance Healer")))
|
||||
|| (currentCall.equals("Pois. Tofu") && (target.contains("Poisoned tofu") && target.contains("->") && target.contains("Penance Healer"))))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
}
|
||||
|
||||
if (target.contains("->") && target.contains("Penance Healer"))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (config.antiDrag())
|
||||
{
|
||||
client.setInventoryDragDelay(config.antiDragDelay());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addCounter()
|
||||
{
|
||||
if (!config.defTimer() || counter != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int itemSpriteId = ItemID.FIGHTER_TORSO;
|
||||
|
||||
BufferedImage taskImg = itemManager.getImage(itemSpriteId);
|
||||
counter = new CycleCounter(taskImg, this, tickNum);
|
||||
|
||||
infoBoxManager.addInfoBox(counter);
|
||||
}
|
||||
|
||||
private void removeCounter()
|
||||
{
|
||||
if (counter == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
infoBoxManager.removeInfoBox(counter);
|
||||
counter = null;
|
||||
}
|
||||
|
||||
private void swap(String optionA, String optionB, String target, boolean strict)
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
|
||||
int idxA = searchIndex(entries, optionA, target, strict);
|
||||
int idxB = searchIndex(entries, optionB, target, strict);
|
||||
|
||||
if (idxA >= 0 && idxB >= 0)
|
||||
{
|
||||
MenuEntry entry = entries[idxA];
|
||||
entries[idxA] = entries[idxB];
|
||||
entries[idxB] = entry;
|
||||
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
|
||||
private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict)
|
||||
{
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
{
|
||||
MenuEntry entry = entries[i];
|
||||
String entryOption = Text.removeTags(entry.getOption()).toLowerCase();
|
||||
String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase();
|
||||
|
||||
if (strict)
|
||||
{
|
||||
if (entryOption.equals(option) && entryTarget.equals(target))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static WorldPoint rotate(WorldPoint point, int rotation)
|
||||
{
|
||||
int chunkX = point.getX() & ~(CHUNK_SIZE - 1);
|
||||
int chunkY = point.getY() & ~(CHUNK_SIZE - 1);
|
||||
int x = point.getX() & (CHUNK_SIZE - 1);
|
||||
int y = point.getY() & (CHUNK_SIZE - 1);
|
||||
switch (rotation)
|
||||
{
|
||||
case 1:
|
||||
return new WorldPoint(chunkX + y, chunkY + (CHUNK_SIZE - 1 - x), point.getPlane());
|
||||
case 2:
|
||||
return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - x), chunkY + (CHUNK_SIZE - 1 - y), point.getPlane());
|
||||
case 3:
|
||||
return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - y), chunkY + x, point.getPlane());
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
private boolean checkNewSpawn(NPC npc)
|
||||
{
|
||||
int regionId = 7509;
|
||||
int regionX = 42;
|
||||
int regionY = 46;
|
||||
int z = 0;
|
||||
|
||||
// world point of the tile marker
|
||||
WorldPoint worldPoint = new WorldPoint(
|
||||
((regionId >>> 8) << 6) + regionX,
|
||||
((regionId & 0xff) << 6) + regionY,
|
||||
z
|
||||
);
|
||||
|
||||
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
||||
for (int x = 0; x < instanceTemplateChunks[z].length; ++x)
|
||||
{
|
||||
for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y)
|
||||
{
|
||||
int chunkData = instanceTemplateChunks[z][x][y];
|
||||
int rotation = chunkData >> 1 & 0x3;
|
||||
int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
||||
int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
||||
if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE
|
||||
&& worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE)
|
||||
{
|
||||
WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)),
|
||||
client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)),
|
||||
worldPoint.getPlane());
|
||||
p = rotate(p, rotation);
|
||||
if (p.distanceTo(npc.getWorldLocation()) < 5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Cameron <https://github.com/noremac201>
|
||||
* 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.batools;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum Calls
|
||||
{
|
||||
//Attacker Calls
|
||||
RED_EGG("Red egg", "Tell-red"),
|
||||
GREEN_EGG("Green egg", "Tell-green"),
|
||||
BLUE_EGG("Blue egg", "Tell-blue"),
|
||||
//Collector Calls
|
||||
CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"),
|
||||
ACCURATE("Accurate/Field/Water", "Tell-accurate"),
|
||||
AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"),
|
||||
DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"),
|
||||
//Healer Calls
|
||||
TOFU("Tofu", "Tell-tofu"),
|
||||
CRACKERS("Crackers", "Tell-crackers"),
|
||||
WORMS("Worms", "Tell-worms"),
|
||||
//Defender Calls
|
||||
POIS_WORMS("Pois. Worms", "Tell-worms"),
|
||||
POIS_TOFU("Pois. Tofu", "Tell-tofu"),
|
||||
POIS_MEAT("Pois. Meat", "Tell-meat");
|
||||
|
||||
private final String call;
|
||||
private final String option;
|
||||
|
||||
private static final Map<String, String> CALL_MENU = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for (Calls s : values())
|
||||
{
|
||||
CALL_MENU.put(s.getCall(), s.getOption());
|
||||
}
|
||||
}
|
||||
|
||||
Calls(String call, String option)
|
||||
{
|
||||
this.call = call;
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public String getCall()
|
||||
{
|
||||
return call;
|
||||
}
|
||||
|
||||
public String getOption()
|
||||
{
|
||||
return option;
|
||||
}
|
||||
|
||||
public static String getOption(String call)
|
||||
{
|
||||
return CALL_MENU.get(call);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.ui.overlay.infobox.Counter;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class CycleCounter extends Counter
|
||||
{
|
||||
public CycleCounter(BufferedImage img, Plugin plugin, int tick)
|
||||
{
|
||||
super(img, plugin, tick);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Actor;
|
||||
|
||||
|
||||
public class Healer
|
||||
{
|
||||
|
||||
@Getter
|
||||
private NPC npc;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int wave;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int spawnNumber;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int foodRemaining;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int lastFoodTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int firstCallFood;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int secondCallFood;
|
||||
|
||||
|
||||
|
||||
public Healer(NPC npc, int spawnNumber, int wave)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.wave = wave;
|
||||
this.spawnNumber = spawnNumber;
|
||||
this.firstCallFood = getCode(wave).getFirstCallFood()[spawnNumber];
|
||||
this.secondCallFood = getCode(wave).getSecondCallFood()[spawnNumber];
|
||||
this.foodRemaining = firstCallFood + secondCallFood;
|
||||
this.lastFoodTime = getCode(wave).getSpacing()[spawnNumber];
|
||||
}
|
||||
|
||||
private HealerCode getCode(int wave)
|
||||
{
|
||||
switch(wave)
|
||||
{
|
||||
case 1:
|
||||
return HealerCode.WAVEONE;
|
||||
case 2:
|
||||
return HealerCode.WAVETWO;
|
||||
case 3:
|
||||
return HealerCode.WAVETHREE;
|
||||
case 4:
|
||||
return HealerCode.WAVEFOUR;
|
||||
case 5:
|
||||
return HealerCode.WAVEFIVE;
|
||||
case 6:
|
||||
return HealerCode.WAVESIX;
|
||||
case 7:
|
||||
return HealerCode.WAVESEVEN;
|
||||
case 8:
|
||||
return HealerCode.WAVEEIGHT;
|
||||
case 9:
|
||||
return HealerCode.WAVENINE;
|
||||
case 10:
|
||||
return HealerCode.WAVETEN;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
enum HealerCode
|
||||
{
|
||||
|
||||
WAVEONE(new int[] {1,1}, new int[] {0,0}, new int[] {0,0}),
|
||||
WAVETWO(new int[] {1,1,2}, new int[] {0,0,0}, new int[] {0,0,21}),
|
||||
WAVETHREE(new int[] {1,6,2}, new int[] {0,0,0}, new int[] {0,0,0}),
|
||||
WAVEFOUR(new int[] {2,5,2,0}, new int[] {0,0,7,10}, new int[] {0,0,0,0}),
|
||||
WAVEFIVE(new int[] {2,5,2,3,0}, new int[] {0,0,0,0,7}, new int[] {0,0,21,30,0}),
|
||||
WAVESIX(new int[] {3,5,3,1,0,0}, new int[] {0,0,0,2,9,10}, new int[] {18,0,0,0,0,0}),
|
||||
WAVESEVEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,0,0,0,6,8,10}, new int[] {27,33,0,0,51,0,0}),
|
||||
WAVEEIGHT(new int[] {2,8,1,1,0,0,0}, new int[] {1,0,1,1,3,1,10}, new int[] {36,0,33,39,45,48,0}),
|
||||
WAVENINE(new int[] {2,8,1,1,0,0,0,0}, new int[] {1,1,1,1,1,1,1,10}, new int[] {0,21,0,0,0,0,0,0,0}),
|
||||
WAVETEN(new int[] {5,2,1,1,0,0,0}, new int[] {0,1,1,1,3,3,10}, new int[] {27,33,0,0,51,0,0});
|
||||
|
||||
|
||||
@Getter
|
||||
private final int[] firstCallFood;
|
||||
@Getter
|
||||
private final int[] secondCallFood;
|
||||
@Getter
|
||||
private final int[] spacing;
|
||||
|
||||
HealerCode(int[] firstCallFood, int[] secondCallFood, int[] spacing)
|
||||
{
|
||||
this.firstCallFood = firstCallFood;
|
||||
this.secondCallFood = secondCallFood;
|
||||
this.spacing = spacing;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("clanmanmode")
|
||||
public interface ClanManModeConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "highlightattackable",
|
||||
name = "Highlight attackable targets",
|
||||
description = "Highlights targets attackable by all clan members"
|
||||
)
|
||||
default boolean highlightAttackable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "attackablecolor",
|
||||
name = "Attackable target c olor",
|
||||
description = "Color of targets all clan members can target"
|
||||
)
|
||||
default Color getAttackableColor()
|
||||
{
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "highlightattacked",
|
||||
name = "Highlight clan targets",
|
||||
description = "Highlights people being attacked by your clan"
|
||||
)
|
||||
default boolean highlightAttacked()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "attackedcolor",
|
||||
name = "Clan target color",
|
||||
description = "Color of players being attacked by clan"
|
||||
)
|
||||
default Color getClanAttackableColor()
|
||||
{
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "drawPlayerTiles",
|
||||
name = "Draw tiles under players",
|
||||
description = "Configures whether or not tiles under highlighted players should be drawn"
|
||||
)
|
||||
default boolean drawTiles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "drawOverheadPlayerNames",
|
||||
name = "Draw names above players",
|
||||
description = "Configures whether or not player names should be drawn above players"
|
||||
)
|
||||
default boolean drawOverheadPlayerNames()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "drawMinimapNames",
|
||||
name = "Draw names on minimap",
|
||||
description = "Configures whether or not minimap names for players with rendered names should be drawn"
|
||||
)
|
||||
default boolean drawMinimapNames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "showtargets",
|
||||
name = "Highlight My Attackers",
|
||||
description = "Shows players interacting with you"
|
||||
)
|
||||
default boolean showAttackers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "attackcolor",
|
||||
name = "Attacker Color",
|
||||
description = "Color of attackers"
|
||||
)
|
||||
default Color getAttackerColor()
|
||||
{
|
||||
return new Color(255, 0, 0);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "showbold",
|
||||
name = "Bold names of clan targets",
|
||||
description = "Turns names of clan targets bold"
|
||||
)
|
||||
default boolean ShowBold() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "hideafter",
|
||||
name = "Hide attackable targets after login",
|
||||
description = "Automatically disables attackable player highlighting after login"
|
||||
)
|
||||
default boolean hideAttackable() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "hidetime",
|
||||
name = "Ticks to hide",
|
||||
description = "How many ticks after you are logged in that attackbles are hidden (1 tick = 0.6 seconds)"
|
||||
)
|
||||
default int hideTime() { return 5; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "mycblvl",
|
||||
name = "Calc targets on my own combat level",
|
||||
description = "Calculates potential targets based off your own combat lvl instead of clans"
|
||||
)
|
||||
default boolean CalcSelfCB() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "hideatkopt",
|
||||
name = "Hide attack option for clan members",
|
||||
description = "Disables attack option for clan members"
|
||||
)
|
||||
default boolean hideAtkOpt() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "showclanmembers",
|
||||
name = "Persistent Clan Members",
|
||||
description = "Will highlight clan members even when not in clan chat"
|
||||
)
|
||||
default boolean PersistentClan() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 15,
|
||||
keyName = "clancolor",
|
||||
name = "Clan Member Color",
|
||||
description = "Color of clan members"
|
||||
)
|
||||
default Color getClanMemberColor()
|
||||
{
|
||||
return new Color(255, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class ClanManModeMinimapOverlay extends Overlay
|
||||
{
|
||||
private final ClanManModeService ClanManModeService;
|
||||
private final ClanManModeConfig config;
|
||||
|
||||
@Inject
|
||||
private ClanManModeMinimapOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService)
|
||||
{
|
||||
this.config = config;
|
||||
this.ClanManModeService = ClanManModeService;
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
final String name = actor.getName().replace('\u00A0', ' ');
|
||||
|
||||
if (config.drawMinimapNames())
|
||||
{
|
||||
final net.runelite.api.Point minimapLocation = actor.getMinimapLocation();
|
||||
|
||||
if (minimapLocation != null)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.ClanMemberRank;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class ClanManModeOverlay extends Overlay
|
||||
{
|
||||
private final ClanManModeService ClanManModeService;
|
||||
private final ClanManModeConfig config;
|
||||
private final ClanManager clanManager;
|
||||
|
||||
@Inject
|
||||
private ClanManModeOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService,
|
||||
ClanManager clanManager)
|
||||
{
|
||||
this.config = config;
|
||||
this.ClanManModeService = ClanManModeService;
|
||||
this.clanManager = clanManager;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
ClanManModeService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
if (!config.drawOverheadPlayerNames())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String name = actor.getName().replace('\u00A0', ' ');
|
||||
int offset = actor.getLogicalHeight() + 40;
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, name, offset);
|
||||
|
||||
if (textLocation != null)
|
||||
{
|
||||
if (config.getClanAttackableColor().equals(color) && config.ShowBold()) {
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"aqua\">!Clan Man Mode</font>",
|
||||
description = "Assists in clan PVP scenarios",
|
||||
tags = {"highlight", "minimap", "overlay", "players"}
|
||||
)
|
||||
public class ClanManModePlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private ClanManModeConfig config;
|
||||
|
||||
@Inject
|
||||
private ClanManModeOverlay ClanManModeOverlay;
|
||||
|
||||
@Inject
|
||||
private ClanManModeTileOverlay ClanManModeTileOverlay;
|
||||
|
||||
@Inject
|
||||
private ClanManModeMinimapOverlay ClanManModeMinimapOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClanManager clanManager;
|
||||
|
||||
@Provides
|
||||
ClanManModeConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(ClanManModeConfig.class);
|
||||
}
|
||||
|
||||
int wildernessLevel;
|
||||
int clanmin;
|
||||
int clanmax;
|
||||
int inwildy;
|
||||
int ticks;
|
||||
Map<String, Integer> clan = new HashMap<>();
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
overlayManager.add(ClanManModeOverlay);
|
||||
overlayManager.add(ClanManModeTileOverlay);
|
||||
overlayManager.add(ClanManModeMinimapOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
overlayManager.remove(ClanManModeOverlay);
|
||||
overlayManager.remove(ClanManModeTileOverlay);
|
||||
overlayManager.remove(ClanManModeMinimapOverlay);
|
||||
clan.clear();
|
||||
ticks = 0;
|
||||
wildernessLevel = 0;
|
||||
clanmin = 0;
|
||||
clanmax = 0;
|
||||
inwildy = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged) {
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN || gameStateChanged.getGameState() == GameState.HOPPING) {
|
||||
ticks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event) {
|
||||
ticks++;
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
if (!clan.containsKey(localPlayer.getName())) {
|
||||
clan.put(localPlayer.getName(), localPlayer.getCombatLevel());
|
||||
}
|
||||
WorldPoint a = localPlayer.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
inwildy = client.getVar(Varbits.IN_WILDERNESS);
|
||||
if (clan.size() > 0) {
|
||||
clanmin = Collections.min(clan.values());
|
||||
clanmax = Collections.max(clan.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event) {
|
||||
if (!config.hideAtkOpt()) {
|
||||
return;
|
||||
}
|
||||
if (client.getGameState() != GameState.LOGGED_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
|
||||
if (option.equals("attack")) {
|
||||
final Pattern ppattern = Pattern.compile("<col=ffffff>(.+?)<col=");
|
||||
final Matcher pmatch = ppattern.matcher(event.getTarget());
|
||||
pmatch.find();
|
||||
if (pmatch.matches()) {
|
||||
if (pmatch.group(1) != null) {
|
||||
if (clan.containsKey(pmatch.group(1).replace(" ", " "))) {
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
entries = ArrayUtils.removeElement(entries, entries[entries.length - 1]);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
|
||||
@Singleton
|
||||
public class ClanManModeService
|
||||
{
|
||||
private final Client client;
|
||||
private final ClanManModeConfig config;
|
||||
private final ClanManModePlugin plugin;
|
||||
|
||||
@Inject
|
||||
private ClanManModeService(Client client, ClanManModeConfig config, ClanManModePlugin plugin)
|
||||
{
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
Map<String, String> interactors = new HashMap<>();
|
||||
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
|
||||
{
|
||||
int minatk = plugin.clanmax - plugin.wildernessLevel;
|
||||
int maxatk = plugin.clanmin + plugin.wildernessLevel;
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
final String localName = localPlayer.getName();
|
||||
int selfmin = localPlayer.getCombatLevel() - plugin.wildernessLevel;
|
||||
int selfmax = localPlayer.getCombatLevel() + plugin.wildernessLevel;
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
if (player == null || player.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player == localPlayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isClanMember = player.isClanMember();
|
||||
Actor interacting = player.getInteracting();
|
||||
Player interactor = null;
|
||||
if (interacting != null && !(interacting instanceof NPC)) {
|
||||
interactor = ((Player) interacting);
|
||||
}
|
||||
|
||||
if (config.showAttackers()) {
|
||||
if (interactor != null) {
|
||||
if (interactor.getName().equals(localName)) {
|
||||
consumer.accept(player, config.getAttackerColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.inwildy == 1) {
|
||||
if (isClanMember) {
|
||||
if (!plugin.clan.containsKey(player.getName())) {
|
||||
plugin.clan.put(player.getName(), player.getCombatLevel());
|
||||
}
|
||||
if (config.highlightAttacked()) {
|
||||
if (interactor != null) {
|
||||
if (!interactors.containsKey(interactor.getName())) {
|
||||
WorldPoint a = interactor.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
int wildydiff = plugin.wildernessLevel - wildernessLevel;
|
||||
if (wildydiff < 0) {
|
||||
wildydiff = 0;
|
||||
}
|
||||
if (config.CalcSelfCB()) {
|
||||
if (interacting.getCombatLevel() <= selfmax && interacting.getCombatLevel() - wildydiff >= selfmin && !interactor.isClanMember()) {
|
||||
interactors.put(interactor.getName(), player.getName());
|
||||
consumer.accept(interactor, config.getClanAttackableColor());
|
||||
}
|
||||
} else {
|
||||
if (interacting.getCombatLevel() <= maxatk && interacting.getCombatLevel() - wildydiff >= minatk && !interactor.isClanMember()) {
|
||||
interactors.put(interactor.getName(), player.getName());
|
||||
consumer.accept(interactor, config.getClanAttackableColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (config.PersistentClan()) {
|
||||
if (plugin.clan.containsKey(player.getName())) {
|
||||
consumer.accept(player, config.getClanMemberColor());
|
||||
}
|
||||
}
|
||||
if (config.highlightAttacked()) {
|
||||
if (interactors.containsKey(player.getName())) {
|
||||
String attackername = interactors.get(player.getName());
|
||||
Boolean found = false;
|
||||
for (Player attacker : client.getPlayers()) {
|
||||
if (attacker == null || attacker.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
if (attacker.getName().equals(attackername)) {
|
||||
found = true;
|
||||
Actor ainteract = attacker.getInteracting();
|
||||
if (ainteract != null) {
|
||||
if (ainteract.getName().equals(player.getName())) {
|
||||
consumer.accept(player, config.getClanAttackableColor());
|
||||
} else {
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
} else {
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
interactors.remove(player.getName());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (config.highlightAttackable()) {
|
||||
if ((config.hideAttackable() && plugin.ticks >= config.hideTime()) || plugin.clan.containsKey(player.getName())) {
|
||||
continue;
|
||||
}
|
||||
WorldPoint a = player.getWorldLocation();
|
||||
int underLevel = ((a.getY() - 9920) / 8) + 1;
|
||||
int upperLevel = ((a.getY() - 3520) / 8) + 1;
|
||||
int wildernessLevel = a.getY() > 6400 ? underLevel : upperLevel;
|
||||
int wildydiff = plugin.wildernessLevel - wildernessLevel;
|
||||
if (wildydiff < 0) {
|
||||
wildydiff = 0;
|
||||
}
|
||||
if (config.CalcSelfCB()) {
|
||||
if (player.getCombatLevel() <= selfmax && player.getCombatLevel() - wildydiff >= selfmin) {
|
||||
consumer.accept(player, config.getAttackableColor());
|
||||
}
|
||||
} else {
|
||||
if (player.getCombatLevel() <= maxatk && player.getCombatLevel() - wildydiff >= minatk) {
|
||||
consumer.accept(player, config.getAttackableColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.runelite.client.plugins.clanmanmode;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class ClanManModeTileOverlay extends Overlay
|
||||
{
|
||||
private final ClanManModeService ClanManModeService;
|
||||
private final ClanManModeConfig config;
|
||||
|
||||
@Inject
|
||||
private ClanManModeTileOverlay(ClanManModeConfig config, ClanManModeService ClanManModeService)
|
||||
{
|
||||
this.config = config;
|
||||
this.ClanManModeService = ClanManModeService;
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!config.drawTiles())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ClanManModeService.forEachPlayer((player, color) ->
|
||||
{
|
||||
final Polygon poly = player.getCanvasTilePoly();
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ public class ConfigPanel extends PluginPanel
|
||||
}
|
||||
|
||||
ConfigPanel(PluginManager pluginManager, ConfigManager configManager, ScheduledExecutorService executorService,
|
||||
RuneLiteConfig runeLiteConfig, ChatColorConfig chatColorConfig)
|
||||
RuneLiteConfig runeLiteConfig, ChatColorConfig chatColorConfig)
|
||||
{
|
||||
super(false);
|
||||
this.pluginManager = pluginManager;
|
||||
@@ -195,28 +195,28 @@ public class ConfigPanel extends PluginPanel
|
||||
|
||||
// populate pluginList with all non-hidden plugins
|
||||
pluginManager.getPlugins().stream()
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
|
||||
.forEach(plugin ->
|
||||
{
|
||||
final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
||||
final Config config = pluginManager.getPluginConfigProxy(plugin);
|
||||
final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
|
||||
.filter(plugin -> !plugin.getClass().getAnnotation(PluginDescriptor.class).hidden())
|
||||
.forEach(plugin ->
|
||||
{
|
||||
final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
|
||||
final Config config = pluginManager.getPluginConfigProxy(plugin);
|
||||
final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
|
||||
|
||||
final PluginListItem listItem = new PluginListItem(this, plugin, descriptor, config, configDescriptor);
|
||||
listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
|
||||
pluginList.add(listItem);
|
||||
});
|
||||
final PluginListItem listItem = new PluginListItem(this, plugin, descriptor, config, configDescriptor);
|
||||
listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
|
||||
pluginList.add(listItem);
|
||||
});
|
||||
|
||||
// add special entries for core client configurations
|
||||
final PluginListItem runeLite = new PluginListItem(this, runeLiteConfig,
|
||||
configManager.getConfigDescriptor(runeLiteConfig),
|
||||
RUNELITE_PLUGIN, "RuneLite client settings", "client");
|
||||
configManager.getConfigDescriptor(runeLiteConfig),
|
||||
RUNELITE_PLUGIN, "RuneLite client settings", "client");
|
||||
runeLite.setPinned(pinnedPlugins.contains(RUNELITE_PLUGIN));
|
||||
pluginList.add(runeLite);
|
||||
|
||||
final PluginListItem chatColor = new PluginListItem(this, chatColorConfig,
|
||||
configManager.getConfigDescriptor(chatColorConfig),
|
||||
CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages");
|
||||
configManager.getConfigDescriptor(chatColorConfig),
|
||||
CHAT_COLOR_PLUGIN, "Recolor chat text", "colour", "messages");
|
||||
chatColor.setPinned(pinnedPlugins.contains(CHAT_COLOR_PLUGIN));
|
||||
pluginList.add(chatColor);
|
||||
|
||||
@@ -421,7 +421,7 @@ public class ConfigPanel extends PluginPanel
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
RuneliteColorPicker colorPicker = new RuneliteColorPicker(SwingUtilities.windowForComponent(ConfigPanel.this),
|
||||
colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null);
|
||||
colorPickerBtn.getBackground(), cid.getItem().name(), cid.getAlpha() == null);
|
||||
colorPicker.setLocation(getLocationOnScreen());
|
||||
colorPicker.setOnColorChange(c ->
|
||||
{
|
||||
@@ -467,7 +467,7 @@ public class ConfigPanel extends PluginPanel
|
||||
heightSpinnerTextField.setColumns(4);
|
||||
|
||||
ChangeListener listener = e ->
|
||||
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue());
|
||||
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), widthSpinner.getValue() + "x" + heightSpinner.getValue());
|
||||
|
||||
widthSpinner.addChangeListener(listener);
|
||||
heightSpinner.addChangeListener(listener);
|
||||
@@ -512,8 +512,8 @@ public class ConfigPanel extends PluginPanel
|
||||
if (cid.getType() == Keybind.class || cid.getType() == ModifierlessKeybind.class)
|
||||
{
|
||||
Keybind startingValue = configManager.getConfiguration(cd.getGroup().value(),
|
||||
cid.getItem().keyName(),
|
||||
(Class<? extends Keybind>) cid.getType());
|
||||
cid.getItem().keyName(),
|
||||
(Class<? extends Keybind>) cid.getType());
|
||||
|
||||
HotkeyButton button = new HotkeyButton(startingValue, cid.getType() == ModifierlessKeybind.class);
|
||||
|
||||
@@ -536,8 +536,8 @@ public class ConfigPanel extends PluginPanel
|
||||
resetButton.addActionListener((e) ->
|
||||
{
|
||||
final int result = JOptionPane.showOptionDialog(resetButton, "Are you sure you want to reset this plugin's configuration?",
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
|
||||
if (result == JOptionPane.YES_OPTION)
|
||||
{
|
||||
@@ -564,8 +564,8 @@ public class ConfigPanel extends PluginPanel
|
||||
if (!Strings.isNullOrEmpty(configItem.warning()))
|
||||
{
|
||||
final int result = JOptionPane.showOptionDialog(component, configItem.warning(),
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||
null, new String[]{"Yes", "No"}, "No");
|
||||
|
||||
if (result != JOptionPane.YES_OPTION)
|
||||
{
|
||||
@@ -659,9 +659,9 @@ public class ConfigPanel extends PluginPanel
|
||||
void savePinnedPlugins()
|
||||
{
|
||||
final String value = pluginList.stream()
|
||||
.filter(PluginListItem::isPinned)
|
||||
.map(PluginListItem::getName)
|
||||
.collect(Collectors.joining(","));
|
||||
.filter(PluginListItem::isPinned)
|
||||
.map(PluginListItem::getName)
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
configManager.setConfiguration(RUNELITE_GROUP_NAME, PINNED_PLUGINS_CONFIG_KEY, value);
|
||||
}
|
||||
@@ -704,4 +704,4 @@ public class ConfigPanel extends PluginPanel
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,17 +99,17 @@ class PluginListItem extends JPanel
|
||||
ON_STAR = new ImageIcon(onStar);
|
||||
CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100));
|
||||
BufferedImage offSwitcherImage = ImageUtil.flipImage(
|
||||
ImageUtil.grayscaleOffset(
|
||||
ImageUtil.grayscaleImage(onSwitcher),
|
||||
0.61f
|
||||
),
|
||||
true,
|
||||
false
|
||||
ImageUtil.grayscaleOffset(
|
||||
ImageUtil.grayscaleImage(onSwitcher),
|
||||
0.61f
|
||||
),
|
||||
true,
|
||||
false
|
||||
);
|
||||
OFF_SWITCHER = new ImageIcon(offSwitcherImage);
|
||||
BufferedImage offStar = ImageUtil.grayscaleOffset(
|
||||
ImageUtil.grayscaleImage(onStar),
|
||||
0.77f
|
||||
ImageUtil.grayscaleImage(onStar),
|
||||
0.77f
|
||||
);
|
||||
OFF_STAR = new ImageIcon(offStar);
|
||||
}
|
||||
@@ -121,23 +121,23 @@ class PluginListItem extends JPanel
|
||||
* if there is no configuration associated with the plugin.
|
||||
*/
|
||||
PluginListItem(ConfigPanel configPanel, Plugin plugin, PluginDescriptor descriptor,
|
||||
@Nullable Config config, @Nullable ConfigDescriptor configDescriptor)
|
||||
@Nullable Config config, @Nullable ConfigDescriptor configDescriptor)
|
||||
{
|
||||
this(configPanel, plugin, config, configDescriptor,
|
||||
descriptor.name(), descriptor.description(), descriptor.tags());
|
||||
descriptor.name(), descriptor.description(), descriptor.tags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code PluginListItem} for a core configuration.
|
||||
*/
|
||||
PluginListItem(ConfigPanel configPanel, Config config, ConfigDescriptor configDescriptor,
|
||||
String name, String description, String... tags)
|
||||
String name, String description, String... tags)
|
||||
{
|
||||
this(configPanel, null, config, configDescriptor, name, description, tags);
|
||||
}
|
||||
|
||||
private PluginListItem(ConfigPanel configPanel, @Nullable Plugin plugin, @Nullable Config config,
|
||||
@Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags)
|
||||
@Nullable ConfigDescriptor configDescriptor, String name, String description, String... tags)
|
||||
{
|
||||
this.configPanel = configPanel;
|
||||
this.plugin = plugin;
|
||||
@@ -260,7 +260,7 @@ class PluginListItem extends JPanel
|
||||
for (String term : searchTerms)
|
||||
{
|
||||
if (keywords.stream().noneMatch((t) -> t.contains(term) ||
|
||||
DISTANCE.apply(t, term) > 0.9))
|
||||
DISTANCE.apply(t, term) > 0.9))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Aria <aria@ar1as.space>
|
||||
* 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.equipmentinspector;
|
||||
|
||||
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.grounditems.config.ItemHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.MenuHighlightMode;
|
||||
import net.runelite.client.plugins.grounditems.config.PriceDisplayMode;
|
||||
|
||||
@ConfigGroup("grounditems")
|
||||
public interface EquipmentInspectorConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "ShowValue",
|
||||
name = "Show the total value of the items",
|
||||
description = "shows the total value of the items",
|
||||
position = 1
|
||||
)
|
||||
default boolean ShowValue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ConfigItem(
|
||||
keyName = "protecteditems",
|
||||
name = "# of protected items",
|
||||
description = "Limit 4",
|
||||
position = 2
|
||||
)
|
||||
default int protecteditems()
|
||||
{ return 1; }
|
||||
@ConfigItem(
|
||||
keyName = "ExactValue",
|
||||
name = "Show exact value",
|
||||
description = "shows the excact gp value",
|
||||
position = 3
|
||||
)
|
||||
default boolean ExactValue()
|
||||
{ return false; }
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package net.runelite.client.plugins.equipmentinspector;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class EquipmentInspectorPanel extends PluginPanel
|
||||
{
|
||||
private final static String NO_PLAYER_SELECTED = "No player selected";
|
||||
|
||||
private GridBagConstraints c;
|
||||
private JPanel equipmentPanels;
|
||||
private JPanel header;
|
||||
private JLabel nameLabel;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
public EquipmentInspectorPanel()
|
||||
{
|
||||
GroupLayout layout = new GroupLayout(this);
|
||||
setLayout(layout);
|
||||
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
equipmentPanels = new JPanel(new GridBagLayout());
|
||||
c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.weightx = 1;
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
|
||||
header = new JPanel();
|
||||
header.setLayout(new BorderLayout());
|
||||
header.setBorder(new CompoundBorder(
|
||||
BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(58, 58, 58)),
|
||||
BorderFactory.createEmptyBorder(0, 0, 10, 0)));
|
||||
|
||||
nameLabel = new JLabel(NO_PLAYER_SELECTED);
|
||||
nameLabel.setForeground(Color.WHITE);
|
||||
|
||||
header.add(nameLabel, BorderLayout.CENTER);
|
||||
|
||||
layout.setHorizontalGroup(layout.createParallelGroup()
|
||||
.addComponent(equipmentPanels)
|
||||
.addComponent(header)
|
||||
);
|
||||
layout.setVerticalGroup(layout.createSequentialGroup()
|
||||
.addComponent(header)
|
||||
.addGap(10)
|
||||
.addComponent(equipmentPanels)
|
||||
);
|
||||
|
||||
update(new HashMap<>(), "");
|
||||
}
|
||||
|
||||
public void update(Map<KitType, ItemComposition> playerEquipment, String playerName)
|
||||
{
|
||||
if (playerName.isEmpty() || playerName == null)
|
||||
{
|
||||
nameLabel.setText(NO_PLAYER_SELECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
nameLabel.setText("Player: " + playerName);
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
equipmentPanels.removeAll();
|
||||
playerEquipment.forEach((kitType, itemComposition) ->
|
||||
{
|
||||
AsyncBufferedImage itemImage = itemManager.getImage(itemComposition.getId());
|
||||
equipmentPanels.add(new ItemPanel(itemComposition, kitType, itemImage), c);
|
||||
c.gridy++;
|
||||
|
||||
});
|
||||
header.revalidate();
|
||||
header.repaint();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
package net.runelite.client.plugins.equipmentinspector;
|
||||
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.PlayerMenuOptionClicked;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.http.api.item.ItemPrice;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!Equipment Inspector</font>",
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
|
||||
public class EquipmentInspectorPlugin extends Plugin {
|
||||
|
||||
private static final String INSPECT_EQUIPMENT = "Gear";
|
||||
private static final String KICK_OPTION = "Kick";
|
||||
|
||||
@Inject
|
||||
@Nullable
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private EquipmentInspectorConfig config;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
@Inject
|
||||
private MenuManager menuManager;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
@Inject
|
||||
private ClientToolbar pluginToolbar;
|
||||
|
||||
@Provides
|
||||
EquipmentInspectorConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(EquipmentInspectorConfig.class);
|
||||
}
|
||||
|
||||
private NavigationButton navButton;
|
||||
private EquipmentInspectorPanel equipmentInspectorPanel;
|
||||
private int TotalPrice = 0;
|
||||
private int Prot1 = 0;
|
||||
private int Prot2 = 0;
|
||||
private int Prot3 = 0;
|
||||
private int Prot4 = 0;
|
||||
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
|
||||
equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class);
|
||||
if(client != null) {
|
||||
menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT);
|
||||
}
|
||||
|
||||
BufferedImage icon;
|
||||
synchronized (ImageIO.class)
|
||||
{
|
||||
icon = ImageIO.read(getClass().getResourceAsStream("normal.png"));
|
||||
}
|
||||
|
||||
navButton = NavigationButton.builder()
|
||||
.tooltip("Equipment Inspector")
|
||||
.icon(icon)
|
||||
.priority(5)
|
||||
.panel(equipmentInspectorPanel)
|
||||
.build();
|
||||
|
||||
|
||||
pluginToolbar.addNavigation(navButton);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
|
||||
menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event)
|
||||
{
|
||||
if (event.getMenuOption().equals(INSPECT_EQUIPMENT))
|
||||
{
|
||||
|
||||
|
||||
executor.execute(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
SwingUtilities.invokeAndWait(() ->
|
||||
{
|
||||
if (!navButton.isSelected())
|
||||
{
|
||||
navButton.getOnSelect().run();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException e)
|
||||
{
|
||||
|
||||
throw new RuntimeException(e);
|
||||
|
||||
}
|
||||
String playerName = Text.removeTags(event.getMenuTarget());
|
||||
// The player menu uses a non-breaking space in the player name, we need to replace this to compare
|
||||
// against the playerName in the player cache.
|
||||
String finalPlayerName = playerName.replace('\u00A0', ' ');
|
||||
System.out.println(finalPlayerName);
|
||||
List<Player> players = client.getPlayers();
|
||||
Optional<Player> targetPlayer = players.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(p -> p.getName().equals(finalPlayerName)).findFirst();
|
||||
|
||||
if (targetPlayer.isPresent())
|
||||
{
|
||||
TotalPrice = 0;
|
||||
Prot1 = 0;
|
||||
Prot2 = 0;
|
||||
Prot3 = 0;
|
||||
Prot4 = 0;
|
||||
Player p = targetPlayer.get();
|
||||
Map<KitType, ItemComposition> playerEquipment = new HashMap<>();
|
||||
|
||||
for (KitType kitType : KitType.values())
|
||||
{
|
||||
int itemId = p.getPlayerComposition().getEquipmentId(kitType);
|
||||
if (itemId != -1)
|
||||
{
|
||||
ItemComposition itemComposition = client.getItemDefinition(itemId);
|
||||
playerEquipment.put(kitType, itemComposition);
|
||||
int ItemPrice = itemManager.getItemPrice(itemId);
|
||||
TotalPrice += ItemPrice;
|
||||
if (ItemPrice > Prot1 ) {
|
||||
Prot4 = Prot3;
|
||||
Prot3 = Prot2;
|
||||
Prot2 = Prot1;
|
||||
|
||||
Prot1 = ItemPrice;
|
||||
} else if (ItemPrice > Prot2){
|
||||
Prot4 = Prot3;
|
||||
Prot3 = Prot2;
|
||||
Prot2 = ItemPrice;
|
||||
} else if (ItemPrice > Prot3){
|
||||
Prot4 = Prot3;
|
||||
Prot3 = ItemPrice;
|
||||
} else if (ItemPrice > Prot4){
|
||||
Prot4 = ItemPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
int IgnoredItems = config.protecteditems();
|
||||
if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) {
|
||||
IgnoredItems = 4;
|
||||
|
||||
}
|
||||
if (config.ShowValue()) {
|
||||
switch (IgnoredItems) {
|
||||
case 1:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
break;
|
||||
case 2:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
TotalPrice = TotalPrice - Prot2;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
TotalPrice = TotalPrice - Prot2;
|
||||
TotalPrice = TotalPrice - Prot3;
|
||||
break;
|
||||
case 4:
|
||||
TotalPrice = TotalPrice - Prot1;
|
||||
TotalPrice = TotalPrice - Prot2;
|
||||
TotalPrice = TotalPrice - Prot3;
|
||||
TotalPrice = TotalPrice - Prot4;
|
||||
break;
|
||||
}
|
||||
String StringPrice = "";
|
||||
if (!config.ExactValue()) {
|
||||
TotalPrice = TotalPrice / 1000;
|
||||
StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice);
|
||||
StringPrice = StringPrice + 'K';
|
||||
}
|
||||
if (config.ExactValue()) {
|
||||
StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice);
|
||||
}
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("Risked Value: ")
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(StringPrice)
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
equipmentInspectorPanel.update(playerEquipment, playerName);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.runelite.client.plugins.equipmentinspector;
|
||||
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.game.AsyncBufferedImage;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
class ItemPanel extends JPanel
|
||||
{
|
||||
|
||||
ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon)
|
||||
{
|
||||
setBorder(new EmptyBorder(3, 3, 3, 3));
|
||||
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
|
||||
GroupLayout layout = new GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
|
||||
JLabel name = new JLabel(item.getName());
|
||||
|
||||
JLabel location = new JLabel(StringUtils.capitalize(kitType.toString().toLowerCase()));
|
||||
location.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
JLabel imageLabel = new JLabel();
|
||||
icon.addTo(imageLabel);
|
||||
|
||||
layout.setVerticalGroup(layout.createParallelGroup()
|
||||
.addComponent(imageLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
);
|
||||
|
||||
layout.setHorizontalGroup(layout.createSequentialGroup()
|
||||
.addComponent(imageLabel)
|
||||
.addGap(8)
|
||||
.addGroup(layout.createParallelGroup()
|
||||
.addComponent(name)
|
||||
.addComponent(location)
|
||||
)
|
||||
);
|
||||
|
||||
// AWT's Z order is weird. This put image at the back of the stack
|
||||
setComponentZOrder(imageLabel, getComponentCount() - 1);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 624 B |
@@ -0,0 +1,63 @@
|
||||
package net.runelite.client.plugins.fightcavejadhelper;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class FightCaveJadHelperOverlay extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final Client client;
|
||||
private final FightCaveJadHelperPlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private FightCaveJadHelperOverlay(Client client, FightCaveJadHelperPlugin plugin, SpriteManager spriteManager)
|
||||
{
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.spriteManager = spriteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final JadAttack attack = plugin.getAttack();
|
||||
|
||||
if (attack == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final BufferedImage prayerImage = getPrayerImage(attack);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer())
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(JadAttack attack)
|
||||
{
|
||||
final int prayerSpriteID = attack == JadAttack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES;
|
||||
return spriteManager.getSprite(prayerSpriteID, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package net.runelite.client.plugins.fightcavejadhelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Fight Cave - Jad</font>",
|
||||
description = "Show what to pray against Jad",
|
||||
tags = {"bosses", "combat", "minigame", "overlay", "prayer", "pve", "pvm"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class FightCaveJadHelperPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private FightCaveJadHelperOverlay overlay;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Nullable
|
||||
private JadAttack attack;
|
||||
|
||||
private NPC jad;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(final NpcSpawned event)
|
||||
{
|
||||
final int id = event.getNpc().getId();
|
||||
|
||||
if (id == NpcID.TZTOKJAD || id == NpcID.TZTOKJAD_6506)
|
||||
{
|
||||
jad = event.getNpc();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(final NpcDespawned event)
|
||||
{
|
||||
if (jad == event.getNpc())
|
||||
{
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(final AnimationChanged event)
|
||||
{
|
||||
if (event.getActor() != jad)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (jad.getAnimation() == JadAttack.MAGIC.getAnimation())
|
||||
{
|
||||
attack = JadAttack.MAGIC;
|
||||
}
|
||||
else if (jad.getAnimation() == JadAttack.RANGE.getAnimation())
|
||||
{
|
||||
attack = JadAttack.RANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.runelite.client.plugins.fightcavejadhelper;
|
||||
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Prayer;
|
||||
|
||||
public enum JadAttack
|
||||
{
|
||||
MAGIC(AnimationID.TZTOK_JAD_MAGIC_ATTACK, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE(AnimationID.TZTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES);
|
||||
|
||||
private final int animation;
|
||||
private final Prayer prayer;
|
||||
|
||||
JadAttack(int animation, Prayer prayer)
|
||||
{
|
||||
this.animation = animation;
|
||||
this.prayer = prayer;
|
||||
}
|
||||
|
||||
public int getAnimation()
|
||||
{
|
||||
return animation;
|
||||
}
|
||||
|
||||
public Prayer getPrayer()
|
||||
{
|
||||
return prayer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcavewavehelper;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("Fight Cave - Wave Helper")
|
||||
public interface FightCaveWaveHelperConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "waveDisplay",
|
||||
name = "Wave display",
|
||||
description = "Shows monsters that will spawn on the selected wave(s)."
|
||||
)
|
||||
default WaveDisplayMode waveDisplay()
|
||||
{
|
||||
return WaveDisplayMode.BOTH;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcavewavehelper;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Fight Cave - Waves</font>",
|
||||
description = "Displays current and upcoming wave monsters in the Fight Caves",
|
||||
tags = {"bosses", "combat", "minigame", "overlay", "pve", "pvm", "jad", "fire", "cape", "wave"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class FightCaveWaveHelperPlugin extends Plugin
|
||||
{
|
||||
private static final Pattern WAVE_PATTERN = Pattern.compile(".*Wave: (\\d+).*");
|
||||
private static final int FIGHT_CAVE_REGION = 9551;
|
||||
private static final int MAX_MONSTERS_OF_TYPE_PER_WAVE = 2;
|
||||
|
||||
static final int MAX_WAVE = 63;
|
||||
|
||||
@Getter
|
||||
static final List<EnumMap<WaveMonster, Integer>> WAVES = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private int currentWave = -1;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private WaveOverlay waveOverlay;
|
||||
|
||||
static
|
||||
{
|
||||
final WaveMonster[] waveMonsters = WaveMonster.values();
|
||||
|
||||
// Add wave 1, future waves are derived from its contents
|
||||
final EnumMap<WaveMonster, Integer> waveOne = new EnumMap<>(WaveMonster.class);
|
||||
waveOne.put(waveMonsters[0], 1);
|
||||
WAVES.add(waveOne);
|
||||
|
||||
for (int wave = 1; wave < MAX_WAVE; wave++)
|
||||
{
|
||||
final EnumMap<WaveMonster, Integer> prevWave = WAVES.get(wave - 1).clone();
|
||||
int maxMonsterOrdinal = -1;
|
||||
|
||||
for (int i = 0; i < waveMonsters.length; i++)
|
||||
{
|
||||
final int ordinalMonsterQuantity = prevWave.getOrDefault(waveMonsters[i], 0);
|
||||
|
||||
if (ordinalMonsterQuantity == MAX_MONSTERS_OF_TYPE_PER_WAVE)
|
||||
{
|
||||
maxMonsterOrdinal = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxMonsterOrdinal >= 0)
|
||||
{
|
||||
prevWave.remove(waveMonsters[maxMonsterOrdinal]);
|
||||
}
|
||||
|
||||
final int addedMonsterOrdinal = maxMonsterOrdinal >= 0 ? maxMonsterOrdinal + 1 : 0;
|
||||
final WaveMonster addedMonster = waveMonsters[addedMonsterOrdinal];
|
||||
final int addedMonsterQuantity = prevWave.getOrDefault(addedMonster, 0);
|
||||
|
||||
prevWave.put(addedMonster, addedMonsterQuantity + 1);
|
||||
|
||||
WAVES.add(prevWave);
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
FightCaveWaveHelperConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(FightCaveWaveHelperConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
overlayManager.add(waveOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
overlayManager.remove(waveOverlay);
|
||||
currentWave = -1;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inFightCave())
|
||||
{
|
||||
currentWave = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage());
|
||||
|
||||
if (event.getType() != ChatMessageType.GAMEMESSAGE
|
||||
|| !inFightCave()
|
||||
|| !waveMatcher.matches())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentWave = Integer.parseInt(waveMatcher.group(1));
|
||||
}
|
||||
|
||||
boolean inFightCave()
|
||||
{
|
||||
return ArrayUtils.contains(client.getMapRegions(), FIGHT_CAVE_REGION);
|
||||
}
|
||||
|
||||
static String formatMonsterQuantity(final WaveMonster monster, final int quantity)
|
||||
{
|
||||
return String.format("%dx %s", quantity, monster);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcavewavehelper;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum WaveDisplayMode
|
||||
{
|
||||
CURRENT("Current wave"),
|
||||
NEXT("Next wave"),
|
||||
BOTH("Both");
|
||||
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcavewavehelper;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
enum WaveMonster
|
||||
{
|
||||
TZ_KIH("Tz-Kih", 22),
|
||||
TZ_KEK("Tz-Kek", 45),
|
||||
TOK_XIL("Tok-Xil", 90),
|
||||
YT_MEJKOT("Yt-MejKot", 180),
|
||||
KET_ZEK("Ket-Zek", 360),
|
||||
TZKOK_JAD("TzTok-Jad", 702);
|
||||
|
||||
private final String name;
|
||||
private final int level;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s - Level %s", name, level);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcavewavehelper;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class WaveOverlay extends Overlay
|
||||
{
|
||||
private static final Color HEADER_COLOR = ColorScheme.BRAND_ORANGE;
|
||||
|
||||
private final FightCaveWaveHelperConfig config;
|
||||
private final FightCaveWaveHelperPlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private WaveOverlay(FightCaveWaveHelperConfig config, FightCaveWaveHelperPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.inFightCave()
|
||||
|| plugin.getCurrentWave() < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
final int currentWave = plugin.getCurrentWave();
|
||||
final int waveIndex = currentWave - 1;
|
||||
|
||||
if (config.waveDisplay() == WaveDisplayMode.CURRENT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex);
|
||||
|
||||
addWaveInfo("Wave " + plugin.getCurrentWave(), waveContents);
|
||||
}
|
||||
|
||||
if ((config.waveDisplay() == WaveDisplayMode.NEXT
|
||||
|| config.waveDisplay() == WaveDisplayMode.BOTH)
|
||||
&& currentWave != FightCaveWaveHelperPlugin.MAX_WAVE)
|
||||
{
|
||||
final Map<WaveMonster, Integer> waveContents = FightCaveWaveHelperPlugin.getWAVES().get(waveIndex + 1);
|
||||
|
||||
addWaveInfo("Next wave", waveContents);
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private void addWaveInfo(final String headerText, final Map<WaveMonster, Integer> waveContents)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text(headerText)
|
||||
.color(HEADER_COLOR)
|
||||
.build());
|
||||
|
||||
for (LineComponent line : buildWaveLines(waveContents))
|
||||
{
|
||||
panelComponent.getChildren().add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<LineComponent> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<WaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<LineComponent> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<WaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final WaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final LineComponent line = LineComponent.builder()
|
||||
.left(FightCaveWaveHelperPlugin.formatMonsterQuantity(monster, quantity))
|
||||
.build();
|
||||
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.client.plugins.freezetimers.Spell;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
public class Barrage
|
||||
extends Spell {
|
||||
public static final long DURATION = 20000L;
|
||||
private long remainingTime;
|
||||
private boolean isFinished;
|
||||
|
||||
public Barrage(Actor affectedTarget, Actor caster) {
|
||||
super(affectedTarget, caster);
|
||||
}
|
||||
|
||||
public long getRemainingTime() {
|
||||
long elapsedTime = System.currentTimeMillis() - this.startTime;
|
||||
if (Barrage.getDURATION() > elapsedTime) {
|
||||
return Barrage.getDURATION() - elapsedTime;
|
||||
}
|
||||
this.isFinished = true;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Barrage) {
|
||||
Barrage barrage = (Barrage)o;
|
||||
return Text.standardize(this.getAffectedTarget().getName()).equals(Text.standardize(((Barrage)o).getAffectedTarget().getName())) && this.getStartTime() == ((Barrage)o).getStartTime();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long getDURATION() {
|
||||
return 20000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return this.isFinished;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup(value="freezetimers")
|
||||
public interface FreezeTimersConfig
|
||||
extends Config {
|
||||
@ConfigItem(position=0, keyName="freezeenable", name="Enable PvP freeze timers", description="Configures whether or not to show freeze timers.")
|
||||
default public boolean EnableFreezeTimers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(position=1, keyName="tilehighlight", name="Frozen opponent tile highlighting", description="Configures whether or not to highlight tiles frozen opponents are standing on.")
|
||||
default public boolean drawTiles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(position=2, keyName="timercolor", name="Freeze Timer Color", description="Color of freeze timer")
|
||||
default public Color FreezeTimerColor() {
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(position=3, keyName="spellIcon", name="Show spell icon", description="Shows the spell icon for the freeze spell affecting the target")
|
||||
default public boolean spellIcon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position=4, keyName="refreezeTimer", name="Refreeze Timer", description="Show a timer that counts up until the target can be refrozen")
|
||||
default public boolean refreezeTimer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position=5, keyName="refreezeTimerColor", name="Refreeze color", description="The color for the timer that counts until the target can be refrozen")
|
||||
default public Color RefreezeTimerColor() {
|
||||
return Color.red;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 6, keyName = "tbtimer", name = "Tele Block Timer", description = "Enables tele block timer")
|
||||
default boolean TBTimer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 7, keyName = "timerpos", name = "Freeze Timer Position", description = "Position of freeze timer")
|
||||
default int FreezeTimerPos() {
|
||||
return 80;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersService;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class FreezeTimersOverlay
|
||||
extends Overlay {
|
||||
private final FreezeTimersService FreezeTimersService;
|
||||
private final FreezeTimersConfig config;
|
||||
private final FreezeTimersPlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private FreezeTimersOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2, FreezeTimersPlugin plugin, Client client, SpriteManager spriteManager) {
|
||||
this.config = config;
|
||||
this.FreezeTimersService = FreezeTimersService2;
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
this.spriteManager = spriteManager;
|
||||
this.setPosition(OverlayPosition.DYNAMIC);
|
||||
this.setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!this.config.EnableFreezeTimers()) {
|
||||
return null;
|
||||
}
|
||||
this.FreezeTimersService.forEachPlayer((player, color) -> this.renderPlayerOverlay(graphics, (Player)player, (Color)color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) {
|
||||
BufferedImage clanchatImage;
|
||||
int timer = 0;
|
||||
String name = actor.getName();
|
||||
int freezetype = this.plugin.freezetype(name);
|
||||
boolean frozenoverlay = false;
|
||||
int offset = 5;
|
||||
long dtime = this.plugin.opponentfreezetime(name);
|
||||
long tbed = plugin.istbed(name);
|
||||
Point textLocation = null;
|
||||
HeadIcon headIcon = actor.getOverheadIcon();
|
||||
int freezetime = 0;
|
||||
if (freezetype == 1 || freezetype == 4) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 2 || freezetype == 5) {
|
||||
freezetime = 10000;
|
||||
} else if (freezetype == 3 || freezetype == 6) {
|
||||
freezetime = 15000;
|
||||
} else if (freezetype == 7) {
|
||||
freezetime = 20000;
|
||||
} else if (freezetype == 8) {
|
||||
freezetime = 2500;
|
||||
} else if (freezetype == 9) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 10) {
|
||||
freezetime = 7500;
|
||||
}
|
||||
long currenttime = System.currentTimeMillis();
|
||||
long timediff = currenttime - dtime;
|
||||
timer = (freezetime - (int)timediff) / 1000;
|
||||
if (timediff < (long)freezetime) {
|
||||
textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos());
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
} else if (timediff < (long)(freezetime + 3000)) {
|
||||
timer = Math.abs(timer);
|
||||
++timer;
|
||||
if (this.config.refreezeTimer()) {
|
||||
textLocation = actor.getCanvasTextLocation(graphics, String.valueOf(timer), actor.getLogicalHeight() + config.FreezeTimerPos());
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
if (headIcon != null) {
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
}
|
||||
frozenoverlay = true;
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), this.config.RefreezeTimerColor());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.plugin.deleteopponent(name);
|
||||
}
|
||||
if (textLocation != null && (clanchatImage = this.plugin.GetFreezeIcon(freezetype - 1)) != null) {
|
||||
int width = clanchatImage.getWidth();
|
||||
int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent();
|
||||
Point imageLocation = new Point(textLocation.getX(), textLocation.getY() - (config.FreezeTimerPos() / 2));
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
graphics.setStroke(new BasicStroke(3.0f));
|
||||
if (this.config.spellIcon()) {
|
||||
frozenoverlay = true;
|
||||
graphics.drawOval(imageLocation.getX(), imageLocation.getY(), clanchatImage.getWidth(), clanchatImage.getHeight());
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, clanchatImage);
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), color);
|
||||
} else {
|
||||
graphics.setColor(Color.cyan);
|
||||
graphics.drawOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight());
|
||||
graphics.setColor(Color.blue);
|
||||
graphics.fillOval(textLocation.getX() - 3, textLocation.getY() - 15, clanchatImage.getWidth(), graphics.getFontMetrics().getHeight());
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(timer), Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.TBTimer()) {
|
||||
if (tbed > 0) {
|
||||
int type = plugin.tbtype(name);
|
||||
int tbexpiry;
|
||||
if (type > 0) {
|
||||
if (type == 1) {
|
||||
tbexpiry = 300000;
|
||||
} else if (type == 2) {
|
||||
tbexpiry = 150000;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
long tbtime = currenttime - tbed;
|
||||
int tbtimer = (tbexpiry - (int) tbtime) / 1000;
|
||||
if (tbtime < tbexpiry) {
|
||||
textLocation = actor.getCanvasTextLocation(graphics, Integer.toString(tbtimer), actor.getLogicalHeight() + config.FreezeTimerPos());
|
||||
if (frozenoverlay) {
|
||||
textLocation = new Point(textLocation.getX() + 40, textLocation.getY() - config.FreezeTimerPos());
|
||||
} else {
|
||||
textLocation = new Point(textLocation.getX(), textLocation.getY() - config.FreezeTimerPos());
|
||||
}
|
||||
} else {
|
||||
plugin.deletetb(name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,402 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.freezetimers.Barrage;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersOverlay;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersTileOverlay;
|
||||
import net.runelite.client.plugins.freezetimers.Spell;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"aqua\">!Freeze Timers</font>",
|
||||
description = "PVP Freeze Timers",
|
||||
tags = {"PvP", "Freeze", "Timers"}
|
||||
)
|
||||
|
||||
public class FreezeTimersPlugin
|
||||
extends Plugin {
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
@Inject
|
||||
private FreezeTimersConfig config;
|
||||
@Inject
|
||||
private FreezeTimersOverlay FreezeTimersOverlay;
|
||||
@Inject
|
||||
private FreezeTimersTileOverlay FreezeTimersTileOverlay;
|
||||
@Inject
|
||||
private Client client;
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
private static final int[] FREEZE_ICONS = {
|
||||
SpriteID.SPELL_BIND,
|
||||
SpriteID.SPELL_SNARE,
|
||||
SpriteID.SPELL_ENTANGLE,
|
||||
SpriteID.SPELL_ICE_RUSH,
|
||||
SpriteID.SPELL_ICE_BURST,
|
||||
SpriteID.SPELL_ICE_BLITZ,
|
||||
SpriteID.SPELL_ICE_BARRAGE,
|
||||
SpriteID.SPELL_BIND,
|
||||
SpriteID.SPELL_SNARE,
|
||||
SpriteID.SPELL_ENTANGLE,
|
||||
SpriteID.SPELL_TELE_BLOCK
|
||||
};
|
||||
private static final Dimension FREEZE_ICON_DIMENSION = new Dimension(25, 25);
|
||||
private static final Color FREEZE_ICON_OUTLINE_COLOR = new Color(33, 33, 33);
|
||||
private final BufferedImage[] FreezeIcons = new BufferedImage[FREEZE_ICONS.length];
|
||||
private final int SPLASH_ID = 85;
|
||||
Map<String, Long> tbedthings = new HashMap<>();
|
||||
Map<String, Integer> tbtypes = new HashMap<>();
|
||||
Map<String, Spell> testMap = new HashMap<String, Spell>();
|
||||
Map<String, Long> frozenthings = new HashMap<String, Long>();
|
||||
Map<String, WorldPoint> frozenthingpoints = new HashMap<String, WorldPoint>();
|
||||
Map<String, Integer> freezetype = new HashMap<String, Integer>();
|
||||
Map<Integer, Integer> magexp = new HashMap<Integer, Integer>();
|
||||
int lastxp;
|
||||
int ticks;
|
||||
int currticks;
|
||||
String currtarget;
|
||||
String spell;
|
||||
|
||||
@Provides
|
||||
FreezeTimersConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(FreezeTimersConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged) {
|
||||
if (gameStateChanged.getGameState() == GameState.LOGGED_IN) {
|
||||
this.loadFreezeIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
this.overlayManager.add(this.FreezeTimersOverlay);
|
||||
this.overlayManager.add(this.FreezeTimersTileOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
this.overlayManager.remove(this.FreezeTimersOverlay);
|
||||
this.overlayManager.remove(this.FreezeTimersTileOverlay);
|
||||
this.frozenthings.clear();
|
||||
this.frozenthingpoints.clear();
|
||||
this.tbedthings.clear();
|
||||
this.tbtypes.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event) {
|
||||
if (event.getMenuTarget().contains("->")) {
|
||||
Pattern spattern = Pattern.compile(">(.+?)</col>");
|
||||
Pattern ppattern = Pattern.compile("> <col=ffffff>(.+?)<col=");
|
||||
Matcher smatch = spattern.matcher(event.getMenuTarget());
|
||||
Matcher pmatch = ppattern.matcher(event.getMenuTarget());
|
||||
smatch.find();
|
||||
pmatch.find();
|
||||
if (smatch.group(1) != null && pmatch.group(1) != null) {
|
||||
this.currticks = this.ticks;
|
||||
this.spell = smatch.group(1);
|
||||
this.currtarget = pmatch.group(1).replace("\u00a0", " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event) {
|
||||
if (event.getSkill() == Skill.MAGIC) {
|
||||
int xp = this.client.getSkillExperience(Skill.MAGIC);
|
||||
int gains = xp - this.lastxp;
|
||||
this.lastxp = xp;
|
||||
if (!this.magexp.containsKey(this.ticks)) {
|
||||
this.magexp.clear();
|
||||
this.magexp.put(this.ticks, gains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onAnimationChanged(AnimationChanged event) {
|
||||
Logger l = this.client.getLogger();
|
||||
Actor subject = event.getActor();
|
||||
Actor target = subject.getInteracting();
|
||||
if (subject.getAnimation() == 1979) {
|
||||
try {
|
||||
if (target.getGraphic() == 85 || target.getGraphic() != -1) {
|
||||
return;
|
||||
}
|
||||
if (this.frozenthings.containsKey(target.getName())) {
|
||||
return;
|
||||
}
|
||||
this.testMap.put(target.getName(), new Barrage(target, subject));
|
||||
this.freezetype.put(target.getName(), 7);
|
||||
this.frozenthings.put(target.getName(), System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(target.getName(), target.getWorldLocation());
|
||||
}
|
||||
catch (NullPointerException nullPointerException) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event) {
|
||||
int xp = 0;
|
||||
boolean praymage = false;
|
||||
if (this.magexp.containsKey(this.ticks)) {
|
||||
xp = this.magexp.get(this.ticks);
|
||||
}
|
||||
if (xp > 0 && this.currtarget != null) {
|
||||
if (this.frozenthings.containsKey(this.currtarget)) {
|
||||
this.currtarget = null;
|
||||
return;
|
||||
}
|
||||
WorldPoint targetPosition = null;
|
||||
for (Player player : this.client.getPlayers()) {
|
||||
String playerName;
|
||||
if (player == null || !(playerName = player.getName()).equals(this.currtarget)) continue;
|
||||
if (player.getOverheadIcon() != null && player.getOverheadIcon().equals((Object)HeadIcon.MAGIC)) {
|
||||
praymage = true;
|
||||
}
|
||||
targetPosition = player.getWorldLocation();
|
||||
break;
|
||||
}
|
||||
if (targetPosition != null) {
|
||||
if (this.spell.equals("Bind") && xp > 30) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
if (praymage) {
|
||||
this.freezetype.put(this.currtarget, 8);
|
||||
} else {
|
||||
this.freezetype.put(this.currtarget, 1);
|
||||
}
|
||||
} else if (this.spell.equals("Snare") && xp > 60) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
if (praymage) {
|
||||
this.freezetype.put(this.currtarget, 9);
|
||||
} else {
|
||||
this.freezetype.put(this.currtarget, 2);
|
||||
}
|
||||
} else if (this.spell.equals("Entangle") && xp >= 89) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
if (praymage) {
|
||||
this.freezetype.put(this.currtarget, 10);
|
||||
} else {
|
||||
this.freezetype.put(this.currtarget, 3);
|
||||
}
|
||||
} else if (this.spell.equals("Ice Rush") && xp > 34) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 4);
|
||||
} else if (this.spell.equals("Ice Burst") && xp > 40) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 5);
|
||||
} else if (this.spell.equals("Ice Blitz") && xp > 46) {
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 6);
|
||||
} else if (this.spell.equals("Ice Barrage") && xp > 52) {
|
||||
Barrage barrage = new Barrage(this.client.getLocalPlayer().getInteracting(), this.client.getLocalPlayer());
|
||||
this.testMap.put(this.currtarget, barrage);
|
||||
this.frozenthings.put(this.currtarget, System.currentTimeMillis());
|
||||
this.frozenthingpoints.put(this.currtarget, targetPosition);
|
||||
this.freezetype.put(this.currtarget, 7);
|
||||
} else if (spell.equals("Tele Block") && xp == 95) {
|
||||
if (config.TBTimer()) {
|
||||
if (praymage) {
|
||||
this.tbtypes.put(this.currtarget, 2);
|
||||
} else {
|
||||
this.tbtypes.put(this.currtarget, 1);
|
||||
}
|
||||
this.tbedthings.put(this.currtarget, System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.currtarget != null && this.ticks > this.currticks + 1) {
|
||||
Player local = this.client.getLocalPlayer();
|
||||
Actor interacting = local.getInteracting();
|
||||
if (interacting != null) {
|
||||
if (!interacting.getName().equals(this.currtarget)) {
|
||||
this.currtarget = null;
|
||||
}
|
||||
} else {
|
||||
this.currtarget = null;
|
||||
}
|
||||
}
|
||||
++this.ticks;
|
||||
}
|
||||
|
||||
public long opponentfreezetime(String name) {
|
||||
if (this.frozenthings.containsKey(name)) {
|
||||
return this.frozenthings.get(name);
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public WorldPoint playerpos(String name) {
|
||||
if (this.frozenthingpoints.containsKey(name)) {
|
||||
return this.frozenthingpoints.get(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updatePosition(String name, WorldPoint point) {
|
||||
if (this.frozenthingpoints.containsKey(name)) {
|
||||
this.frozenthingpoints.remove(name);
|
||||
this.frozenthingpoints.put(name, point);
|
||||
}
|
||||
}
|
||||
|
||||
public int freezetype(String name) {
|
||||
if (this.freezetype.containsKey(name)) {
|
||||
return this.freezetype.get(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public long istbed(String name) {
|
||||
if (this.tbedthings.containsKey(name)) {
|
||||
return this.tbedthings.get(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public int tbtype(String name) {
|
||||
if (this.tbtypes.containsKey(name)) {
|
||||
return this.tbtypes.get(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public void deleteopponent(String name) {
|
||||
if (this.frozenthings.containsKey(name)) {
|
||||
this.frozenthings.remove(name);
|
||||
}
|
||||
if (this.frozenthingpoints.containsKey(name)) {
|
||||
this.frozenthingpoints.remove(name);
|
||||
}
|
||||
if (this.freezetype.containsKey(name)) {
|
||||
this.freezetype.remove(name);
|
||||
}
|
||||
}
|
||||
public void deletetb(String name) {
|
||||
if (this.tbedthings.containsKey(name)) {
|
||||
this.tbedthings.remove(name);
|
||||
}
|
||||
if (this.tbtypes.containsKey(name)) {
|
||||
this.tbtypes.remove(name);
|
||||
}
|
||||
}
|
||||
private void loadFreezeIcons() {
|
||||
IndexedSprite[] freezeIcons = new IndexedSprite[]{};
|
||||
IndexedSprite[] newfreezeIcons = Arrays.copyOf(freezeIcons, FREEZE_ICONS.length);
|
||||
int curPosition = 0;
|
||||
int i = 0;
|
||||
while (i < FREEZE_ICONS.length) {
|
||||
int resource = FREEZE_ICONS[i];
|
||||
this.FreezeIcons[i] = FreezeTimersPlugin.rgbaToIndexedBufferedImage(FreezeTimersPlugin.FreezeIconFromSprite(this.spriteManager.getSprite(resource, 0)));
|
||||
newfreezeIcons[curPosition] = FreezeTimersPlugin.createIndexedSprite(this.client, this.FreezeIcons[i]);
|
||||
++i;
|
||||
++curPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private static IndexedSprite createIndexedSprite(Client client, BufferedImage bufferedImage) {
|
||||
IndexColorModel indexedCM = (IndexColorModel)bufferedImage.getColorModel();
|
||||
int width = bufferedImage.getWidth();
|
||||
int height = bufferedImage.getHeight();
|
||||
byte[] pixels = ((DataBufferByte)bufferedImage.getRaster().getDataBuffer()).getData();
|
||||
int[] palette = new int[indexedCM.getMapSize()];
|
||||
indexedCM.getRGBs(palette);
|
||||
IndexedSprite newIndexedSprite = client.createIndexedSprite();
|
||||
newIndexedSprite.setPixels(pixels);
|
||||
newIndexedSprite.setPalette(palette);
|
||||
newIndexedSprite.setWidth(width);
|
||||
newIndexedSprite.setHeight(height);
|
||||
newIndexedSprite.setOriginalWidth(width);
|
||||
newIndexedSprite.setOriginalHeight(height);
|
||||
newIndexedSprite.setOffsetX(0);
|
||||
newIndexedSprite.setOffsetY(0);
|
||||
return newIndexedSprite;
|
||||
}
|
||||
|
||||
private static BufferedImage rgbaToIndexedBufferedImage(BufferedImage sourceBufferedImage) {
|
||||
BufferedImage indexedImage = new BufferedImage(sourceBufferedImage.getWidth(), sourceBufferedImage.getHeight(), 13);
|
||||
ColorModel cm = indexedImage.getColorModel();
|
||||
IndexColorModel icm = (IndexColorModel)cm;
|
||||
int size = icm.getMapSize();
|
||||
byte[] reds = new byte[size];
|
||||
byte[] greens = new byte[size];
|
||||
byte[] blues = new byte[size];
|
||||
icm.getReds(reds);
|
||||
icm.getGreens(greens);
|
||||
icm.getBlues(blues);
|
||||
WritableRaster raster = indexedImage.getRaster();
|
||||
int pixel = raster.getSample(0, 0, 0);
|
||||
IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel);
|
||||
BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
|
||||
resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
|
||||
return resultIndexedImage;
|
||||
}
|
||||
|
||||
private static BufferedImage FreezeIconFromSprite(BufferedImage freezeSprite) {
|
||||
BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.width, FreezeTimersPlugin.FREEZE_ICON_DIMENSION.height);
|
||||
return ImageUtil.outlineImage(freezeCanvas, FREEZE_ICON_OUTLINE_COLOR);
|
||||
}
|
||||
|
||||
BufferedImage GetFreezeIcon(int id) {
|
||||
return this.FreezeIcons[id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersPlugin;
|
||||
|
||||
@Singleton
|
||||
public class FreezeTimersService {
|
||||
private final Client client;
|
||||
private final FreezeTimersConfig config;
|
||||
private final FreezeTimersPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private FreezeTimersService(Client client, FreezeTimersConfig config, FreezeTimersPlugin plugin) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void forEachPlayer(BiConsumer<Player, Color> consumer) {
|
||||
for (Player player : this.client.getPlayers()) {
|
||||
if (player == null || player.getName() == null) continue;
|
||||
String name = player.getName();
|
||||
int freezetype = this.plugin.freezetype(name);
|
||||
long tbed = plugin.istbed(name);
|
||||
long dtime = this.plugin.opponentfreezetime(name);
|
||||
int freezetime = 0;
|
||||
if (freezetype == 1 || freezetype == 4) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 2 || freezetype == 5) {
|
||||
freezetime = 10000;
|
||||
} else if (freezetype == 3 || freezetype == 6) {
|
||||
freezetime = 15000;
|
||||
} else if (freezetype == 7) {
|
||||
freezetime = 20000;
|
||||
} else if (freezetype == 8) {
|
||||
freezetime = 2500;
|
||||
} else if (freezetype == 9) {
|
||||
freezetime = 5000;
|
||||
} else if (freezetype == 10) {
|
||||
freezetime = 7500;
|
||||
}
|
||||
if (dtime <= 0L) continue;
|
||||
long currenttime = System.currentTimeMillis();
|
||||
long timediff = currenttime - dtime;
|
||||
if (timediff < (long)freezetime) {
|
||||
WorldPoint lastWorldPoint;
|
||||
WorldPoint currentWorldPoint = player.getWorldLocation();
|
||||
if (currentWorldPoint.equals(lastWorldPoint = this.plugin.playerpos(name))) {
|
||||
consumer.accept(player, this.config.FreezeTimerColor());
|
||||
continue;
|
||||
}
|
||||
if (timediff < 605L) {
|
||||
this.plugin.updatePosition(name, currentWorldPoint);
|
||||
consumer.accept(player, this.config.FreezeTimerColor());
|
||||
continue;
|
||||
}
|
||||
this.plugin.deleteopponent(name);
|
||||
continue;
|
||||
}
|
||||
if (timediff < (long)(freezetime + 3000)) {
|
||||
consumer.accept(player, Color.YELLOW);
|
||||
continue;
|
||||
} else {
|
||||
this.plugin.deleteopponent(name);
|
||||
}
|
||||
if (tbed > 0) {
|
||||
consumer.accept(player, config.FreezeTimerColor());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersConfig;
|
||||
import net.runelite.client.plugins.freezetimers.FreezeTimersService;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class FreezeTimersTileOverlay
|
||||
extends Overlay {
|
||||
private final FreezeTimersService FreezeTimersService;
|
||||
private final FreezeTimersConfig config;
|
||||
|
||||
@Inject
|
||||
private FreezeTimersTileOverlay(FreezeTimersConfig config, FreezeTimersService FreezeTimersService2) {
|
||||
this.config = config;
|
||||
this.FreezeTimersService = FreezeTimersService2;
|
||||
this.setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.setPosition(OverlayPosition.DYNAMIC);
|
||||
this.setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!this.config.drawTiles()) {
|
||||
return null;
|
||||
}
|
||||
this.FreezeTimersService.forEachPlayer((player, color) -> {
|
||||
Polygon poly = player.getCanvasTilePoly();
|
||||
if (poly != null) {
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
public enum PlayerSpellEffect {
|
||||
BARRAGE("Ice Barrage", 20000, false),
|
||||
BLITZ("Ice Blitz", 15000, false);
|
||||
|
||||
private final String SPELL_NAME;
|
||||
private long startTime;
|
||||
private int duration;
|
||||
private boolean halvable;
|
||||
|
||||
private PlayerSpellEffect(String name, int duration, boolean halvable) {
|
||||
this.SPELL_NAME = name;
|
||||
this.duration = duration;
|
||||
this.halvable = halvable;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public String getSPELL_NAME() {
|
||||
return this.SPELL_NAME;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public boolean isHalvable() {
|
||||
return this.halvable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.runelite.client.plugins.freezetimers;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
|
||||
public abstract class Spell {
|
||||
private final Actor affectedTarget;
|
||||
private final Actor caster;
|
||||
public final long startTime;
|
||||
private long remainingTime;
|
||||
private boolean isFinished;
|
||||
|
||||
protected Spell(Actor affectedTarget, Actor caster) {
|
||||
this.affectedTarget = affectedTarget;
|
||||
this.caster = caster;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public Actor getAffectedTarget() {
|
||||
return this.affectedTarget;
|
||||
}
|
||||
|
||||
public Actor getCaster() {
|
||||
return this.caster;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.isFinished;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Damen <https://github.com/basicDamen>
|
||||
* 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.grotesqueguardians;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GraphicsObject;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
class GrotesqueGuardiansOverlay extends Overlay
|
||||
{
|
||||
private static final int GROTESQUE_GUARDIANS_REGION_ID = 6727;
|
||||
private final Client client;
|
||||
private static final int GROTESQUE_GUARDIANS_LIGHTNING_START = 1416;
|
||||
private static final int GROTESQUE_GUARDIANS_LIGHTNING_END = 1431;
|
||||
private static final int GROTESQUE_GUARDIANS_FALLING_ROCKS = 1436;
|
||||
private static final int GROTESQUE_GUARDIANS_STONE_ORB = 160;
|
||||
|
||||
@Inject
|
||||
private GrotesqueGuardiansOverlay(Client client)
|
||||
{
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPriority(OverlayPriority.LOW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!client.isInInstancedRegion() || client.getMapRegions()[0] != GROTESQUE_GUARDIANS_REGION_ID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Awaiting GraphicsObjectDespawn event to be tracked to make this more efficient.
|
||||
for (GraphicsObject graphicsObject : client.getGraphicsObjects())
|
||||
{
|
||||
Color color = null;
|
||||
|
||||
if (graphicsObject.getId() >= GROTESQUE_GUARDIANS_LIGHTNING_START && graphicsObject.getId() <= GROTESQUE_GUARDIANS_LIGHTNING_END)
|
||||
{
|
||||
color = Color.ORANGE;
|
||||
}
|
||||
else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_STONE_ORB)
|
||||
{
|
||||
color = Color.GRAY;
|
||||
}
|
||||
else if (graphicsObject.getId() == GROTESQUE_GUARDIANS_FALLING_ROCKS)
|
||||
{
|
||||
color = Color.YELLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalPoint lp = graphicsObject.getLocation();
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
|
||||
if (poly != null)
|
||||
{
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Damen <https://github.com/basicDamen>
|
||||
* 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.grotesqueguardians;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Grotesque Guardians</font>",
|
||||
description = "Display tile indicators for the Grotesque Guardian special attacks",
|
||||
tags = {"grotesque", "guardians", "gargoyle", "garg"}
|
||||
)
|
||||
public class GrotesqueGuardiansPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private GrotesqueGuardiansOverlay overlay;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.runelite.client.plugins.hideprayers;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("hideprayers")
|
||||
public interface HidePrayersConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "pk prayers",
|
||||
name = "Hides none pk prayers",
|
||||
description = "Hides widget icons."
|
||||
)
|
||||
default boolean showPrayers() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "eagle/mystic",
|
||||
name = "Shows eagle and mystic prayers",
|
||||
description = "Hides widget icons."
|
||||
)
|
||||
default boolean showEagleMystic() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "ultstr",
|
||||
name = "Shows ultimate strength",
|
||||
description = "Hides widget icons."
|
||||
)
|
||||
default boolean showUltStrength() { return false; }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
package net.runelite.client.plugins.hideprayers;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!Hide Prayers</font>",
|
||||
description = "Hides specific Prayers in the Prayer tab."
|
||||
)
|
||||
public class HidePrayersPlugin extends Plugin {
|
||||
private static final int PRAYER_COUNT = Prayer.values().length;
|
||||
|
||||
private static final List<WidgetInfo> PRAYER_WIDGET_INFO_LIST = ImmutableList.of(WidgetInfo.PRAYER_THICK_SKIN,
|
||||
WidgetInfo.PRAYER_BURST_OF_STRENGTH, WidgetInfo.PRAYER_CLARITY_OF_THOUGHT, WidgetInfo.PRAYER_SHARP_EYE,
|
||||
WidgetInfo.PRAYER_MYSTIC_WILL, WidgetInfo.PRAYER_ROCK_SKIN, WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH,
|
||||
WidgetInfo.PRAYER_IMPROVED_REFLEXES, WidgetInfo.PRAYER_RAPID_RESTORE, WidgetInfo.PRAYER_RAPID_HEAL,
|
||||
WidgetInfo.PRAYER_PROTECT_ITEM, WidgetInfo.PRAYER_HAWK_EYE, WidgetInfo.PRAYER_MYSTIC_LORE,
|
||||
WidgetInfo.PRAYER_STEEL_SKIN, WidgetInfo.PRAYER_ULTIMATE_STRENGTH, WidgetInfo.PRAYER_INCREDIBLE_REFLEXES,
|
||||
WidgetInfo.PRAYER_PROTECT_FROM_MAGIC, WidgetInfo.PRAYER_PROTECT_FROM_MISSILES,
|
||||
WidgetInfo.PRAYER_PROTECT_FROM_MELEE, WidgetInfo.PRAYER_EAGLE_EYE, WidgetInfo.PRAYER_MYSTIC_MIGHT,
|
||||
WidgetInfo.PRAYER_RETRIBUTION, WidgetInfo.PRAYER_REDEMPTION, WidgetInfo.PRAYER_SMITE,
|
||||
WidgetInfo.PRAYER_PRESERVE, WidgetInfo.PRAYER_CHIVALRY, WidgetInfo.PRAYER_PIETY, WidgetInfo.PRAYER_RIGOUR,
|
||||
WidgetInfo.PRAYER_AUGURY);
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private HidePrayersConfig config;
|
||||
|
||||
@Provides
|
||||
HidePrayersConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(HidePrayersConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
hidePrayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
restorePrayers();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event) {
|
||||
if (event.getGameState() == GameState.LOGGED_IN) {
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onConfigChanged(ConfigChanged event) {
|
||||
if (event.getGroup().equals("hideprayers")) {
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event) {
|
||||
if (event.getGroupId() == WidgetID.PRAYER_GROUP_ID || event.getGroupId() == WidgetID.QUICK_PRAYERS_GROUP_ID) {
|
||||
hidePrayers();
|
||||
}
|
||||
}
|
||||
|
||||
private PrayerTabState getPrayerTabState() {
|
||||
HashTable<WidgetNode> componentTable = client.getComponentTable();
|
||||
for (WidgetNode widgetNode : componentTable.getNodes()) {
|
||||
if (widgetNode.getId() == WidgetID.PRAYER_GROUP_ID) {
|
||||
return PrayerTabState.PRAYERS;
|
||||
} else if (widgetNode.getId() == WidgetID.QUICK_PRAYERS_GROUP_ID) {
|
||||
return PrayerTabState.QUICK_PRAYERS;
|
||||
}
|
||||
}
|
||||
return PrayerTabState.NONE;
|
||||
}
|
||||
|
||||
private void restorePrayers() {
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
return;
|
||||
|
||||
PrayerTabState prayerTabState = getPrayerTabState();
|
||||
|
||||
if (prayerTabState == PrayerTabState.PRAYERS) {
|
||||
List<Widget> prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
|
||||
return;
|
||||
|
||||
for (int index = 0; index < PRAYER_COUNT; index++)
|
||||
prayerWidgets.get(Prayer.values()[index].ordinal()).setHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void hidePrayers() {
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
return;
|
||||
|
||||
PrayerTabState prayerTabState = getPrayerTabState();
|
||||
|
||||
if (prayerTabState == PrayerTabState.PRAYERS) {
|
||||
List<Widget> prayerWidgets = PRAYER_WIDGET_INFO_LIST.stream().map(client::getWidget)
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
if (prayerWidgets.size() != PRAYER_WIDGET_INFO_LIST.size())
|
||||
return;
|
||||
|
||||
for (int index = 0; index < PRAYER_COUNT; index++) {
|
||||
Prayer prayer = Prayer.values()[index];
|
||||
Widget prayerWidget = prayerWidgets.get(prayer.ordinal());
|
||||
|
||||
if (!config.showPrayers() && !config.showEagleMystic())
|
||||
prayerWidget.setHidden(false);
|
||||
|
||||
if (config.showPrayers()) {
|
||||
prayerWidget.setHidden(true);
|
||||
prayerWidgets.get(Prayer.values()[10].ordinal()).setHidden(false);// protect item
|
||||
prayerWidgets.get(Prayer.values()[16].ordinal()).setHidden(false);// mage
|
||||
prayerWidgets.get(Prayer.values()[17].ordinal()).setHidden(false);// range
|
||||
prayerWidgets.get(Prayer.values()[18].ordinal()).setHidden(false);// melee
|
||||
prayerWidgets.get(Prayer.values()[23].ordinal()).setHidden(false);// smite
|
||||
if (config.showEagleMystic()) {
|
||||
prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
|
||||
prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
|
||||
} else {
|
||||
prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(false);// rigour
|
||||
prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(false);// augury
|
||||
}
|
||||
if (config.showUltStrength()) {
|
||||
prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
|
||||
} else {
|
||||
prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(false);// piety
|
||||
}
|
||||
}
|
||||
if (config.showEagleMystic()) {
|
||||
prayerWidget.setHidden(true);
|
||||
prayerWidgets.get(Prayer.values()[19].ordinal()).setHidden(false);// eagle
|
||||
prayerWidgets.get(Prayer.values()[20].ordinal()).setHidden(false);// mystic
|
||||
prayerWidgets.get(Prayer.values()[27].ordinal()).setHidden(true);// rigour
|
||||
prayerWidgets.get(Prayer.values()[28].ordinal()).setHidden(true);// augury
|
||||
}
|
||||
if (config.showUltStrength()) {
|
||||
prayerWidget.setHidden(true);
|
||||
prayerWidgets.get(Prayer.values()[14].ordinal()).setHidden(false);// Ult Strength
|
||||
prayerWidgets.get(Prayer.values()[26].ordinal()).setHidden(true);// piety
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.runelite.client.plugins.hideprayers;
|
||||
|
||||
public enum PrayerTabState
|
||||
{
|
||||
NONE,
|
||||
PRAYERS,
|
||||
QUICK_PRAYERS
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("hydra")
|
||||
public interface HydraConfig extends Config {
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "hydraenable",
|
||||
name = "Enable Hydra (194 cb) Helper",
|
||||
description = "Configures whether or not to enable Hydra Helper. (For use on regular hydra's only, will not work with Alchemical Hydra)."
|
||||
)
|
||||
default boolean EnableHydra() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "textindicators",
|
||||
name = "Text Indicator",
|
||||
description = "Configures if text indicator is shown above hydra's or not."
|
||||
)
|
||||
default boolean TextIndicator() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "countersize",
|
||||
name = "Bold indicator",
|
||||
description = "Configures if text indicator is bold or not."
|
||||
)
|
||||
default boolean BoldText() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "prayerhelper",
|
||||
name = "Prayer Helper",
|
||||
description = "Configures if prayer helper is shown or not."
|
||||
)
|
||||
default boolean PrayerHelper() { return true; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
|
||||
public class HydraIndicatorOverlay extends Overlay {
|
||||
private final HydraConfig config;
|
||||
private final HydraPlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private HydraIndicatorOverlay(HydraConfig config, HydraPlugin plugin) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.MED);
|
||||
panelComponent.setPreferredSize(new Dimension(14, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!config.PrayerHelper()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (plugin.Hydra != null) {
|
||||
if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) {
|
||||
int val = plugin.hydras.get(plugin.Hydra.getIndex());
|
||||
if (val != 0) {
|
||||
panelComponent.getChildren().clear();
|
||||
panelComponent.getChildren().add(LineComponent.builder().right(Integer.toString(val)).build());
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class HydraOverlay extends Overlay {
|
||||
private final HydraConfig config;
|
||||
private final HydraPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private HydraOverlay(HydraConfig config, HydraPlugin plugin) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
panelComponent.setPreferredSize(new Dimension(150, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!config.TextIndicator()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (NPC hydra : client.getNpcs()) {
|
||||
if (hydra == null || hydra.getName() == null) {
|
||||
continue;
|
||||
}
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (plugin.hydras.containsKey(hydra.getIndex())) {
|
||||
int val = plugin.hydras.get(hydra.getIndex());
|
||||
if (val != 0) {
|
||||
if (config.BoldText()) {
|
||||
graphics.setFont(FontManager.getRunescapeBoldFont());
|
||||
}
|
||||
if (plugin.hydraattacks.containsKey(hydra.getIndex())) {
|
||||
int attack = plugin.hydraattacks.get(hydra.getIndex());
|
||||
if (attack == 8261) {
|
||||
if (val == 3) {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE);
|
||||
} else {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN);
|
||||
}
|
||||
} else if (attack == 8262) {
|
||||
if (val == 3) {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "RANGE", hydra.getLogicalHeight() + 100), "RANGE", Color.GREEN);
|
||||
} else {
|
||||
OverlayUtil.renderTextLocation(graphics, hydra.getCanvasTextLocation(graphics, "MAGE", hydra.getLogicalHeight() + 100), "MAGE", Color.BLUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Point runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam = hydra.getCanvasTextLocation(graphics, Integer.toString(val), hydra.getLogicalHeight() + 40);
|
||||
if (runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam != null) {
|
||||
OverlayUtil.renderTextLocation(graphics, runelitepleaseexplainwhyineedtocheckthisfornullinsteadoftheentirehydravariablethisshitcostmelikeanhourofmylifeandiblameyouadam, Integer.toString(val), Color.WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
graphics.setFont(FontManager.getRunescapeFont());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Hydra",
|
||||
description = "Hydra Helper",
|
||||
tags = {"Hydra", "Helper"}
|
||||
)
|
||||
public class HydraPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private HydraConfig config;
|
||||
|
||||
@Inject
|
||||
private HydraOverlay HydraOverlay;
|
||||
|
||||
@Inject
|
||||
private HydraPrayOverlay HydraPrayOverlay;
|
||||
|
||||
@Inject
|
||||
private HydraIndicatorOverlay HydraIndicatorOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Provides
|
||||
HydraConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(HydraConfig.class);
|
||||
}
|
||||
|
||||
Map<Integer, Integer> hydras = new HashMap<>();
|
||||
Map<Integer, Integer> hydraattacks = new HashMap<>();
|
||||
NPC Hydra;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
overlayManager.add(HydraOverlay);
|
||||
overlayManager.add(HydraPrayOverlay);
|
||||
overlayManager.add(HydraIndicatorOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
overlayManager.remove(HydraOverlay);
|
||||
overlayManager.remove(HydraPrayOverlay);
|
||||
overlayManager.remove(HydraIndicatorOverlay);
|
||||
hydras.clear();
|
||||
hydraattacks.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event) {
|
||||
if (!config.EnableHydra()) {
|
||||
return;
|
||||
}
|
||||
NPC hydra = event.getNpc();
|
||||
if (hydra.getCombatLevel() != 0 && hydra.getName() != null) {
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (!hydras.containsKey(hydra.getIndex())) {
|
||||
hydras.put(hydra.getIndex(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event) {
|
||||
if (!config.EnableHydra()) {
|
||||
return;
|
||||
}
|
||||
NPC hydra = event.getNpc();
|
||||
if (hydra.getCombatLevel() != 0 && hydra.getName() != null) {
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (hydras.containsKey(hydra.getIndex())) {
|
||||
hydras.remove(hydra.getIndex());
|
||||
}
|
||||
if (hydraattacks.containsKey(hydra.getIndex())) {
|
||||
hydraattacks.remove(hydra.getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged event) {
|
||||
Actor monster = event.getActor();
|
||||
Actor local = client.getLocalPlayer();
|
||||
if (monster instanceof NPC) {
|
||||
NPC hydra = (NPC) monster;
|
||||
if (hydra.getCombatLevel() != 0 && hydra.getName() != null) {
|
||||
if (hydra.getName().equalsIgnoreCase("Hydra")) {
|
||||
if (hydras.containsKey(hydra.getIndex())) {
|
||||
if (hydra.getAnimation() == 8261 || hydra.getAnimation() == 8262) {
|
||||
if (hydra.getInteracting().equals(local)) {
|
||||
Hydra = hydra;
|
||||
}
|
||||
if (hydraattacks.containsKey(hydra.getIndex())) {
|
||||
int lastattack = hydraattacks.get(hydra.getIndex());
|
||||
hydraattacks.replace(hydra.getIndex(), hydra.getAnimation());
|
||||
|
||||
if (lastattack != hydra.getAnimation()) {
|
||||
hydras.replace(hydra.getIndex(), 2);
|
||||
} else {
|
||||
int currval = hydras.get(hydra.getIndex());
|
||||
if (currval == 1) {
|
||||
hydras.replace(hydra.getIndex(), 3);
|
||||
} else {
|
||||
hydras.replace(hydra.getIndex(), currval - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hydraattacks.put(hydra.getIndex(), hydra.getAnimation());
|
||||
int currval = hydras.get(hydra.getIndex());
|
||||
if (currval == 1) {
|
||||
hydras.replace(hydra.getIndex(), 3);
|
||||
} else {
|
||||
hydras.replace(hydra.getIndex(), currval - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package net.runelite.client.plugins.hydra;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.ImageComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
public class HydraPrayOverlay extends Overlay {
|
||||
private final HydraConfig config;
|
||||
private final HydraPlugin plugin;
|
||||
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private HydraPrayOverlay(HydraConfig config, HydraPlugin plugin, SpriteManager spriteManager) {
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
this.spriteManager = spriteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (!config.PrayerHelper()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (plugin.Hydra != null) {
|
||||
if (plugin.hydras.containsKey(plugin.Hydra.getIndex())) {
|
||||
int val = plugin.hydras.get(plugin.Hydra.getIndex());
|
||||
if (val != 0) {
|
||||
if (plugin.hydraattacks.containsKey(plugin.Hydra.getIndex())) {
|
||||
int attack = plugin.hydraattacks.get(plugin.Hydra.getIndex());
|
||||
if (attack == 8261) {
|
||||
if (val == 3) {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
} else {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
} else if (attack == 8262) {
|
||||
if (val == 3) {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
} else {
|
||||
final BufferedImage prayerImage = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
|
||||
imagePanelComponent.getChildren().clear();
|
||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
|
||||
return imagePanelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ public class InventoryTagsOverlay extends WidgetItemOverlay
|
||||
{
|
||||
this.itemManager = itemManager;
|
||||
this.plugin = plugin;
|
||||
showOnEquipment();
|
||||
showOnInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,6 +51,8 @@ class ItemChargeOverlay extends WidgetItemOverlay
|
||||
{
|
||||
this.itemChargePlugin = itemChargePlugin;
|
||||
this.config = config;
|
||||
showOnInventory();
|
||||
showOnEquipment();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.runelite.client.plugins.kittennotifier;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("kittennotifier")
|
||||
public interface KittenNotifierConfig extends Config{
|
||||
@ConfigItem(
|
||||
keyName = "absolutelyNeeded",
|
||||
name = "Notify only on Absolute Need",
|
||||
description = "Only notify when kitten absolutely needs food or attention."
|
||||
)
|
||||
default boolean absolutelyNeeded() { return false; }
|
||||
@ConfigItem(
|
||||
keyName = "catOwned",
|
||||
name = "",
|
||||
description = "",
|
||||
hidden = true
|
||||
)
|
||||
default boolean catOwned() { return false; }
|
||||
@ConfigItem(
|
||||
keyName = "catOwned",
|
||||
name = "",
|
||||
description = ""
|
||||
)
|
||||
void catOwned(Boolean bool);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.runelite.client.plugins.kittennotifier;
|
||||
import com.google.inject.Provides;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.NpcActionChanged;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Client;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "!Kitten Notifier",
|
||||
description = "Sends a notification when your kitten needs food, attention, or is grown.",
|
||||
tags = {"kitten, notifications"}
|
||||
)
|
||||
public class KittenNotifierPlugin extends Plugin{
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
@Inject
|
||||
private KittenNotifierConfig config;
|
||||
@Inject
|
||||
private Client client;
|
||||
@Provides
|
||||
KittenNotifierConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(KittenNotifierConfig.class);
|
||||
}
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event) {
|
||||
if (event.getType() == ChatMessageType.ENGINE && !config.catOwned()) {
|
||||
if (!config.absolutelyNeeded()) {
|
||||
if (event.getMessage().contentEquals("<col=ef1020>Your kitten is hungry.</col>")) {
|
||||
notifier.notify("Your kitten is hungry.");
|
||||
}
|
||||
if (event.getMessage().contentEquals("<col=ef1020>Your kitten wants attention.</col>")) {
|
||||
notifier.notify("Your kitten wants attention.");
|
||||
}
|
||||
}
|
||||
if (event.getMessage().contentEquals("<col=ef1020>Your kitten is very hungry.</col>")) {
|
||||
notifier.notify("Your kitten is very hungry.");
|
||||
}
|
||||
if (event.getMessage().contentEquals("<col=ef1020>Your kitten really wants attention.</col>")) {
|
||||
notifier.notify("Your kitten really wants attention.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@Subscribe
|
||||
public void onNpcActionChanged(NpcActionChanged event) {
|
||||
if (!config.catOwned()) {
|
||||
for (NPC npc : client.getNpcs()) {
|
||||
if (npc.getInteracting() != null) {
|
||||
if (npc.getName().contentEquals("Cat") && !config.catOwned()) {
|
||||
// If this if statement is included in previous it could null.
|
||||
if (npc.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) {
|
||||
config.catOwned(true);
|
||||
notifier.notify("Your kitten has grown into a cat.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event) {
|
||||
NPC cat = event.getNpc();
|
||||
if (cat.getName() != null) {
|
||||
if (cat.getName().equalsIgnoreCase("Kitten")) {
|
||||
if (cat.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) {
|
||||
config.catOwned(false);
|
||||
}
|
||||
}
|
||||
else if (cat.getName().contentEquals("Cat")) {
|
||||
if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) {
|
||||
config.catOwned(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.runelite.client.plugins.lizardmenshaman;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("shaman")
|
||||
public interface LizardmenShamanConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "showTimer",
|
||||
name = "Show timer",
|
||||
description = "Display timer till for lizardman shaman spawns."
|
||||
)
|
||||
default boolean showTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "notifyOnSpawn",
|
||||
name = "Notify on spawn",
|
||||
description = "Notify user when lizardman summons spawns."
|
||||
)
|
||||
default boolean notifyOnSpawn()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package net.runelite.client.plugins.lizardmenshaman;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"#4863A0\">!Lizard Shamans</font>",
|
||||
description = "Configures timer for lizardmen shaman spawns.",
|
||||
enabledByDefault = false,
|
||||
tags = {"shaman", "lizard", "lizardmen"}
|
||||
)
|
||||
@Slf4j
|
||||
public class LizardmenShamanPlugin extends Plugin
|
||||
{
|
||||
private static final String SHAMAN = "Lizardman shaman";
|
||||
private static final String MESSAGE = "A Lizardman shaman has summoned his spawn!";
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Map<LocalPoint, LizardmenShamanSpawn> spawns = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private ShamanSpawnOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private LizardmenShamanConfig config;
|
||||
|
||||
@Inject
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Provides
|
||||
LizardmenShamanConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(LizardmenShamanConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
spawns.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged event)
|
||||
{
|
||||
Actor actor = event.getActor();
|
||||
if (actor == null || actor.getName() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (actor.getName().equals(SHAMAN) && actor.getAnimation() == 7157)
|
||||
{
|
||||
if (config.showTimer())
|
||||
{
|
||||
spawns.put(event.getActor().getLocalLocation(), new LizardmenShamanSpawn(8.4, null));
|
||||
}
|
||||
|
||||
if (config.notifyOnSpawn())
|
||||
{
|
||||
notifier.notify(MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.runelite.client.plugins.lizardmenshaman;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
@AllArgsConstructor
|
||||
class LizardmenShamanSpawn
|
||||
{
|
||||
private final Instant start = Instant.now();
|
||||
private double countdownTimer;
|
||||
private Instant end;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package net.runelite.client.plugins.lizardmenshaman;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.ProgressPieComponent;
|
||||
|
||||
class ShamanSpawnOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final LizardmenShamanPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private ShamanSpawnOverlay(Client client, LizardmenShamanPlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
plugin.getSpawns().forEach((localPoint, spawn) ->
|
||||
{
|
||||
final Instant now = Instant.now();
|
||||
final long startCountdown = Duration.between(spawn.getStart(), now).getSeconds();
|
||||
final double certainSec = spawn.getCountdownTimer() - startCountdown;
|
||||
|
||||
if (certainSec <= 0)
|
||||
{
|
||||
if (spawn.getEnd() == null)
|
||||
{
|
||||
spawn.setEnd(Instant.now());
|
||||
}
|
||||
}
|
||||
|
||||
final ProgressPieComponent pieComponent = new ProgressPieComponent();
|
||||
final Point loc = Perspective.localToCanvas(client, localPoint, client.getPlane());
|
||||
|
||||
if (loc == null || certainSec < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pieComponent.setPosition(loc);
|
||||
pieComponent.setProgress(certainSec / spawn.getCountdownTimer());
|
||||
if (certainSec > 4.8)
|
||||
{
|
||||
pieComponent.setFill(Color.GREEN);
|
||||
pieComponent.setBorderColor(Color.GREEN);
|
||||
pieComponent.render(graphics);
|
||||
}
|
||||
else if (certainSec > 3.6)
|
||||
{
|
||||
pieComponent.setFill(Color.YELLOW);
|
||||
pieComponent.setBorderColor(Color.YELLOW);
|
||||
pieComponent.render(graphics);
|
||||
}
|
||||
else if (certainSec > 2.4)
|
||||
{
|
||||
pieComponent.setFill(Color.ORANGE);
|
||||
pieComponent.setBorderColor(Color.ORANGE);
|
||||
pieComponent.render(graphics);
|
||||
}
|
||||
else if (certainSec > 1.2)
|
||||
{
|
||||
pieComponent.setFill(new Color(255, 140, 0));
|
||||
pieComponent.setBorderColor(new Color(255, 140, 0));
|
||||
pieComponent.render(graphics);
|
||||
}
|
||||
else
|
||||
{
|
||||
pieComponent.setFill(Color.RED);
|
||||
pieComponent.setBorderColor(Color.RED);
|
||||
pieComponent.render(graphics);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.runelite.client.plugins.menumodifier;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("menumodifier")
|
||||
public interface MenuModifierConfig extends Config
|
||||
{
|
||||
@ConfigItem(position = 0, keyName = "hideCancel", name = "Hide Cancel", description = "Hides the 'cancel' option from the right click menu")
|
||||
default boolean hideCancel() { return true; }
|
||||
|
||||
@ConfigItem(position = 1, keyName = "hideExamine", name = "Hide Examine", description = "Hides the 'examine' option from the right click menu")
|
||||
default boolean hideExamine() { return true; }
|
||||
|
||||
@ConfigItem(position = 2, keyName = "hideTradeWith", name = "Hide Trade With", description = "Hides the 'trade with' option from the right click menu")
|
||||
default boolean hideTradeWith() { return true; }
|
||||
|
||||
@ConfigItem(position = 3, keyName = "hideReport", name = "Hide Report", description = "Hides the 'report' option from the right click menu")
|
||||
default boolean hideReport() { return true; }
|
||||
|
||||
@ConfigItem(position = 4, keyName = "hideLookup", name = "Hide Lookup", description = "Hides the 'lookup' option from the right click menu")
|
||||
default boolean hideLookup() { return true; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.runelite.client.plugins.menumodifier;
|
||||
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.MouseAdapter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class MenuModifierInputListener extends MouseAdapter implements KeyListener
|
||||
{
|
||||
private static final int HOTKEY = KeyEvent.VK_CONTROL;
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
private MenuModifierPlugin plugin;
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == HOTKEY)
|
||||
{
|
||||
plugin.setHotKeyPressed(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == HOTKEY)
|
||||
{
|
||||
plugin.setHotKeyPressed(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package net.runelite.client.plugins.menumodifier;
|
||||
|
||||
import net.runelite.api.events.MenuOpened;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.util.MiscUtils;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!Menu Modifier</font>",
|
||||
description = "Changes right click menu for players",
|
||||
tags = { "menu", "modifier", "right", "click", "pk", "bogla" },
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class MenuModifierPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private MenuModifierConfig config;
|
||||
|
||||
@Inject
|
||||
private MenuModifierInputListener inputListener;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Provides
|
||||
MenuModifierConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(MenuModifierConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
keyManager.unregisterKeyListener(inputListener);
|
||||
}
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean hotKeyPressed;
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOpened(MenuOpened event)
|
||||
{
|
||||
Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
if (localPlayer == null)
|
||||
return;
|
||||
|
||||
if (!(MiscUtils.getWildernessLevelFrom(client, localPlayer.getWorldLocation()) >= 0))
|
||||
return;
|
||||
|
||||
if (hotKeyPressed)
|
||||
return;
|
||||
|
||||
List<MenuEntry> menu_entries = new ArrayList<MenuEntry>();
|
||||
|
||||
for (MenuEntry entry : event.getMenuEntries())
|
||||
{
|
||||
String option = Text.removeTags(entry.getOption()).toLowerCase();
|
||||
|
||||
if (option.contains("trade with") && config.hideTradeWith())
|
||||
continue;
|
||||
|
||||
if (option.contains("lookup") && config.hideLookup())
|
||||
continue;
|
||||
|
||||
if (option.contains("report") && config.hideReport())
|
||||
continue;
|
||||
|
||||
if (option.contains("examine") && config.hideExamine())
|
||||
continue;
|
||||
|
||||
int identifier = entry.getIdentifier();
|
||||
|
||||
Player[] players = client.getCachedPlayers();
|
||||
Player player = null;
|
||||
|
||||
if (identifier >= 0 && identifier < players.length)
|
||||
player = players[identifier];
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
menu_entries.add(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((option.contains("attack") || option.contains("cast")) && (player.isFriend() || player.isClanMember()))
|
||||
continue;
|
||||
|
||||
menu_entries.add(entry);
|
||||
}
|
||||
|
||||
MenuEntry[] updated_menu_entries = new MenuEntry[menu_entries.size()];
|
||||
updated_menu_entries = menu_entries.toArray(updated_menu_entries);
|
||||
|
||||
client.setMenuEntries(updated_menu_entries);
|
||||
}
|
||||
|
||||
/*@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
|
||||
{
|
||||
if (true)
|
||||
return;
|
||||
|
||||
if (!inWilderness)
|
||||
return;
|
||||
|
||||
if (hotKeyPressed)
|
||||
return;
|
||||
|
||||
String option = Text.removeTags(menuEntryAdded.getOption()).toLowerCase();
|
||||
|
||||
if ((option.contains("trade with") && config.hideTradeWith())
|
||||
|| (option.contains("lookup") && config.hideLookup())
|
||||
|| (option.contains("report") && config.hideReport())
|
||||
|| (option.contains("examine") && config.hideExamine())
|
||||
|| (option.contains("cancel") && config.hideCancel()))
|
||||
{
|
||||
int identifier = menuEntryAdded.getIdentifier();
|
||||
|
||||
Player[] players = client.getCachedPlayers();
|
||||
Player player = null;
|
||||
|
||||
if (identifier >= 0 && identifier < players.length)
|
||||
player = players[identifier];
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
//allow trading with friends/clanmates
|
||||
if (option.contains("trade with") && (player.isFriend() || player.isClanMember()))
|
||||
return;
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
|
||||
if (menuEntries.length > 0)
|
||||
client.setMenuEntries(Arrays.copyOf(menuEntries, menuEntries.length - 1));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Rodolfo Ruiz-Velasco <https://github.com/lequietriot/>
|
||||
* 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.musicmodifier;
|
||||
|
||||
import javax.sound.midi.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MidiFileAdjuster {
|
||||
|
||||
private int bankLSBValue;
|
||||
private int chPosition = -1;
|
||||
|
||||
private boolean customBank = false;
|
||||
|
||||
public Sequence reorderTracks(Sequence sequence) throws InvalidMidiDataException, IOException {
|
||||
for (Track track : sequence.getTracks()) {
|
||||
for (int i = 0; i < track.size(); i++) {
|
||||
MidiEvent midiEvent = track.get(i);
|
||||
MidiMessage midiMessage = midiEvent.getMessage();
|
||||
|
||||
if (midiMessage instanceof ShortMessage) {
|
||||
ShortMessage sm = (ShortMessage) midiMessage;
|
||||
|
||||
if (sm.getChannel() < 16) {
|
||||
getBankLSB(sm);
|
||||
|
||||
if (i == 0 & bankLSBValue != 1) {
|
||||
chPosition++;
|
||||
if (chPosition == 9) {
|
||||
chPosition = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (!customBank) {
|
||||
|
||||
if (sm.getChannel() == 9) {
|
||||
bankLSBValue = 1;
|
||||
}
|
||||
|
||||
if (sm.getChannel() != 9) {
|
||||
bankLSBValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bankLSBValue == 1) {
|
||||
|
||||
int drumChannel = 9;
|
||||
if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) {
|
||||
sm.setMessage(ShortMessage.PROGRAM_CHANGE, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) {
|
||||
sm.setMessage(ShortMessage.CONTROL_CHANGE, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.NOTE_OFF) {
|
||||
sm.setMessage(ShortMessage.NOTE_OFF, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.NOTE_ON) {
|
||||
sm.setMessage(ShortMessage.NOTE_ON, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) {
|
||||
sm.setMessage(ShortMessage.PROGRAM_CHANGE, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) {
|
||||
sm.setMessage(ShortMessage.CONTROL_CHANGE, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.PITCH_BEND) {
|
||||
sm.setMessage(ShortMessage.PITCH_BEND, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.CHANNEL_PRESSURE) {
|
||||
sm.setMessage(ShortMessage.CHANNEL_PRESSURE, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.POLY_PRESSURE) {
|
||||
sm.setMessage(ShortMessage.POLY_PRESSURE, drumChannel, sm.getData1(), sm.getData2());
|
||||
}
|
||||
} else {
|
||||
|
||||
if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) {
|
||||
sm.setMessage(ShortMessage.PROGRAM_CHANGE, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) {
|
||||
sm.setMessage(ShortMessage.CONTROL_CHANGE, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.NOTE_OFF) {
|
||||
sm.setMessage(ShortMessage.NOTE_OFF, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.NOTE_ON) {
|
||||
sm.setMessage(ShortMessage.NOTE_ON, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.PROGRAM_CHANGE) {
|
||||
sm.setMessage(ShortMessage.PROGRAM_CHANGE, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) {
|
||||
sm.setMessage(ShortMessage.CONTROL_CHANGE, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.PITCH_BEND) {
|
||||
sm.setMessage(ShortMessage.PITCH_BEND, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.CHANNEL_PRESSURE) {
|
||||
sm.setMessage(ShortMessage.CHANNEL_PRESSURE, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
|
||||
if (sm.getCommand() == ShortMessage.POLY_PRESSURE) {
|
||||
sm.setMessage(ShortMessage.POLY_PRESSURE, chPosition, sm.getData1(), sm.getData2());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sequence;
|
||||
}
|
||||
|
||||
private void getBankLSB(ShortMessage sm) throws InvalidMidiDataException
|
||||
{
|
||||
if (sm.getCommand() == ShortMessage.CONTROL_CHANGE)
|
||||
{
|
||||
if (sm.getData1() == 32)
|
||||
{
|
||||
bankLSBValue = sm.getData2();
|
||||
customBank = true;
|
||||
}
|
||||
if (sm.getData1() == 0)
|
||||
{
|
||||
sm.setMessage(sm.getCommand(), sm.getChannel(), sm.getData1(), bankLSBValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Rodolfo Ruiz-Velasco <https://github.com/lequietriot/>
|
||||
* 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.musicmodifier;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.*;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxTextInput;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Music Track Customizer",
|
||||
description = "Customize what track plays and how it sounds, with local files",
|
||||
tags = {"music", "sound"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
public class MusicCustomizerPlugin extends Plugin
|
||||
{
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
private RealTimeMIDIPlayer realTimeMIDIPlayer = new RealTimeMIDIPlayer();
|
||||
|
||||
private String songName = "Scape Main";
|
||||
|
||||
private ChatboxTextInput songInput;
|
||||
|
||||
private Widget playlistModeButton;
|
||||
|
||||
private Widget playlistBox;
|
||||
|
||||
private Widget hidePlaylistButton;
|
||||
|
||||
private Widget addPlaylistSongButton;
|
||||
|
||||
private Widget playlistText;
|
||||
|
||||
private Widget playlistSong;
|
||||
|
||||
private String defaultUnlockedSongs;
|
||||
|
||||
private boolean isLooping = true;
|
||||
|
||||
private boolean playlistMode = false;
|
||||
|
||||
private int newSongY = 34;
|
||||
|
||||
private int playlistCount = 0;
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
playSong(songName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
if (realTimeMIDIPlayer != null)
|
||||
{
|
||||
realTimeMIDIPlayer.stopSong();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!playlistMode)
|
||||
{
|
||||
String newSong = client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).getText();
|
||||
|
||||
if (!newSong.equals(songName))
|
||||
{
|
||||
songName = newSong;
|
||||
playSongFromList(songName);
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException ignored)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void playSong(String song)
|
||||
{
|
||||
File midiMusicFile = new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" +
|
||||
"Music/" + song + ".mid/");
|
||||
if (realTimeMIDIPlayer.midi == null)
|
||||
{
|
||||
realTimeMIDIPlayer.midi = midiMusicFile;
|
||||
realTimeMIDIPlayer.run();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (realTimeMIDIPlayer.isPlaying())
|
||||
{
|
||||
realTimeMIDIPlayer.stopSong();
|
||||
}
|
||||
realTimeMIDIPlayer.midi = midiMusicFile;
|
||||
realTimeMIDIPlayer.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onWidgetLoaded(WidgetLoaded widgetLoaded)
|
||||
{
|
||||
if (widgetLoaded.getGroupId() == WidgetID.MUSICTAB_GROUP_ID)
|
||||
{
|
||||
Widget musicPlayerSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS);
|
||||
if (musicPlayerSongs != null)
|
||||
{
|
||||
playlistModeButton = musicPlayerSongs.createChild(-1, WidgetType.GRAPHIC);
|
||||
playlistModeButton.setSpriteId(SpriteID.RS2_TAB_MUSIC);
|
||||
playlistModeButton.setOriginalWidth(32);
|
||||
playlistModeButton.setOriginalHeight(32);
|
||||
playlistModeButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT);
|
||||
playlistModeButton.setOriginalX(0);
|
||||
playlistModeButton.setOriginalY(0);
|
||||
playlistModeButton.setHasListener(true);
|
||||
playlistModeButton.setAction(1, "Open");
|
||||
playlistModeButton.setOnOpListener((JavaScriptCallback) e -> openPlaylist());
|
||||
playlistModeButton.setName("Playlist");
|
||||
playlistModeButton.setHidden(true); //Playlist is not enabled for this release (Unfinished).
|
||||
playlistModeButton.revalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void openPlaylist()
|
||||
{
|
||||
playlistMode = true;
|
||||
|
||||
Widget currentPlayingSong = client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME);
|
||||
Widget allInGameSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS);
|
||||
Widget musicScrollbar = client.getWidget(WidgetInfo.MUSICTAB_SCROLLBAR);
|
||||
allInGameSongs.setHidden(true);
|
||||
musicScrollbar.setHidden(true);
|
||||
|
||||
defaultUnlockedSongs = client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).getText();
|
||||
|
||||
client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(playlistCount + " / 10");
|
||||
|
||||
playlistBox = client.getWidget(WidgetInfo.MUSICTAB_INTERFACE);
|
||||
|
||||
playlistText = playlistBox.createChild(-1, WidgetType.TEXT);
|
||||
playlistText.setText("Music Playlist");
|
||||
playlistText.setFontId(497);
|
||||
playlistText.setXPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
playlistText.setOriginalX(40);
|
||||
playlistText.setOriginalY(14);
|
||||
playlistText.setOriginalHeight(1);
|
||||
playlistText.setOriginalWidth(1);
|
||||
playlistText.setTextColor(currentPlayingSong.getTextColor());
|
||||
playlistText.revalidate();
|
||||
|
||||
hidePlaylistButton = playlistBox.createChild(-1, WidgetType.GRAPHIC);
|
||||
hidePlaylistButton.setSpriteId(SpriteID.RS2_TAB_MUSIC);
|
||||
hidePlaylistButton.setOriginalWidth(32);
|
||||
hidePlaylistButton.setOriginalHeight(32);
|
||||
hidePlaylistButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT);
|
||||
hidePlaylistButton.setOriginalX(0);
|
||||
hidePlaylistButton.setOriginalY(6);
|
||||
hidePlaylistButton.setHasListener(true);
|
||||
hidePlaylistButton.setAction(1, "Close");
|
||||
hidePlaylistButton.setOnOpListener((JavaScriptCallback) e -> closePlaylist());
|
||||
hidePlaylistButton.setName("Playlist");
|
||||
hidePlaylistButton.revalidate();
|
||||
|
||||
addPlaylistSongButton = playlistBox.createChild(-1, WidgetType.GRAPHIC);
|
||||
addPlaylistSongButton.setSpriteId(SpriteID.BANK_ADD_TAB_ICON);
|
||||
addPlaylistSongButton.setOriginalWidth(36);
|
||||
addPlaylistSongButton.setOriginalHeight(32);
|
||||
addPlaylistSongButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_LEFT);
|
||||
addPlaylistSongButton.setOriginalX(0);
|
||||
addPlaylistSongButton.setOriginalY(6);
|
||||
addPlaylistSongButton.setHasListener(true);
|
||||
addPlaylistSongButton.setAction(1, "Add to");
|
||||
addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> addSongFromInput());
|
||||
addPlaylistSongButton.setName("Playlist");
|
||||
addPlaylistSongButton.revalidate();
|
||||
|
||||
if (playlistSong != null)
|
||||
{
|
||||
playlistSong.setHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void closePlaylist()
|
||||
{
|
||||
playlistMode = false;
|
||||
|
||||
Widget allInGameSongs = client.getWidget(WidgetInfo.MUSICTAB_ALL_SONGS);
|
||||
Widget musicScrollbar = client.getWidget(WidgetInfo.MUSICTAB_SCROLLBAR);
|
||||
allInGameSongs.setHidden(false);
|
||||
musicScrollbar.setHidden(false);
|
||||
|
||||
client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(defaultUnlockedSongs);
|
||||
playlistText.setHidden(true);
|
||||
addPlaylistSongButton.setHidden(true);
|
||||
hidePlaylistButton.setHidden(true);
|
||||
|
||||
if (playlistSong != null)
|
||||
{
|
||||
playlistSong.setHidden(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSongFromInput()
|
||||
{
|
||||
addPlaylistSongButton.setAction(1, "Close search");
|
||||
addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> closeInput());
|
||||
songInput = chatboxPanelManager.openTextInput("Please type a valid song name")
|
||||
.onChanged(s -> clientThread.invokeLater(() -> updateSongs(s)))
|
||||
.onClose(() ->
|
||||
{
|
||||
clientThread.invokeLater(() -> updateSongs(songInput.getValue()));
|
||||
addPlaylistSongButton.setOnOpListener((JavaScriptCallback) e -> addSongFromInput());
|
||||
addPlaylistSongButton.setAction(1, "Add to");
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private void updateSongs()
|
||||
{
|
||||
String song = "";
|
||||
if (chatboxIsOpen())
|
||||
{
|
||||
song = songInput.getValue();
|
||||
}
|
||||
updateSongs(song);
|
||||
}
|
||||
|
||||
private void updateSongs(String song)
|
||||
{
|
||||
if (playlistBox == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" +
|
||||
"Music/" + song + ".mid/").exists())
|
||||
{
|
||||
playListSongPlayer(song);
|
||||
}
|
||||
}
|
||||
|
||||
private void playListSongPlayer(String song)
|
||||
{
|
||||
if (!song.equals(songName) && !chatboxIsOpen() && playlistCount < 10)
|
||||
{
|
||||
Widget playlistWidget = client.getWidget(WidgetInfo.MUSICTAB_INTERFACE);
|
||||
playlistSong = playlistWidget.createChild(-1, WidgetType.TEXT);
|
||||
playlistSong.setText(song);
|
||||
playlistSong.setFontId(495);
|
||||
playlistSong.setOriginalX(12);
|
||||
playlistSong.setOriginalY(newSongY);
|
||||
playlistSong.setOriginalWidth(120);
|
||||
playlistSong.setOriginalHeight(16);
|
||||
playlistSong.setTextColor(client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).getTextColor());
|
||||
playlistSong.setHasListener(true);
|
||||
playlistSong.setAction(1, "Play");
|
||||
playlistSong.setOnOpListener((JavaScriptCallback) e -> playSongFromList(song));
|
||||
playlistSong.setName(song);
|
||||
playlistSong.revalidate();
|
||||
|
||||
newSongY = newSongY + 15;
|
||||
|
||||
songName = song;
|
||||
|
||||
playlistCount++;
|
||||
client.getWidget(WidgetInfo.MUSICTAB_UNLOCKED_SONGS).setText(playlistCount + " / 10");
|
||||
|
||||
if (playlistCount == 10)
|
||||
{
|
||||
addPlaylistSongButton.setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean chatboxIsOpen()
|
||||
{
|
||||
return songInput != null && chatboxPanelManager.getCurrentInput() == songInput;
|
||||
}
|
||||
|
||||
private void closeInput()
|
||||
{
|
||||
updateSongs();
|
||||
chatboxPanelManager.close();
|
||||
}
|
||||
|
||||
private void playSongFromList(String song)
|
||||
{
|
||||
client.getWidget(WidgetInfo.MUSICTAB_CURRENT_SONG_NAME).setName(song);
|
||||
File midiMusicFile = new File(System.getProperty("user.home") + "/RuneLiteAudio/MIDI Files/" +
|
||||
"Music/" + song + ".mid/");
|
||||
|
||||
if (realTimeMIDIPlayer.midi == null)
|
||||
{
|
||||
realTimeMIDIPlayer.midi = midiMusicFile;
|
||||
realTimeMIDIPlayer.run();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (realTimeMIDIPlayer.isPlaying())
|
||||
{
|
||||
realTimeMIDIPlayer.stopSong();
|
||||
}
|
||||
realTimeMIDIPlayer.midi = midiMusicFile;
|
||||
realTimeMIDIPlayer.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Rodolfo Ruiz-Velasco <https://github.com/lequietriot/>
|
||||
* 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.musicmodifier;
|
||||
|
||||
import com.sun.media.sound.AudioSynthesizer;
|
||||
|
||||
import javax.sound.midi.*;
|
||||
import javax.sound.sampled.*;
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RealTimeMIDIPlayer implements Runnable
|
||||
{
|
||||
private AudioFormat format;
|
||||
|
||||
private Sequence midiSequence;
|
||||
|
||||
private Soundbank soundbank;
|
||||
|
||||
private SourceDataLine sdl;
|
||||
|
||||
private MusicCustomizerPlugin customMusicPlugin;
|
||||
|
||||
private MidiFileAdjuster adjuster;
|
||||
|
||||
private Clip clip;
|
||||
|
||||
public boolean looping = true;
|
||||
|
||||
public File soundFont = new File(System.getProperty("user.home") + "/RuneLiteAudio/SoundFonts/" +
|
||||
"RuneScape 2.sf2/");
|
||||
|
||||
public File midi;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
adjuster = new MidiFileAdjuster(); //Unfinished class
|
||||
|
||||
midiSequence = MidiSystem.getSequence(midi);
|
||||
soundbank = MidiSystem.getSoundbank(soundFont);
|
||||
init();
|
||||
}
|
||||
catch (IOException | InvalidMidiDataException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopSong()
|
||||
{
|
||||
if (sdl.isRunning())
|
||||
{
|
||||
sdl.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static AudioSynthesizer findAudioSynthesizer() throws MidiUnavailableException
|
||||
{
|
||||
Synthesizer synth = MidiSystem.getSynthesizer();
|
||||
if (synth instanceof AudioSynthesizer)
|
||||
return (AudioSynthesizer) synth;
|
||||
|
||||
double gain = 0.8D;
|
||||
|
||||
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
|
||||
MidiChannel[] channels = synth.getChannels();
|
||||
|
||||
for (int i = 0; i < channels.length; i++)
|
||||
{
|
||||
channels[i].controlChange(7, ((int) (channels[i].getController(7) * gain)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < infos.length; i++)
|
||||
{
|
||||
MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
|
||||
|
||||
if (device instanceof AudioSynthesizer)
|
||||
return (AudioSynthesizer) device;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isPlaying()
|
||||
{
|
||||
return sdl.isActive();
|
||||
}
|
||||
|
||||
public static double send(Sequence sequence, Receiver receiver) {
|
||||
float divtype = sequence.getDivisionType();
|
||||
assert (sequence.getDivisionType() == Sequence.PPQ);
|
||||
Track[] tracks = sequence.getTracks();
|
||||
int[] trackspos = new int[tracks.length];
|
||||
int mpq = 500000;
|
||||
int seqres = sequence.getResolution();
|
||||
long lasttick = 0;
|
||||
long curtime = 0;
|
||||
while (true) {
|
||||
MidiEvent selevent = null;
|
||||
int seltrack = -1;
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
int trackpos = trackspos[i];
|
||||
Track track = tracks[i];
|
||||
if (trackpos < track.size()) {
|
||||
MidiEvent event = track.get(trackpos);
|
||||
if (selevent == null
|
||||
|| event.getTick() < selevent.getTick()) {
|
||||
selevent = event;
|
||||
seltrack = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seltrack == -1)
|
||||
break;
|
||||
trackspos[seltrack]++;
|
||||
long tick = selevent.getTick();
|
||||
if (divtype == Sequence.PPQ)
|
||||
curtime += ((tick - lasttick) * mpq) / seqres;
|
||||
else
|
||||
curtime = (long) ((tick * 1000000.0 * divtype) / seqres);
|
||||
lasttick = tick;
|
||||
MidiMessage msg = selevent.getMessage();
|
||||
if (msg instanceof MetaMessage) {
|
||||
if (divtype == Sequence.PPQ)
|
||||
if (((MetaMessage) msg).getType() == 0x51) {
|
||||
byte[] data = ((MetaMessage) msg).getData();
|
||||
mpq = ((data[0] & 0xff) << 16)
|
||||
| ((data[1] & 0xff) << 8) | (data[2] & 0xff);
|
||||
}
|
||||
} else {
|
||||
if (receiver != null)
|
||||
receiver.send(msg, curtime);
|
||||
}
|
||||
}
|
||||
return curtime / 1000000.0;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
AudioSynthesizer synth = null;
|
||||
try {
|
||||
synth = findAudioSynthesizer();
|
||||
format = new AudioFormat(44100, 16, 2, true, false);
|
||||
|
||||
Map<String, Object> info = new HashMap<String, Object>();
|
||||
info.put("resamplerType", "sinc");
|
||||
info.put("maxPolyphony", "8192");
|
||||
AudioInputStream ais = synth.openStream(format, info);
|
||||
synth.unloadAllInstruments(synth.getDefaultSoundbank());
|
||||
synth.loadAllInstruments(soundbank);
|
||||
double total = send(midiSequence, synth.getReceiver());
|
||||
long length = (long) (ais.getFormat().getFrameRate() * (total + 4));
|
||||
AudioInputStream stream = new AudioInputStream(ais, format, length);
|
||||
sdl = AudioSystem.getSourceDataLine(format);
|
||||
sdl.open(format);
|
||||
sdl.start();
|
||||
writeAudio(sdl, stream);
|
||||
} catch (LineUnavailableException | MidiUnavailableException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void writeAudio(SourceDataLine sdl, AudioInputStream stream)
|
||||
{
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
byte[] sampledAudio = new byte[1024];
|
||||
|
||||
int numBytesRead = 0;
|
||||
|
||||
while (numBytesRead != -1) {
|
||||
try
|
||||
{
|
||||
numBytesRead = stream.read(sampledAudio, 0, sampledAudio.length);
|
||||
|
||||
if (numBytesRead >= 0) {
|
||||
sdl.write(sampledAudio, 0, numBytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
finally {
|
||||
|
||||
if (!isPlaying() && looping)
|
||||
{
|
||||
this.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package net.runelite.client.plugins.nexthitnotifier;
|
||||
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
|
||||
@ConfigGroup("nexthitnotifier")
|
||||
public interface NextHitNotifierConfig extends Config
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package net.runelite.client.plugins.nexthitnotifier;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.util.MiscUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
|
||||
public class NextHitNotifierOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final NextHitNotifierPlugin plugin;
|
||||
private final NextHitNotifierConfig config;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
private final Dimension panelSize = new Dimension(48, 0);
|
||||
|
||||
@Inject
|
||||
private NextHitNotifierOverlay(Client client, NextHitNotifierPlugin plugin, NextHitNotifierConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.BOTTOM_LEFT);
|
||||
//setPosition(OverlayPosition.DYNAMIC);
|
||||
//setPosition(OverlayPosition.DETACHED);
|
||||
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
panelComponent.getChildren().clear();
|
||||
panelComponent.setPreferredSize(panelSize);
|
||||
|
||||
String lastHitText = Integer.toString(plugin.lastHit);
|
||||
int lastHit = plugin.lastHit;
|
||||
|
||||
if (plugin.showTime < 0)
|
||||
{
|
||||
lastHitText = "0";
|
||||
lastHit = 0;
|
||||
}
|
||||
|
||||
int g = (int)MiscUtils.clamp((float)Math.floor(lastHit / 30.f) * 255.f, 0.f, 255.f);
|
||||
int r = 255 - g;
|
||||
|
||||
Color textColor = Color.getHSBColor(Color.RGBtoHSB(r, g, 0, null)[0], 1.f, 1.f);
|
||||
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Next hit:").color(Color.YELLOW).build());
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text(lastHitText).color(textColor).build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package net.runelite.client.plugins.nexthitnotifier;
|
||||
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"green\">!Next Hit Notifier</font>",
|
||||
description = "Shows estimated next hit based on xp drop.",
|
||||
tags = { "experience", "damage", "overlay", "pking", "bogla" },
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class NextHitNotifierPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private NextHitNotifierOverlay overlay;
|
||||
|
||||
private int lastHpXp = 0;
|
||||
int lastHit = 0;
|
||||
int showTime = 0;
|
||||
|
||||
@Provides
|
||||
NextHitNotifierConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(NextHitNotifierConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
lastHpXp = client.getSkillExperience(Skill.HITPOINTS);
|
||||
lastHit = 0;
|
||||
showTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastHpXp = 0;
|
||||
lastHit = 0;
|
||||
showTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (showTime > 0)
|
||||
showTime--;
|
||||
else
|
||||
lastHit = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onExperienceChanged(ExperienceChanged event)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
lastHpXp = 0;
|
||||
lastHit = 0;
|
||||
showTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
final Skill skill = event.getSkill();
|
||||
|
||||
if (skill != Skill.HITPOINTS)
|
||||
return;
|
||||
|
||||
final int currentXp = client.getSkillExperience(skill);
|
||||
|
||||
int gainedXp = currentXp - lastHpXp;
|
||||
|
||||
//filter out big xp drops (such as login)
|
||||
if (gainedXp > 1000)
|
||||
{
|
||||
lastHpXp = client.getSkillExperience(skill);
|
||||
return;
|
||||
}
|
||||
|
||||
lastHit = (int)Math.rint(gainedXp / 1.33f);
|
||||
lastHpXp = currentXp;
|
||||
showTime = 3;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.runelite.client.plugins.pkvision;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("pkvision")
|
||||
public interface PKVisionConfig extends Config
|
||||
{
|
||||
@ConfigItem(position = 0, keyName = "drawOwnName", name = "Highlight own player", description = "Configures whether or not your own player should be highlighted")
|
||||
default boolean highlightOwnPlayer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 1, keyName = "ownNameColor", name = "Own player color", description = "Color of your own player")
|
||||
default Color getOwnPlayerColor()
|
||||
{
|
||||
return new Color(0, 184, 212);
|
||||
}
|
||||
|
||||
@ConfigItem(position = 2, keyName = "drawFriendNames", name = "Highlight friends", description = "Configures whether or not friends should be highlighted")
|
||||
default boolean highlightFriends()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 3, keyName = "friendNameColor", name = "Friend color", description = "Color of friend names" )
|
||||
default Color getFriendColor()
|
||||
{
|
||||
return new Color(0, 200, 80);
|
||||
}
|
||||
|
||||
@ConfigItem(position = 4, keyName = "drawPlayerTiles", name = "Draw tiles under players", description = "Configures whether or not tiles under highlighted players should be drawn")
|
||||
default boolean drawTiles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(position = 5, keyName = "drawPlayerNames", name = "Draw names above players", description = "Configures whether or not player names should be drawn above players")
|
||||
default boolean drawPlayerNames() { return true; }
|
||||
|
||||
@ConfigItem(position = 6, keyName = "drawPlayerLevels", name = "Draw levels above players", description = "Configures whether or not player levels should be drawn above players")
|
||||
default boolean drawPlayerLevels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//@ConfigItem(position = 7, keyName = "drawPlayerHealth", name = "Draw health above players", description = "Configures whether or not player levels should be drawn above players")
|
||||
//default boolean drawPlayerHealth()
|
||||
//{
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.runelite.client.plugins.pkvision;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class PKVisionMinimapOverlay extends Overlay
|
||||
{
|
||||
private final PKVisionService pkVisionService;
|
||||
|
||||
@Inject
|
||||
private PKVisionMinimapOverlay(PKVisionService pkVisionService)
|
||||
{
|
||||
this.pkVisionService = pkVisionService;
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
pkVisionService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
final net.runelite.api.Point minimapLocation = actor.getMinimapLocation();
|
||||
|
||||
if (minimapLocation != null)
|
||||
OverlayUtil.renderTextLocation(graphics, minimapLocation, Integer.toString(actor.getCombatLevel()), color);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.runelite.client.plugins.pkvision;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
@Singleton
|
||||
public class PKVisionOverlay extends Overlay
|
||||
{
|
||||
private final PKVisionService pkVisionService;
|
||||
private final PKVisionConfig config;
|
||||
|
||||
@Inject
|
||||
private PKVisionOverlay(PKVisionConfig config, PKVisionService pkVisionService, PKVisionPlugin pkVisionPlugin)
|
||||
{
|
||||
this.config = config;
|
||||
this.pkVisionService = pkVisionService;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
pkVisionService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color));
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color)
|
||||
{
|
||||
if (!config.drawPlayerNames() && !config.drawPlayerLevels())
|
||||
return;
|
||||
|
||||
String text = "";
|
||||
if (config.drawPlayerLevels())
|
||||
text += "(" + actor.getCombatLevel() + ") ";
|
||||
|
||||
if (config.drawPlayerNames())
|
||||
text += actor.getName().replace('\u00A0', ' ');
|
||||
|
||||
Point textLocation = actor.getCanvasTextLocation(graphics, text, actor.getLogicalHeight() + 40);
|
||||
|
||||
if (textLocation != null)
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, text, color);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package net.runelite.client.plugins.pkvision;
|
||||
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.*;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.MenuEntryAdded;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.MiscUtils;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"aqua\">!PK Vision</font>",
|
||||
description = "Highlight players on-screen and/or on the minimap",
|
||||
tags = {"highlight", "minimap", "overlay", "players", "pk", "helper", "vision", "bogla"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class PKVisionPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private PKVisionConfig config;
|
||||
|
||||
@Inject
|
||||
private PKVisionOverlay pkVisionOverlay;
|
||||
|
||||
@Inject
|
||||
private PKVisionTileOverlay pkVisionTileOverlay;
|
||||
|
||||
@Inject
|
||||
private PKVisionMinimapOverlay pkVisionMinimapOverlay;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Provides
|
||||
PKVisionConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(PKVisionConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(pkVisionOverlay);
|
||||
overlayManager.add(pkVisionTileOverlay);
|
||||
overlayManager.add(pkVisionMinimapOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(pkVisionOverlay);
|
||||
overlayManager.remove(pkVisionTileOverlay);
|
||||
overlayManager.remove(pkVisionMinimapOverlay);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
|
||||
{
|
||||
int type = menuEntryAdded.getType();
|
||||
String option = Text.removeTags(menuEntryAdded.getOption()).toLowerCase();
|
||||
|
||||
if (type >= 2000)
|
||||
type -= 2000;
|
||||
|
||||
int identifier = menuEntryAdded.getIdentifier();
|
||||
if (type == FOLLOW.getId() || type == TRADE.getId()
|
||||
|| type == ITEM_USE_ON_PLAYER.getId() || type == PLAYER_FIRST_OPTION.getId()
|
||||
|| type == PLAYER_SECOND_OPTION.getId() || type == PLAYER_THIRD_OPTION.getId()
|
||||
|| type == PLAYER_FOURTH_OPTION.getId() || type == PLAYER_FIFTH_OPTION.getId()
|
||||
|| type == PLAYER_SIXTH_OPTION.getId() || type == PLAYER_SEVENTH_OPTION.getId()
|
||||
|| type == PLAYER_EIGTH_OPTION.getId() || type == SPELL_CAST_ON_PLAYER.getId()
|
||||
|| type == RUNELITE.getId())
|
||||
{
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
Player[] players = client.getCachedPlayers();
|
||||
Player player = null;
|
||||
|
||||
if (identifier >= 0 && identifier < players.length)
|
||||
player = players[identifier];
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
Color color = null;
|
||||
|
||||
if (config.highlightFriends() && (player.isFriend() || player.isClanMember()))
|
||||
{
|
||||
color = config.getFriendColor();
|
||||
}
|
||||
else if (!player.isFriend() && !player.isClanMember())
|
||||
{
|
||||
int lvlDelta = player.getCombatLevel() - localPlayer.getCombatLevel();
|
||||
int wildyLvl = MiscUtils.getWildernessLevelFrom(client, player.getWorldLocation());
|
||||
|
||||
if (wildyLvl <= 0)
|
||||
return;
|
||||
|
||||
int R = MiscUtils.clamp((int)(((float)(lvlDelta + wildyLvl) / (float)(wildyLvl * 2)) * 255.f), 0, 255);
|
||||
int G = MiscUtils.clamp(255 - R, 0, 255);
|
||||
|
||||
if (Math.abs(lvlDelta) <= wildyLvl)
|
||||
color = Color.getHSBColor(Color.RGBtoHSB(R, G, 0, null)[0], 1.f, 1.f);
|
||||
}
|
||||
|
||||
if (color != null)
|
||||
{
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
|
||||
|
||||
// strip out existing <col...
|
||||
String target = lastEntry.getTarget();
|
||||
int idx = target.indexOf('>');
|
||||
if (idx != -1)
|
||||
target = target.substring(idx + 1);
|
||||
|
||||
lastEntry.setTarget(ColorUtil.prependColorTag(target, color));
|
||||
|
||||
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package net.runelite.client.plugins.pkvision;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.util.MiscUtils;
|
||||
|
||||
@Singleton
|
||||
public class PKVisionService
|
||||
{
|
||||
private final Client client;
|
||||
private final PKVisionConfig config;
|
||||
|
||||
@Inject
|
||||
private PKVisionService(Client client, PKVisionConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void forEachPlayer(final BiConsumer<Player, Color> consumer)
|
||||
{
|
||||
final Player localPlayer = client.getLocalPlayer();
|
||||
|
||||
for (Player player : client.getPlayers())
|
||||
{
|
||||
if (player == null || player.getName() == null)
|
||||
continue;
|
||||
|
||||
if (player == localPlayer)
|
||||
{
|
||||
if (config.highlightOwnPlayer())
|
||||
consumer.accept(player, config.getOwnPlayerColor());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config.highlightFriends() && (player.isFriend() || player.isClanMember()))
|
||||
{
|
||||
consumer.accept(player, config.getFriendColor());
|
||||
}
|
||||
else if (player != localPlayer && !player.isFriend() && !player.isClanMember())
|
||||
{
|
||||
int lvlDelta = player.getCombatLevel() - localPlayer.getCombatLevel();
|
||||
int wildyLvl = MiscUtils.getWildernessLevelFrom(client, player.getWorldLocation());
|
||||
|
||||
if (wildyLvl <= 0)
|
||||
continue;
|
||||
|
||||
if (Math.abs(lvlDelta) > wildyLvl)
|
||||
continue;
|
||||
|
||||
int R = MiscUtils.clamp((int)(((float)(lvlDelta + wildyLvl) / (float)(wildyLvl * 2)) * 255.f), 0, 255);
|
||||
int G = MiscUtils.clamp(255 - R, 0, 255);
|
||||
|
||||
consumer.accept(player, Color.getHSBColor(Color.RGBtoHSB(R, G, 0, null)[0], 1.f, 1.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.runelite.client.plugins.pkvision;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class PKVisionTileOverlay extends Overlay
|
||||
{
|
||||
private final PKVisionService pkVisionService;
|
||||
private final PKVisionConfig config;
|
||||
|
||||
@Inject
|
||||
private PKVisionTileOverlay(PKVisionConfig config, PKVisionService pkVisionService)
|
||||
{
|
||||
this.config = config;
|
||||
this.pkVisionService = pkVisionService;
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!config.drawTiles())
|
||||
return null;
|
||||
|
||||
pkVisionService.forEachPlayer((player, color) ->
|
||||
{
|
||||
final Polygon poly = player.getCanvasTilePoly();
|
||||
|
||||
if (poly != null)
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package net.runelite.client.plugins.plankmakehelper;
|
||||
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.widgets.WidgetItem;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
|
||||
public class PlankMakeOverlay extends Overlay {
|
||||
|
||||
private final PlankMakePlugin plugin;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public PlankMakeOverlay(final PlankMakePlugin plugin, final Client client) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
|
||||
setPosition(OverlayPosition.DETACHED);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (hasPlankableItems()) {
|
||||
renderInventory(graphics);
|
||||
renderPlankMakeSpell(graphics);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderInventory(Graphics2D graphics) {
|
||||
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
|
||||
|
||||
int firstItemSeenIndex = -1;
|
||||
|
||||
if (inventory != null) {
|
||||
for (WidgetItem item : inventory.getWidgetItems()) {
|
||||
if (PlankMakePlugin.isLogAndPlankable(item.getId())) {
|
||||
if (firstItemSeenIndex == -1) {
|
||||
firstItemSeenIndex = item.getIndex();
|
||||
}
|
||||
if (!inventory.isHidden()) {
|
||||
if (item.getIndex() != firstItemSeenIndex) {
|
||||
OverlayUtil.renderPolygon(graphics, RectangleToPolygon(item.getCanvasBounds()), Color.BLUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firstItemSeenIndex != -1) {
|
||||
OverlayUtil.renderPolygon(graphics, RectangleToPolygon(inventory.getWidgetItem(firstItemSeenIndex).getCanvasBounds()), Color.CYAN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderPlankMakeSpell(Graphics2D graphics) {
|
||||
Widget plankMakeSpell = client.getWidget(218,128);
|
||||
if (plankMakeSpell != null && (plankMakeSpell.getCanvasLocation().getX() != 29 & plankMakeSpell.getCanvasLocation().getY() != 32)) {
|
||||
OverlayUtil.renderPolygon(graphics, RectangleToPolygon(plankMakeSpell.getBounds()), Color.CYAN);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasPlankableItems() {
|
||||
ItemContainer invo = client.getItemContainer(InventoryID.INVENTORY);
|
||||
if (invo != null) {
|
||||
if (invo.getItems().length > 0) {
|
||||
for (Item item : invo.getItems()) {
|
||||
if (PlankMakePlugin.isLogAndPlankable(item.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Polygon RectangleToPolygon(Rectangle rect) {
|
||||
int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x};
|
||||
int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height};
|
||||
return new Polygon(xpoints, ypoints, 4);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package net.runelite.client.plugins.plankmakehelper;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Plank Make Helper",
|
||||
description = "Highlights planks and plank make spell",
|
||||
tags = {"overlay", "plankmaking", "lunar", "money", "moneymaking", "gp"}
|
||||
)
|
||||
|
||||
public class PlankMakePlugin extends Plugin {
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private PlankMakeOverlay overlay;
|
||||
|
||||
@Override
|
||||
protected void startUp() {
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() {
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
|
||||
static boolean isLogAndPlankable(int itemID) {
|
||||
switch (itemID) {
|
||||
case 6332: //mahogany
|
||||
case 1521: //oak
|
||||
case 6333: //teak
|
||||
case 1511: //plain
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.prayagainstplayer;
|
||||
|
||||
import net.runelite.api.Player;
|
||||
|
||||
/**
|
||||
* Contains a player object
|
||||
* When they attacked me
|
||||
* And (in milliseconds) when to expire the overlay around them
|
||||
*/
|
||||
public class PlayerContainer {
|
||||
|
||||
private Player player;
|
||||
private long whenTheyAttackedMe;
|
||||
private int millisToExpireHighlight;
|
||||
|
||||
public PlayerContainer(Player player, long whenTheyAttackedMe, int millisToExpireHighlight) {
|
||||
this.player = player;
|
||||
this.whenTheyAttackedMe = whenTheyAttackedMe;
|
||||
this.millisToExpireHighlight = millisToExpireHighlight;
|
||||
}
|
||||
|
||||
|
||||
//getters
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
public long getWhenTheyAttackedMe() {
|
||||
return whenTheyAttackedMe;
|
||||
}
|
||||
public int getMillisToExpireHighlight() { return millisToExpireHighlight; };
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.prayagainstplayer;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@ConfigGroup("prayagainstplayer")
|
||||
public interface PrayAgainstPlayerConfig extends Config {
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "attackerPlayerColor",
|
||||
name = "Attacker color",
|
||||
description = "This is the color that will be used to highlight attackers."
|
||||
)
|
||||
default Color attackerPlayerColor() { return new Color(0xFF0006); }
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "potentialPlayerColor",
|
||||
name = "Potential Attacker color",
|
||||
description = "This is the color that will be used to highlight potential attackers."
|
||||
)
|
||||
default Color potentialPlayerColor() { return new Color(0xFFFF00); }
|
||||
|
||||
////
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "attackerTargetTimeout",
|
||||
name = "Attacker Timeout",
|
||||
description = "Seconds until attacker is no longer highlighted."
|
||||
)
|
||||
default int attackerTargetTimeout() { return 10; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "potentialTargetTimeout",
|
||||
name = "Potential Attacker Timeout",
|
||||
description = "Seconds until potential attacker is no longer highlighted."
|
||||
)
|
||||
default int potentialTargetTimeout() { return 10; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "newSpawnTimeout",
|
||||
name = "New Player Timeout",
|
||||
description = "Seconds until logged in/spawned player is no longer highlighted."
|
||||
)
|
||||
default int newSpawnTimeout() { return 5; }
|
||||
////
|
||||
|
||||
////
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "ignoreFriends",
|
||||
name = "Ignore Friends",
|
||||
description = "This lets you decide whether you want friends to be highlighted by this plugin."
|
||||
)
|
||||
default boolean ignoreFriends() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "ignoreClanMates",
|
||||
name = "Ignore Clan Mates",
|
||||
description = "This lets you decide whether you want clan mates to be highlighted by this plugin."
|
||||
)
|
||||
default boolean ignoreClanMates() { return true; }
|
||||
////
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "markNewPlayer",
|
||||
name = "Mark new player as potential attacker",
|
||||
description = "Marks someone that logged in or teleported as a potential attacker for your safety\nDO NOT RUN THIS IN WORLD 1-2 GRAND EXCHANGE!"
|
||||
)
|
||||
default boolean markNewPlayer() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "drawTargetPrayAgainst",
|
||||
name = "Draw what to pray on attacker",
|
||||
description = "Tells you what to pray from what weapon the attacker is holding"
|
||||
)
|
||||
default boolean drawTargetPrayAgainst() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "drawPotentialTargetPrayAgainst",
|
||||
name = "Draw what to pray on potential attacker",
|
||||
description = "Tells you what to pray from what weapon the potential attacker is holding"
|
||||
)
|
||||
default boolean drawPotentialTargetPrayAgainst() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "drawTargetPrayAgainstPrayerTab",
|
||||
name = "Draw what to pray from prayer tab",
|
||||
description = "Tells you what to pray from what weapon the attacker is holding from the prayer tab"
|
||||
)
|
||||
default boolean drawTargetPrayAgainstPrayerTab() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "drawTargetsName",
|
||||
name = "Draw name on attacker",
|
||||
description = "Configures whether or not the attacker\'s name should be shown"
|
||||
)
|
||||
default boolean drawTargetsName() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "drawPotentialTargetsName",
|
||||
name = "Draw name on potential attacker",
|
||||
description = "Configures whether or not the potential attacker\'s name should be shown"
|
||||
)
|
||||
default boolean drawPotentialTargetsName() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "drawTargetHighlight",
|
||||
name = "Draw highlight around attacker",
|
||||
description = "Configures whether or not the attacker should be highlighted"
|
||||
)
|
||||
default boolean drawTargetHighlight() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "drawPotentialTargetHighlight",
|
||||
name = "Draw highlight around potential attacker",
|
||||
description = "Configures whether or not the potential attacker should be highlighted"
|
||||
)
|
||||
default boolean drawPotentialTargetHighlight() { return true; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 15,
|
||||
keyName = "drawTargetTile",
|
||||
name = "Draw tile under attacker",
|
||||
description = "Configures whether or not the attacker\'s tile be highlighted"
|
||||
)
|
||||
default boolean drawTargetTile() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 16,
|
||||
keyName = "drawPotentialTargetTile",
|
||||
name = "Draw tile under potential attacker",
|
||||
description = "Configures whether or not the potential attacker\'s tile be highlighted"
|
||||
)
|
||||
default boolean drawPotentialTargetTile() { return false; }
|
||||
|
||||
@ConfigItem(
|
||||
position = 17,
|
||||
keyName = "drawUnknownWeapons",
|
||||
name = "Draw unknown weapons",
|
||||
description = "Configures whether or not the unknown weapons should be shown when a player equips one"
|
||||
)
|
||||
default boolean drawUnknownWeapons() { return false; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.prayagainstplayer;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.kit.KitType;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.api.Point;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ConcurrentModificationException;
|
||||
|
||||
class PrayAgainstPlayerOverlay extends Overlay {
|
||||
|
||||
private final PrayAgainstPlayerPlugin plugin;
|
||||
private final PrayAgainstPlayerConfig config;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private PrayAgainstPlayerOverlay(PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
renderPotentialPlayers(graphics);
|
||||
renderAttackingPlayers(graphics);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPotentialPlayers(Graphics2D graphics) {
|
||||
if (plugin.getPotentialPlayersAttackingMe() == null || !plugin.getPotentialPlayersAttackingMe().isEmpty()) {
|
||||
try {
|
||||
for (PlayerContainer container : plugin.getPotentialPlayersAttackingMe()) {
|
||||
if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) {
|
||||
plugin.removePlayerFromPotentialContainer(container);
|
||||
}
|
||||
if (config.drawPotentialTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.potentialPlayerColor());
|
||||
if (config.drawPotentialTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.potentialPlayerColor());
|
||||
if (config.drawPotentialTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.potentialPlayerColor());
|
||||
if (config.drawPotentialTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.potentialPlayerColor());
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderAttackingPlayers(Graphics2D graphics) {
|
||||
if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) {
|
||||
try {
|
||||
for (PlayerContainer container : plugin.getPlayersAttackingMe()) {
|
||||
if ((System.currentTimeMillis() > (container.getWhenTheyAttackedMe() + container.getMillisToExpireHighlight())) && (container.getPlayer().getInteracting() != client.getLocalPlayer())) {
|
||||
plugin.removePlayerFromAttackerContainer(container);
|
||||
}
|
||||
|
||||
if (config.drawTargetsName()) renderNameAboveHead(graphics, container.getPlayer(), config.attackerPlayerColor());
|
||||
if (config.drawTargetHighlight()) renderHighlightedPlayer(graphics, container.getPlayer(), config.attackerPlayerColor());
|
||||
if (config.drawTargetTile()) renderTileUnderPlayer(graphics, container.getPlayer(), config.attackerPlayerColor());
|
||||
if (config.drawTargetPrayAgainst()) renderPrayAgainstOnPlayer(graphics, container.getPlayer(), config.attackerPlayerColor());
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderNameAboveHead(Graphics2D graphics, Player player, Color color) {
|
||||
final String name = Text.sanitize(player.getName());
|
||||
final int offset = player.getLogicalHeight() + 40;
|
||||
Point textLocation = player.getCanvasTextLocation(graphics, name, offset);
|
||||
if (textLocation != null) {
|
||||
OverlayUtil.renderTextLocation(graphics, textLocation, name, color);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderHighlightedPlayer(Graphics2D graphics, Player player, Color color) {
|
||||
try {
|
||||
OverlayUtil.renderPolygon(graphics, player.getConvexHull(), color);
|
||||
} catch (NullPointerException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTileUnderPlayer(Graphics2D graphics, Player player, Color color) {
|
||||
Polygon poly = player.getCanvasTilePoly();
|
||||
OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
}
|
||||
|
||||
private void renderPrayAgainstOnPlayer(Graphics2D graphics, Player player, Color color) {
|
||||
final int offset = (player.getLogicalHeight() / 2) + 75;
|
||||
BufferedImage icon;
|
||||
|
||||
switch (WeaponType.checkWeaponOnPlayer(client, player)) {
|
||||
case WEAPON_MELEE:
|
||||
icon = plugin.getProtectionIcon(WeaponType.WEAPON_MELEE);
|
||||
break;
|
||||
case WEAPON_MAGIC:
|
||||
icon = plugin.getProtectionIcon(WeaponType.WEAPON_MAGIC);
|
||||
break;
|
||||
case WEAPON_RANGED:
|
||||
icon = plugin.getProtectionIcon(WeaponType.WEAPON_RANGED);
|
||||
break;
|
||||
default:
|
||||
icon = null;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
if (icon != null) {
|
||||
Point point = player.getCanvasImageLocation(icon, offset);
|
||||
OverlayUtil.renderImageLocation(graphics, point, icon);
|
||||
} else {
|
||||
if (config.drawUnknownWeapons()) {
|
||||
int itemId = player.getPlayerComposition().getEquipmentId(KitType.WEAPON);
|
||||
ItemComposition itemComposition = client.getItemDefinition(itemId);
|
||||
|
||||
final String str = itemComposition.getName().toUpperCase();
|
||||
Point point = player.getCanvasTextLocation(graphics, str, offset);
|
||||
OverlayUtil.renderTextLocation(graphics, point, str, color);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.prayagainstplayer;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.ui.overlay.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
import java.util.ConcurrentModificationException;
|
||||
|
||||
class PrayAgainstPlayerOverlayPrayerTab extends Overlay {
|
||||
|
||||
private final PrayAgainstPlayerPlugin plugin;
|
||||
private final PrayAgainstPlayerConfig config;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private PrayAgainstPlayerOverlayPrayerTab (PrayAgainstPlayerPlugin plugin, PrayAgainstPlayerConfig config, Client client) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
|
||||
setPosition(OverlayPosition.DETACHED);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics) {
|
||||
if (plugin.getPlayersAttackingMe() == null || !plugin.getPlayersAttackingMe().isEmpty()) {
|
||||
try {
|
||||
for (PlayerContainer container : plugin.getPlayersAttackingMe()) {
|
||||
if (plugin.getPlayersAttackingMe() != null && plugin.getPlayersAttackingMe().size() > 0) {
|
||||
//no reason to show you what prayers to pray in your prayer tab if multiple people are attacking you
|
||||
if ((plugin.getPlayersAttackingMe().size() == 1) && (config.drawTargetPrayAgainstPrayerTab())) {
|
||||
renderPrayerToClick(graphics, container.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderPrayerToClick(Graphics2D graphics, Player player) {
|
||||
Widget PROTECT_FROM_MAGIC = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC);
|
||||
Widget PROTECT_FROM_RANGED = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES);
|
||||
Widget PROTECT_FROM_MELEE = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MELEE);
|
||||
Color color = Color.RED;
|
||||
if (PROTECT_FROM_MELEE.isHidden()) return;
|
||||
switch (WeaponType.checkWeaponOnPlayer(client, player)) {
|
||||
case WEAPON_MAGIC:
|
||||
OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MAGIC.getBounds()), color);
|
||||
break;
|
||||
case WEAPON_MELEE:
|
||||
OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_MELEE.getBounds()), color);
|
||||
break;
|
||||
case WEAPON_RANGED:
|
||||
OverlayUtil.renderPolygon(graphics, rectangleToPolygon(PROTECT_FROM_RANGED.getBounds()), color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static Polygon rectangleToPolygon(Rectangle rect) {
|
||||
int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x};
|
||||
int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height};
|
||||
return new Polygon(xpoints, ypoints, 4);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.prayagainstplayer;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import net.runelite.api.*;
|
||||
import net.runelite.api.events.*;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "<font color=\"aqua\">!Pray Against Player</font>",
|
||||
description = "Use plugin in PvP situations for best results!!",
|
||||
tags = {"highlight", "pvp", "overlay", "players"}
|
||||
)
|
||||
|
||||
/**
|
||||
* I am fully aware that there is plenty of overhead and is a MESS!
|
||||
* If you'd like to contribute please do!
|
||||
*/
|
||||
public class PrayAgainstPlayerPlugin extends Plugin {
|
||||
|
||||
private static final int[] PROTECTION_ICONS = {
|
||||
SpriteID.PRAYER_PROTECT_FROM_MISSILES,
|
||||
SpriteID.PRAYER_PROTECT_FROM_MELEE,
|
||||
SpriteID.PRAYER_PROTECT_FROM_MAGIC
|
||||
};
|
||||
private static final Dimension PROTECTION_ICON_DIMENSION = new Dimension(33, 33);
|
||||
private static final Color PROTECTION_ICON_OUTLINE_COLOR = new Color(33, 33, 33);
|
||||
public final BufferedImage[] ProtectionIcons = new BufferedImage[PROTECTION_ICONS.length];
|
||||
|
||||
private ArrayList<PlayerContainer> potentialPlayersAttackingMe;
|
||||
private ArrayList<PlayerContainer> playersAttackingMe;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private PrayAgainstPlayerOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private PrayAgainstPlayerOverlayPrayerTab overlayPrayerTab;
|
||||
|
||||
@Inject
|
||||
private PrayAgainstPlayerConfig config;
|
||||
|
||||
@Provides
|
||||
PrayAgainstPlayerConfig provideConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(PrayAgainstPlayerConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged) {
|
||||
if (gameStateChanged.getGameState() == GameState.LOGGED_IN) {
|
||||
loadProtectionIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() {
|
||||
potentialPlayersAttackingMe = new ArrayList<>();
|
||||
playersAttackingMe = new ArrayList<>();
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(overlayPrayerTab);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception {
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(overlayPrayerTab);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
protected void onAnimationChanged(AnimationChanged animationChanged) {
|
||||
if ((animationChanged.getActor() instanceof Player) && (animationChanged.getActor().getInteracting() instanceof Player) && (animationChanged.getActor().getInteracting() == client.getLocalPlayer())) {
|
||||
Player sourcePlayer = (Player) animationChanged.getActor();
|
||||
|
||||
//is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list
|
||||
if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return;
|
||||
if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return;
|
||||
|
||||
if ((sourcePlayer.getAnimation() != -1) && (!isBlockAnimation(sourcePlayer.getAnimation()))) {
|
||||
//if attacker attacks again, reset his timer so overlay doesn't go away
|
||||
if (findPlayerInAttackerList(sourcePlayer) != null) {
|
||||
resetPlayerFromAttackerContainerTimer(findPlayerInAttackerList(sourcePlayer));
|
||||
}
|
||||
//if he attacks and he was in the potential attackers list, remove him
|
||||
if (!potentialPlayersAttackingMe.isEmpty() && potentialPlayersAttackingMe.contains(findPlayerInPotentialList(sourcePlayer))) {
|
||||
removePlayerFromPotentialContainer(findPlayerInPotentialList(sourcePlayer));
|
||||
}
|
||||
//if he's not in the attackers list, add him
|
||||
if (findPlayerInAttackerList(sourcePlayer) == null) {
|
||||
PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000));
|
||||
playersAttackingMe.add(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
protected void onInteractingChanged(InteractingChanged interactingChanged) {
|
||||
//if someone interacts with you, add them to the potential attackers list
|
||||
if ((interactingChanged.getSource() instanceof Player) && (interactingChanged.getTarget() instanceof Player)) {
|
||||
Player sourcePlayer = (Player) interactingChanged.getSource();
|
||||
Player targetPlayer = (Player) interactingChanged.getTarget();
|
||||
if ((targetPlayer == client.getLocalPlayer()) && (findPlayerInPotentialList(sourcePlayer) == null)) { //we're being interacted with
|
||||
|
||||
//is the client is a friend/clan and the config is set to ignore friends/clan dont add them to list
|
||||
if (client.isFriended(sourcePlayer.getName(), true) && config.ignoreFriends()) return;
|
||||
if (client.isClanMember(sourcePlayer.getName()) && config.ignoreClanMates()) return;
|
||||
|
||||
PlayerContainer container = new PlayerContainer(sourcePlayer, System.currentTimeMillis(), (config.potentialTargetTimeout() * 1000));
|
||||
potentialPlayersAttackingMe.add(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
protected void onPlayerDespawned(PlayerDespawned playerDespawned) {
|
||||
PlayerContainer container = findPlayerInAttackerList(playerDespawned.getPlayer());
|
||||
PlayerContainer container2 = findPlayerInPotentialList(playerDespawned.getPlayer());
|
||||
if (container != null) {
|
||||
playersAttackingMe.remove(container);
|
||||
}
|
||||
if (container2 != null) {
|
||||
potentialPlayersAttackingMe.remove(container2);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
protected void onPlayerSpawned(PlayerSpawned playerSpawned) {
|
||||
if (config.markNewPlayer()) {
|
||||
Player p = playerSpawned.getPlayer();
|
||||
|
||||
if (client.isFriended(p.getName(), true) && config.ignoreFriends()) return;
|
||||
if (client.isClanMember(p.getName()) && config.ignoreClanMates()) return;
|
||||
|
||||
PlayerContainer container = findPlayerInPotentialList(p);
|
||||
if (container == null) {
|
||||
container = new PlayerContainer(p, System.currentTimeMillis(), (config.newSpawnTimeout() * 1000));
|
||||
potentialPlayersAttackingMe.add(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerContainer findPlayerInAttackerList(Player player) {
|
||||
if (playersAttackingMe.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0 ; i < playersAttackingMe.size() ; i++) {
|
||||
PlayerContainer container = playersAttackingMe.get(i);
|
||||
if (container.getPlayer() == player) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerContainer findPlayerInPotentialList(Player player) {
|
||||
if (potentialPlayersAttackingMe.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0 ; i < potentialPlayersAttackingMe.size() ; i++) {
|
||||
PlayerContainer container = potentialPlayersAttackingMe.get(i);
|
||||
if (container.getPlayer() == player) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets player timer in case he attacks again, so his highlight doesn't go away so easily
|
||||
* @param container
|
||||
*/
|
||||
public void resetPlayerFromAttackerContainerTimer(PlayerContainer container) {
|
||||
removePlayerFromAttackerContainer(container);
|
||||
PlayerContainer newContainer = new PlayerContainer(container.getPlayer(), System.currentTimeMillis(), (config.attackerTargetTimeout() * 1000));
|
||||
playersAttackingMe.add(newContainer);
|
||||
}
|
||||
|
||||
|
||||
public void removePlayerFromPotentialContainer(PlayerContainer container) {
|
||||
if ((potentialPlayersAttackingMe != null) && (!potentialPlayersAttackingMe.isEmpty()) && (potentialPlayersAttackingMe.contains(container))) {
|
||||
potentialPlayersAttackingMe.remove(container);
|
||||
}
|
||||
}
|
||||
|
||||
public void removePlayerFromAttackerContainer(PlayerContainer container) {
|
||||
if ((playersAttackingMe != null) && (!playersAttackingMe.isEmpty()) && (playersAttackingMe.contains(container))) {
|
||||
playersAttackingMe.remove(container);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBlockAnimation(int anim) {
|
||||
switch (anim) {
|
||||
case AnimationID.BLOCK_DEFENDER:
|
||||
case AnimationID.BLOCK_NO_SHIELD:
|
||||
case AnimationID.BLOCK_SHIELD:
|
||||
case AnimationID.BLOCK_SWORD:
|
||||
case AnimationID.BLOCK_UNARMED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<PlayerContainer> getPotentialPlayersAttackingMe() { return potentialPlayersAttackingMe; }
|
||||
public ArrayList<PlayerContainer> getPlayersAttackingMe() { return playersAttackingMe; }
|
||||
|
||||
//All of the methods below are from the Zulrah plugin!!! Credits to it's respective owner
|
||||
private void loadProtectionIcons() {
|
||||
final IndexedSprite[] protectionIcons = {};
|
||||
final IndexedSprite[] newProtectionIcons = Arrays.copyOf(protectionIcons, PROTECTION_ICONS.length);
|
||||
int curPosition = 0;
|
||||
|
||||
for (int i = 0; i < PROTECTION_ICONS.length; i++, curPosition++)
|
||||
{
|
||||
final int resource = PROTECTION_ICONS[i];
|
||||
ProtectionIcons[i] = rgbaToIndexedBufferedImage(ProtectionIconFromSprite(spriteManager.getSprite(resource, 0)));
|
||||
newProtectionIcons[curPosition] = createIndexedSprite(client, ProtectionIcons[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static IndexedSprite createIndexedSprite(final Client client, final BufferedImage bufferedImage) {
|
||||
final IndexColorModel indexedCM = (IndexColorModel) bufferedImage.getColorModel();
|
||||
|
||||
final int width = bufferedImage.getWidth();
|
||||
final int height = bufferedImage.getHeight();
|
||||
final byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
|
||||
final int[] palette = new int[indexedCM.getMapSize()];
|
||||
indexedCM.getRGBs(palette);
|
||||
|
||||
final IndexedSprite newIndexedSprite = client.createIndexedSprite();
|
||||
newIndexedSprite.setPixels(pixels);
|
||||
newIndexedSprite.setPalette(palette);
|
||||
newIndexedSprite.setWidth(width);
|
||||
newIndexedSprite.setHeight(height);
|
||||
newIndexedSprite.setOriginalWidth(width);
|
||||
newIndexedSprite.setOriginalHeight(height);
|
||||
newIndexedSprite.setOffsetX(0);
|
||||
newIndexedSprite.setOffsetY(0);
|
||||
return newIndexedSprite;
|
||||
}
|
||||
|
||||
private static BufferedImage rgbaToIndexedBufferedImage(final BufferedImage sourceBufferedImage) {
|
||||
final BufferedImage indexedImage = new BufferedImage(
|
||||
sourceBufferedImage.getWidth(),
|
||||
sourceBufferedImage.getHeight(),
|
||||
BufferedImage.TYPE_BYTE_INDEXED);
|
||||
|
||||
final ColorModel cm = indexedImage.getColorModel();
|
||||
final IndexColorModel icm = (IndexColorModel) cm;
|
||||
|
||||
final int size = icm.getMapSize();
|
||||
final byte[] reds = new byte[size];
|
||||
final byte[] greens = new byte[size];
|
||||
final byte[] blues = new byte[size];
|
||||
icm.getReds(reds);
|
||||
icm.getGreens(greens);
|
||||
icm.getBlues(blues);
|
||||
|
||||
final WritableRaster raster = indexedImage.getRaster();
|
||||
final int pixel = raster.getSample(0, 0, 0);
|
||||
final IndexColorModel resultIcm = new IndexColorModel(8, size, reds, greens, blues, pixel);
|
||||
final BufferedImage resultIndexedImage = new BufferedImage(resultIcm, raster, sourceBufferedImage.isAlphaPremultiplied(), null);
|
||||
resultIndexedImage.getGraphics().drawImage(sourceBufferedImage, 0, 0, null);
|
||||
return resultIndexedImage;
|
||||
}
|
||||
|
||||
private static BufferedImage ProtectionIconFromSprite(final BufferedImage freezeSprite) {
|
||||
final BufferedImage freezeCanvas = ImageUtil.resizeCanvas(freezeSprite, PROTECTION_ICON_DIMENSION.width, PROTECTION_ICON_DIMENSION.height);
|
||||
return ImageUtil.outlineImage(freezeCanvas, PROTECTION_ICON_OUTLINE_COLOR);
|
||||
}
|
||||
|
||||
BufferedImage getProtectionIcon(WeaponType weaponType) {
|
||||
switch (weaponType) {
|
||||
case WEAPON_RANGED:
|
||||
return ProtectionIcons[0];
|
||||
case WEAPON_MELEE:
|
||||
return ProtectionIcons[1];
|
||||
case WEAPON_MAGIC:
|
||||
return ProtectionIcons[2];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.prayagainstplayer;
|
||||
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.kit.KitType;
|
||||
|
||||
enum WeaponType {
|
||||
|
||||
WEAPON_MELEE,
|
||||
WEAPON_RANGED,
|
||||
WEAPON_MAGIC,
|
||||
WEAPON_UNKNOWN;
|
||||
|
||||
/**
|
||||
* im fully aware this could of been done better!!!
|
||||
* @param client
|
||||
* @param attacker
|
||||
* @return
|
||||
*/
|
||||
public static WeaponType checkWeaponOnPlayer (Client client, Player attacker) {
|
||||
int itemId = attacker.getPlayerComposition().getEquipmentId(KitType.WEAPON);
|
||||
ItemComposition itemComposition = client.getItemDefinition(itemId);
|
||||
String weaponNameGivenLowerCase = itemComposition.getName().toLowerCase();
|
||||
|
||||
if (itemId == -1) return WEAPON_MELEE;
|
||||
if (weaponNameGivenLowerCase == null || weaponNameGivenLowerCase.toLowerCase().contains("null")) return WEAPON_MELEE;
|
||||
|
||||
for (String meleeWeaponName : meleeWeaponNames) {
|
||||
if (weaponNameGivenLowerCase.contains(meleeWeaponName) && !weaponNameGivenLowerCase.contains("thrownaxe")) {
|
||||
return WEAPON_MELEE;
|
||||
}
|
||||
}
|
||||
|
||||
for (String rangedWeaponName : rangedWeaponNames) {
|
||||
if (weaponNameGivenLowerCase.contains(rangedWeaponName)) {
|
||||
return WEAPON_RANGED;
|
||||
}
|
||||
}
|
||||
|
||||
for (String magicWeaponName : magicWeaponNames) {
|
||||
if (weaponNameGivenLowerCase.contains(magicWeaponName)) {
|
||||
return WEAPON_MAGIC;
|
||||
}
|
||||
}
|
||||
|
||||
return WEAPON_UNKNOWN;
|
||||
|
||||
}
|
||||
|
||||
private static String[] meleeWeaponNames = {
|
||||
"sword",
|
||||
"scimitar",
|
||||
"dagger",
|
||||
"spear",
|
||||
"mace",
|
||||
"axe",
|
||||
"whip",
|
||||
"tentacle",
|
||||
"-ket-",
|
||||
"-xil-",
|
||||
"warhammer",
|
||||
"halberd",
|
||||
"claws",
|
||||
"hasta",
|
||||
"scythe",
|
||||
"maul",
|
||||
"anchor",
|
||||
"sabre",
|
||||
"excalibur",
|
||||
"machete",
|
||||
"dragon hunter lance",
|
||||
"event rpg",
|
||||
"silverlight",
|
||||
"darklight",
|
||||
"arclight",
|
||||
"flail",
|
||||
"granite hammer",
|
||||
"rapier",
|
||||
"bulwark"
|
||||
};
|
||||
|
||||
private static String[] rangedWeaponNames = {
|
||||
"bow",
|
||||
"blowpipe",
|
||||
"xil-ul",
|
||||
"knife",
|
||||
"dart",
|
||||
"thrownaxe",
|
||||
"chinchompa",
|
||||
"ballista"
|
||||
};
|
||||
|
||||
private static String[] magicWeaponNames = {
|
||||
"staff",
|
||||
"trident",
|
||||
"wand",
|
||||
"dawnbringer"
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.139.
|
||||
*/
|
||||
package net.runelite.client.plugins.profiles;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class ProfilePanel
|
||||
extends JPanel {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProfilePanel.class);
|
||||
private static final ImageIcon DELETE_ICON;
|
||||
private static final ImageIcon DELETE_HOVER_ICON;
|
||||
private final String loginText;
|
||||
private String password = null;
|
||||
|
||||
ProfilePanel(final Client client, final String data, final ProfilesConfig config) {
|
||||
String[] parts = data.split(":");
|
||||
this.loginText = parts[1];
|
||||
if (parts.length == 3) {
|
||||
this.password = parts[2];
|
||||
}
|
||||
final ProfilePanel panel = this;
|
||||
this.setLayout(new BorderLayout());
|
||||
this.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
JPanel labelWrapper = new JPanel(new BorderLayout());
|
||||
labelWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
labelWrapper.setBorder(new CompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR), BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR)));
|
||||
JPanel panelActions = new JPanel(new BorderLayout(3, 0));
|
||||
panelActions.setBorder(new EmptyBorder(0, 0, 0, 8));
|
||||
panelActions.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
final JLabel delete = new JLabel();
|
||||
delete.setIcon(DELETE_ICON);
|
||||
delete.setToolTipText("Delete account profile");
|
||||
delete.addMouseListener(new MouseAdapter(){
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
panel.getParent().remove(panel);
|
||||
ProfilesPanel.removeProfile(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
delete.setIcon(DELETE_HOVER_ICON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
delete.setIcon(DELETE_ICON);
|
||||
}
|
||||
});
|
||||
panelActions.add((Component)delete, "East");
|
||||
JLabel label = new JLabel();
|
||||
label.setText(parts[0]);
|
||||
label.setBorder(null);
|
||||
label.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
label.setPreferredSize(new Dimension(0, 24));
|
||||
label.setForeground(Color.WHITE);
|
||||
label.setBorder(new EmptyBorder(0, 8, 0, 0));
|
||||
labelWrapper.add((Component)label, "Center");
|
||||
labelWrapper.add((Component)panelActions, "East");
|
||||
label.addMouseListener(new MouseAdapter(){
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) {
|
||||
client.setUsername(ProfilePanel.this.loginText);
|
||||
if (config.rememberPassword() && ProfilePanel.this.password != null) {
|
||||
client.setPassword(ProfilePanel.this.password);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
JPanel bottomContainer = new JPanel(new BorderLayout());
|
||||
bottomContainer.setBorder(new EmptyBorder(8, 0, 8, 0));
|
||||
bottomContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
bottomContainer.addMouseListener(new MouseAdapter(){
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) {
|
||||
client.setUsername(ProfilePanel.this.loginText);
|
||||
}
|
||||
}
|
||||
});
|
||||
JLabel login = new JLabel();
|
||||
login.setText(config.isStreamerMode() ? "Hidden email" : this.loginText);
|
||||
login.setBorder(null);
|
||||
login.setPreferredSize(new Dimension(0, 24));
|
||||
login.setForeground(Color.WHITE);
|
||||
login.setBorder(new EmptyBorder(0, 8, 0, 0));
|
||||
bottomContainer.add((Component)login, "Center");
|
||||
this.add((Component)labelWrapper, "North");
|
||||
this.add((Component)bottomContainer, "Center");
|
||||
}
|
||||
|
||||
static {
|
||||
BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ProfilesPlugin.class, "net/runelite/client/plugins/profiles/delete_icon.png");
|
||||
DELETE_ICON = new ImageIcon(deleteImg);
|
||||
DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.139.
|
||||
*/
|
||||
package net.runelite.client.plugins.profiles;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup(value="profiles")
|
||||
public interface ProfilesConfig
|
||||
extends Config {
|
||||
@ConfigItem(keyName="profilesData", name="", description="", hidden=true)
|
||||
default public String profilesData() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ConfigItem(keyName="profilesData", name="", description="")
|
||||
public void profilesData(String var1);
|
||||
|
||||
@ConfigItem(keyName="rememberPassword", name="Remember Password", description="Remembers passwords for accounts")
|
||||
default public boolean rememberPassword() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(keyName="streamerMode", name="Hide email addresses", description="Hides your account emails")
|
||||
default public boolean isStreamerMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(keyName="switchPanel", name="Auto-open Panel", description="Automatically switch to the account switcher panel on the login screen")
|
||||
default public boolean switchPanel() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.139.
|
||||
*/
|
||||
package net.runelite.client.plugins.profiles;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.plugins.profiles.ProfilePanel;
|
||||
import net.runelite.client.plugins.profiles.ProfilesConfig;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class ProfilesPanel
|
||||
extends PluginPanel {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProfilesPanel.class);
|
||||
private static final String ACCOUNT_USERNAME = "Account Username";
|
||||
private static final String ACCOUNT_LABEL = "Account Label";
|
||||
private static final String PASSWORD_LABEL = "Account Password";
|
||||
private static final Dimension PREFERRED_SIZE = new Dimension(205, 30);
|
||||
private static final Dimension MINIMUM_SIZE = new Dimension(0, 30);
|
||||
private final Client client;
|
||||
private static ProfilesConfig profilesConfig;
|
||||
private final JTextField txtAccountLabel = new JTextField("Account Label");
|
||||
private final JPasswordField txtAccountLogin = new JPasswordField("Account Username");
|
||||
private final JPasswordField txtPasswordLogin = new JPasswordField("Account Password");
|
||||
private final JPanel profilesPanel = new JPanel();
|
||||
private GridBagConstraints c;
|
||||
|
||||
@Inject
|
||||
public ProfilesPanel(Client client, final ProfilesConfig config) {
|
||||
this.client = client;
|
||||
profilesConfig = config;
|
||||
this.setBorder(new EmptyBorder(18, 10, 0, 10));
|
||||
this.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||
this.setLayout(new GridBagLayout());
|
||||
this.c = new GridBagConstraints();
|
||||
this.c.fill = 2;
|
||||
this.c.gridx = 0;
|
||||
this.c.gridy = 0;
|
||||
this.c.weightx = 1.0;
|
||||
this.c.weighty = 0.0;
|
||||
this.c.insets = new Insets(0, 0, 4, 0);
|
||||
this.txtAccountLabel.setPreferredSize(PREFERRED_SIZE);
|
||||
this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
this.txtAccountLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
this.txtAccountLabel.setMinimumSize(MINIMUM_SIZE);
|
||||
this.txtAccountLabel.addFocusListener(new FocusListener(){
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (ProfilesPanel.this.txtAccountLabel.getText().equals(ProfilesPanel.ACCOUNT_LABEL)) {
|
||||
ProfilesPanel.this.txtAccountLabel.setText("");
|
||||
ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (ProfilesPanel.this.txtAccountLabel.getText().isEmpty()) {
|
||||
ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
ProfilesPanel.this.txtAccountLabel.setText(ProfilesPanel.ACCOUNT_LABEL);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.add((Component)this.txtAccountLabel, this.c);
|
||||
++this.c.gridy;
|
||||
this.txtAccountLogin.setEchoChar('\u0000');
|
||||
this.txtAccountLogin.setPreferredSize(PREFERRED_SIZE);
|
||||
this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
this.txtAccountLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
this.txtAccountLogin.setMinimumSize(MINIMUM_SIZE);
|
||||
this.txtAccountLogin.addFocusListener(new FocusListener(){
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (ProfilesPanel.ACCOUNT_USERNAME.equals(String.valueOf(ProfilesPanel.this.txtAccountLogin.getPassword()))) {
|
||||
ProfilesPanel.this.txtAccountLogin.setText("");
|
||||
if (config.isStreamerMode()) {
|
||||
ProfilesPanel.this.txtAccountLogin.setEchoChar('*');
|
||||
}
|
||||
ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (ProfilesPanel.this.txtAccountLogin.getPassword().length == 0) {
|
||||
ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
ProfilesPanel.this.txtAccountLogin.setText(ProfilesPanel.ACCOUNT_USERNAME);
|
||||
ProfilesPanel.this.txtAccountLogin.setEchoChar('\u0000');
|
||||
}
|
||||
}
|
||||
});
|
||||
this.add((Component)this.txtAccountLogin, this.c);
|
||||
++this.c.gridy;
|
||||
this.txtPasswordLogin.setEchoChar('\u0000');
|
||||
this.txtPasswordLogin.setPreferredSize(PREFERRED_SIZE);
|
||||
this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
this.txtPasswordLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
this.txtPasswordLogin.setToolTipText("Account password");
|
||||
this.txtPasswordLogin.setMinimumSize(MINIMUM_SIZE);
|
||||
this.txtPasswordLogin.addFocusListener(new FocusListener(){
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (ProfilesPanel.PASSWORD_LABEL.equals(String.valueOf(ProfilesPanel.this.txtPasswordLogin.getPassword()))) {
|
||||
ProfilesPanel.this.txtPasswordLogin.setText("");
|
||||
ProfilesPanel.this.txtPasswordLogin.setEchoChar('*');
|
||||
ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (ProfilesPanel.this.txtPasswordLogin.getPassword().length == 0) {
|
||||
ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
ProfilesPanel.this.txtPasswordLogin.setText(ProfilesPanel.PASSWORD_LABEL);
|
||||
ProfilesPanel.this.txtPasswordLogin.setEchoChar('\u0000');
|
||||
}
|
||||
}
|
||||
});
|
||||
if (config.rememberPassword()) {
|
||||
this.add((Component)this.txtPasswordLogin, this.c);
|
||||
++this.c.gridy;
|
||||
}
|
||||
this.c.insets = new Insets(0, 0, 15, 0);
|
||||
final JButton btnAddAccount = new JButton("Add Account");
|
||||
btnAddAccount.setPreferredSize(PREFERRED_SIZE);
|
||||
btnAddAccount.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
btnAddAccount.setMinimumSize(MINIMUM_SIZE);
|
||||
btnAddAccount.addActionListener(e -> {
|
||||
String labelText = String.valueOf(this.txtAccountLabel.getText());
|
||||
String loginText = String.valueOf(this.txtAccountLogin.getPassword());
|
||||
String passwordText = String.valueOf(this.txtPasswordLogin.getPassword());
|
||||
if (labelText.equals(ACCOUNT_LABEL) || loginText.equals(ACCOUNT_USERNAME)) {
|
||||
return;
|
||||
}
|
||||
String data = config.rememberPassword() && this.txtPasswordLogin.getPassword() != null ? labelText + ":" + loginText + ":" + passwordText : labelText + ":" + loginText;
|
||||
log.info(data);
|
||||
this.addAccount(data);
|
||||
ProfilesPanel.addProfile(data);
|
||||
this.txtAccountLabel.setText(ACCOUNT_LABEL);
|
||||
this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
this.txtAccountLogin.setText(ACCOUNT_USERNAME);
|
||||
this.txtAccountLogin.setEchoChar('\u0000');
|
||||
this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
this.txtPasswordLogin.setText(PASSWORD_LABEL);
|
||||
this.txtPasswordLogin.setEchoChar('\u0000');
|
||||
this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR);
|
||||
});
|
||||
this.txtAccountLogin.addKeyListener(new KeyAdapter(){
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == 10) {
|
||||
btnAddAccount.doClick();
|
||||
btnAddAccount.requestFocus();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.txtAccountLogin.addMouseListener(new MouseListener(){
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
this.add((Component)btnAddAccount, this.c);
|
||||
++this.c.gridy;
|
||||
this.profilesPanel.setLayout(new GridBagLayout());
|
||||
this.add((Component)this.profilesPanel, this.c);
|
||||
this.c.gridy = 0;
|
||||
this.c.insets = new Insets(0, 0, 5, 0);
|
||||
this.addAccounts(config.profilesData());
|
||||
}
|
||||
|
||||
void redrawProfiles() {
|
||||
this.profilesPanel.removeAll();
|
||||
this.c.gridy = 0;
|
||||
this.addAccounts(profilesConfig.profilesData());
|
||||
}
|
||||
|
||||
private void addAccount(String data) {
|
||||
ProfilePanel profile = new ProfilePanel(this.client, data, profilesConfig);
|
||||
++this.c.gridy;
|
||||
this.profilesPanel.add((Component)profile, this.c);
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
void addAccounts(String data) {
|
||||
if (!(data = data.trim()).contains(":")) {
|
||||
return;
|
||||
}
|
||||
Arrays.stream(data.split("\\n")).forEach(this::addAccount);
|
||||
}
|
||||
|
||||
static void addProfile(String data) {
|
||||
profilesConfig.profilesData(profilesConfig.profilesData() + data + "\n");
|
||||
}
|
||||
|
||||
static void removeProfile(String data) {
|
||||
profilesConfig.profilesData(profilesConfig.profilesData().replaceAll(data + "\\n", ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.139.
|
||||
*/
|
||||
package net.runelite.client.plugins.profiles;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.logging.Logger;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.ClientToolbar;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@PluginDescriptor(name="Account Switcher", description="Allow for a allows you to easily switch between multiple OSRS Accounts", tags={"profile", "account", "login", "log in"})
|
||||
public class ProfilesPlugin
|
||||
extends Plugin {
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
@Inject
|
||||
private Client client;
|
||||
@Inject
|
||||
private ProfilesConfig config;
|
||||
private ProfilesPanel panel;
|
||||
private NavigationButton navButton;
|
||||
String text = "Hello World";
|
||||
private static String key = "Bar12345Bar12345";
|
||||
private static Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
|
||||
|
||||
@Provides
|
||||
ProfilesConfig getConfig(ConfigManager configManager) {
|
||||
return configManager.getConfig(ProfilesConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception {
|
||||
this.panel = this.injector.getInstance(ProfilesPanel.class);
|
||||
BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "/net/runelite/client/plugins/profiles/profiles_icon.png");
|
||||
this.navButton = NavigationButton.builder().tooltip("Profiles").icon(icon).priority(8).panel(this.panel).build();
|
||||
this.clientToolbar.addNavigation(this.navButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() {
|
||||
this.clientToolbar.removeNavigation(this.navButton);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onConfigChanged(ConfigChanged event) throws Exception {
|
||||
if (event.getGroup().equals("profiles") && event.getKey().equals("rememberPassword")) {
|
||||
this.panel = this.injector.getInstance(ProfilesPanel.class);
|
||||
this.shutDown();
|
||||
this.startUp();
|
||||
}
|
||||
}
|
||||
|
||||
public static String decryptText(String text) {
|
||||
byte[] bb = new byte[text.length()];
|
||||
for (int i = 0; i < text.length(); ++i) {
|
||||
bb[i] = (byte)text.charAt(i);
|
||||
}
|
||||
Cipher cipher = null;
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES");
|
||||
}
|
||||
catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
cipher.init(2, aesKey);
|
||||
}
|
||||
catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Logger.getLogger("EncryptionLogger").info("Decrypted " + text + " to " + new String(cipher.doFinal(bb)));
|
||||
return new String(cipher.doFinal(bb));
|
||||
}
|
||||
catch (BadPaddingException | IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String encryptText(String text) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(1, aesKey);
|
||||
byte[] encrypted = cipher.doFinal(text.getBytes());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : encrypted) {
|
||||
sb.append((char)b);
|
||||
}
|
||||
Logger.getLogger("EncryptionLogger").info("Encrypted " + text + " to " + sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user