Overhaul of the Tick Timers plugin. (#757)
* Overhaul of the Tick Timers plugin. Added new OverlayUtils that are commonly found. Added Attack Speed to npcManager. (Thanks wiki <3) Updated Prayer API to contain widget info as well. * Remove unnecessary code. * Add Dag King animations. * Update NPCManager to use int instead of Integer. * Add Waterbith Region check for DKs * Make valid region check happen only during game state change event. * Renaming and other misc. * Renaming and other misc.
This commit is contained in:
@@ -157,7 +157,7 @@ public final class AnimationID
|
||||
public static final int HOME_MAKE_TABLET = 4067;
|
||||
public static final int THIEVING_STALL = 832;
|
||||
public static final int PICKPOCKET_SUCCESS = 881;
|
||||
|
||||
|
||||
//block animations for players and perhaps npcs as well?
|
||||
public static final int BLOCK_DEFENDER = 4177;
|
||||
public static final int BLOCK_NO_SHIELD = 420;
|
||||
@@ -252,7 +252,7 @@ public final class AnimationID
|
||||
public static final int HYDRA_RANGED_4 = 8255;
|
||||
public static final int HYDRA_4_1 = 8257;
|
||||
public static final int HYDRA_4_2 = 8258;
|
||||
|
||||
|
||||
// INFERNO animations
|
||||
public static final int JAL_NIB = 7574;
|
||||
public static final int JAL_MEJRAH = 7578;
|
||||
@@ -278,4 +278,31 @@ public final class AnimationID
|
||||
public static final int GENERAL_AUTO1 = 7018;
|
||||
public static final int GENERAL_AUTO2 = 7020;
|
||||
public static final int GENERAL_AUTO3 = 7021;
|
||||
}
|
||||
|
||||
//Zammy-poo
|
||||
public static final int ZAMMY_GENERIC_AUTO = 64;
|
||||
public static final int KRIL_AUTO = 6948;
|
||||
public static final int KRIL_SPEC = 6950;
|
||||
public static final int ZAKL_AUTO = 7077;
|
||||
public static final int BALFRUG_AUTO = 4630;
|
||||
|
||||
//Sara-Poo
|
||||
public static final int ZILYANA_MELEE_AUTO = 6964;
|
||||
public static final int ZILYANA_AUTO = 6967;
|
||||
public static final int ZILYANA_SPEC = 6970;
|
||||
public static final int STARLIGHT_AUTO = 6376;
|
||||
public static final int BREE_AUTO = 7026;
|
||||
public static final int GROWLER_AUTO = 7037;
|
||||
|
||||
//Arma-Poo
|
||||
public static final int KREE_RANGED = 6978;
|
||||
public static final int SKREE_AUTO = 6955;
|
||||
public static final int GEERIN_AUTO = 6956;
|
||||
public static final int GEERIN_FLINCH = 6958;
|
||||
public static final int KILISA_AUTO = 6957;
|
||||
|
||||
//Dag Kings
|
||||
public static final int DAG_REX = 2853;
|
||||
public static final int DAG_PRIME = 2854;
|
||||
public static final int DAG_SUPREME = 2855;
|
||||
}
|
||||
@@ -24,155 +24,147 @@
|
||||
*/
|
||||
package net.runelite.api;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
|
||||
/**
|
||||
* An enumeration of different prayer spells.
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum Prayer
|
||||
{
|
||||
/**
|
||||
* Thick Skin (Level 1, Defence).
|
||||
*/
|
||||
THICK_SKIN(Varbits.PRAYER_THICK_SKIN, 5.0),
|
||||
THICK_SKIN(Varbits.PRAYER_THICK_SKIN, 5.0, WidgetInfo.PRAYER_THICK_SKIN),
|
||||
/**
|
||||
* Burst of Strength (Level 4, Strength).
|
||||
*/
|
||||
BURST_OF_STRENGTH(Varbits.PRAYER_BURST_OF_STRENGTH, 5.0),
|
||||
BURST_OF_STRENGTH(Varbits.PRAYER_BURST_OF_STRENGTH, 5.0, WidgetInfo.PRAYER_BURST_OF_STRENGTH),
|
||||
/**
|
||||
* Clarity of Thought (Level 7, Attack).
|
||||
*/
|
||||
CLARITY_OF_THOUGHT(Varbits.PRAYER_CLARITY_OF_THOUGHT, 5.0),
|
||||
CLARITY_OF_THOUGHT(Varbits.PRAYER_CLARITY_OF_THOUGHT, 5.0, WidgetInfo.PRAYER_CLARITY_OF_THOUGHT),
|
||||
/**
|
||||
* Sharp Eye (Level 8, Ranging).
|
||||
*/
|
||||
SHARP_EYE(Varbits.PRAYER_SHARP_EYE, 5.0),
|
||||
SHARP_EYE(Varbits.PRAYER_SHARP_EYE, 5.0, WidgetInfo.PRAYER_SHARP_EYE),
|
||||
/**
|
||||
* Mystic Will (Level 9, Magic).
|
||||
*/
|
||||
MYSTIC_WILL(Varbits.PRAYER_MYSTIC_WILL, 5.0),
|
||||
MYSTIC_WILL(Varbits.PRAYER_MYSTIC_WILL, 5.0, WidgetInfo.PRAYER_MYSTIC_WILL),
|
||||
/**
|
||||
* Rock Skin (Level 10, Defence).
|
||||
*/
|
||||
ROCK_SKIN(Varbits.PRAYER_ROCK_SKIN, 10.0),
|
||||
ROCK_SKIN(Varbits.PRAYER_ROCK_SKIN, 10.0, WidgetInfo.PRAYER_ROCK_SKIN),
|
||||
/**
|
||||
* Superhuman Strength (Level 13, Strength).
|
||||
*/
|
||||
SUPERHUMAN_STRENGTH(Varbits.PRAYER_SUPERHUMAN_STRENGTH, 10.0),
|
||||
SUPERHUMAN_STRENGTH(Varbits.PRAYER_SUPERHUMAN_STRENGTH, 10.0, WidgetInfo.PRAYER_SUPERHUMAN_STRENGTH),
|
||||
/**
|
||||
* Improved Reflexes (Level 16, Attack).
|
||||
*/
|
||||
IMPROVED_REFLEXES(Varbits.PRAYER_IMPROVED_REFLEXES, 10.0),
|
||||
IMPROVED_REFLEXES(Varbits.PRAYER_IMPROVED_REFLEXES, 10.0, WidgetInfo.PRAYER_IMPROVED_REFLEXES),
|
||||
/**
|
||||
* Rapid Restore (Level 19, Stats).
|
||||
*/
|
||||
RAPID_RESTORE(Varbits.PRAYER_RAPID_RESTORE, 60.0 / 36.0),
|
||||
RAPID_RESTORE(Varbits.PRAYER_RAPID_RESTORE, 60.0 / 36.0, WidgetInfo.PRAYER_RAPID_RESTORE),
|
||||
/**
|
||||
* Rapid Heal (Level 22, Hitpoints).
|
||||
*/
|
||||
RAPID_HEAL(Varbits.PRAYER_RAPID_HEAL, 60.0 / 18),
|
||||
RAPID_HEAL(Varbits.PRAYER_RAPID_HEAL, 60.0 / 18, WidgetInfo.PRAYER_RAPID_HEAL),
|
||||
/**
|
||||
* Protect Item (Level 25).
|
||||
*/
|
||||
PROTECT_ITEM(Varbits.PRAYER_PROTECT_ITEM, 60.0 / 18),
|
||||
PROTECT_ITEM(Varbits.PRAYER_PROTECT_ITEM, 60.0 / 18, WidgetInfo.PRAYER_PROTECT_ITEM),
|
||||
/**
|
||||
* Hawk Eye (Level 26, Ranging).
|
||||
*/
|
||||
HAWK_EYE(Varbits.PRAYER_HAWK_EYE, 10.0),
|
||||
HAWK_EYE(Varbits.PRAYER_HAWK_EYE, 10.0, WidgetInfo.PRAYER_HAWK_EYE),
|
||||
/**
|
||||
* Mystic Lore (Level 27, Magic).
|
||||
*/
|
||||
MYSTIC_LORE(Varbits.PRAYER_MYSTIC_LORE, 10.0),
|
||||
MYSTIC_LORE(Varbits.PRAYER_MYSTIC_LORE, 10.0, WidgetInfo.PRAYER_MYSTIC_LORE),
|
||||
/**
|
||||
* Steel Skin (Level 28, Defence).
|
||||
*/
|
||||
STEEL_SKIN(Varbits.PRAYER_STEEL_SKIN, 20.0),
|
||||
STEEL_SKIN(Varbits.PRAYER_STEEL_SKIN, 20.0, WidgetInfo.PRAYER_STEEL_SKIN),
|
||||
/**
|
||||
* Ultimate Strength (Level 31, Strength).
|
||||
*/
|
||||
ULTIMATE_STRENGTH(Varbits.PRAYER_ULTIMATE_STRENGTH, 20.0),
|
||||
ULTIMATE_STRENGTH(Varbits.PRAYER_ULTIMATE_STRENGTH, 20.0, WidgetInfo.PRAYER_ULTIMATE_STRENGTH),
|
||||
/**
|
||||
* Incredible Reflexes (Level 34, Attack).
|
||||
*/
|
||||
INCREDIBLE_REFLEXES(Varbits.PRAYER_INCREDIBLE_REFLEXES, 20.0),
|
||||
INCREDIBLE_REFLEXES(Varbits.PRAYER_INCREDIBLE_REFLEXES, 20.0, WidgetInfo.PRAYER_INCREDIBLE_REFLEXES),
|
||||
/**
|
||||
* Protect from Magic (Level 37).
|
||||
*/
|
||||
PROTECT_FROM_MAGIC(Varbits.PRAYER_PROTECT_FROM_MAGIC, 20.0),
|
||||
PROTECT_FROM_MAGIC(Varbits.PRAYER_PROTECT_FROM_MAGIC, 20.0, WidgetInfo.PRAYER_PROTECT_FROM_MAGIC),
|
||||
/**
|
||||
* Protect from Missiles (Level 40).
|
||||
*/
|
||||
PROTECT_FROM_MISSILES(Varbits.PRAYER_PROTECT_FROM_MISSILES, 20.0),
|
||||
PROTECT_FROM_MISSILES(Varbits.PRAYER_PROTECT_FROM_MISSILES, 20.0, WidgetInfo.PRAYER_PROTECT_FROM_MISSILES),
|
||||
/**
|
||||
* Protect from Melee (Level 43).
|
||||
*/
|
||||
PROTECT_FROM_MELEE(Varbits.PRAYER_PROTECT_FROM_MELEE, 20.0),
|
||||
PROTECT_FROM_MELEE(Varbits.PRAYER_PROTECT_FROM_MELEE, 20.0, WidgetInfo.PRAYER_PROTECT_FROM_MELEE),
|
||||
/**
|
||||
* Eagle Eye (Level 44, Ranging).
|
||||
*/
|
||||
EAGLE_EYE(Varbits.PRAYER_EAGLE_EYE, 20.0),
|
||||
EAGLE_EYE(Varbits.PRAYER_EAGLE_EYE, 20.0, WidgetInfo.PRAYER_EAGLE_EYE),
|
||||
/**
|
||||
* Mystic Might (Level 45, Magic).
|
||||
*/
|
||||
MYSTIC_MIGHT(Varbits.PRAYER_MYSTIC_MIGHT, 20.0),
|
||||
MYSTIC_MIGHT(Varbits.PRAYER_MYSTIC_MIGHT, 20.0, WidgetInfo.PRAYER_MYSTIC_MIGHT),
|
||||
/**
|
||||
* Retribution (Level 46).
|
||||
*/
|
||||
RETRIBUTION(Varbits.PRAYER_RETRIBUTION, 5.0),
|
||||
RETRIBUTION(Varbits.PRAYER_RETRIBUTION, 5.0, WidgetInfo.PRAYER_RETRIBUTION),
|
||||
/**
|
||||
* Redemption (Level 49).
|
||||
*/
|
||||
REDEMPTION(Varbits.PRAYER_REDEMPTION, 10.0),
|
||||
REDEMPTION(Varbits.PRAYER_REDEMPTION, 10.0, WidgetInfo.PRAYER_REDEMPTION),
|
||||
/**
|
||||
* Smite (Level 52).
|
||||
*/
|
||||
SMITE(Varbits.PRAYER_SMITE, 30.0),
|
||||
SMITE(Varbits.PRAYER_SMITE, 30.0, WidgetInfo.PRAYER_SMITE),
|
||||
/**
|
||||
* Chivalry (Level 60, Defence/Strength/Attack).
|
||||
*/
|
||||
CHIVALRY(Varbits.PRAYER_CHIVALRY, 40.0),
|
||||
CHIVALRY(Varbits.PRAYER_CHIVALRY, 40.0, WidgetInfo.PRAYER_CHIVALRY),
|
||||
/**
|
||||
* Piety (Level 70, Defence/Strength/Attack).
|
||||
*/
|
||||
PIETY(Varbits.PRAYER_PIETY, 40.0),
|
||||
PIETY(Varbits.PRAYER_PIETY, 40.0, WidgetInfo.PRAYER_PIETY),
|
||||
/**
|
||||
* Preserve (Level 55).
|
||||
*/
|
||||
PRESERVE(Varbits.PRAYER_PRESERVE, 60.0 / 18),
|
||||
PRESERVE(Varbits.PRAYER_PRESERVE, 60.0 / 18, WidgetInfo.PRAYER_PRESERVE),
|
||||
/**
|
||||
* Rigour (Level 74, Ranging/Damage/Defence).
|
||||
*/
|
||||
RIGOUR(Varbits.PRAYER_RIGOUR, 40.0),
|
||||
RIGOUR(Varbits.PRAYER_RIGOUR, 40.0, WidgetInfo.PRAYER_RIGOUR),
|
||||
/**
|
||||
* Augury (Level 77, Magic/Magic Def./Defence).
|
||||
*/
|
||||
AUGURY(Varbits.PRAYER_AUGURY, 40.0);
|
||||
|
||||
private final Varbits varbit;
|
||||
|
||||
private final double drainRate;
|
||||
|
||||
Prayer(Varbits varbit, double drainRate)
|
||||
{
|
||||
this.varbit = varbit;
|
||||
this.drainRate = drainRate;
|
||||
}
|
||||
AUGURY(Varbits.PRAYER_AUGURY, 40.0, WidgetInfo.PRAYER_AUGURY);
|
||||
|
||||
/**
|
||||
* Gets the varbit that stores whether the prayer is active or not.
|
||||
*
|
||||
* @return the prayer active varbit
|
||||
*/
|
||||
public Varbits getVarbit()
|
||||
{
|
||||
return varbit;
|
||||
}
|
||||
private final Varbits varbit;
|
||||
|
||||
/**
|
||||
* Gets the prayer drain rate (measured in pray points/minute)
|
||||
*
|
||||
* @return the prayer drain rate
|
||||
*/
|
||||
public double getDrainRate()
|
||||
{
|
||||
return drainRate;
|
||||
}
|
||||
}
|
||||
private final double drainRate;
|
||||
|
||||
/**
|
||||
* Gets the widget info for prayer
|
||||
*/
|
||||
private final WidgetInfo widgetInfo;
|
||||
|
||||
}
|
||||
@@ -59,6 +59,7 @@ public class NPCManager
|
||||
|
||||
/**
|
||||
* Returns the {@link NPCStats} for target NPC id
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return the {@link NPCStats} or null if unknown
|
||||
*/
|
||||
@@ -70,23 +71,41 @@ public class NPCManager
|
||||
|
||||
/**
|
||||
* Returns health for target NPC ID
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return health or null if unknown
|
||||
*/
|
||||
@Nullable
|
||||
public Integer getHealth(final int npcId)
|
||||
public int getHealth(final int npcId)
|
||||
{
|
||||
final NPCStats s = statsMap.get(npcId);
|
||||
if (s == null || s.getHitpoints() == -1)
|
||||
{
|
||||
return null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s.getHitpoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attack speed for target NPC ID.
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return attack speed in game ticks for NPC ID.
|
||||
*/
|
||||
public int getAttackSpeed(final int npcId)
|
||||
{
|
||||
final NPCStats s = statsMap.get(npcId);
|
||||
if (s == null || s.getAttackSpeed() == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s.getAttackSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exp modifier for target NPC ID based on its stats.
|
||||
*
|
||||
* @param npcId NPC id
|
||||
* @return npcs exp modifier. Assumes default xp rate if npc stats are unknown (returns 1)
|
||||
*/
|
||||
|
||||
@@ -34,6 +34,7 @@ public class NPCStats
|
||||
private final int hitpoints;
|
||||
private final int combatLevel;
|
||||
private final int slayerLevel;
|
||||
private final int attackSpeed;
|
||||
|
||||
private final int attackLevel;
|
||||
private final int strengthLevel;
|
||||
|
||||
@@ -65,7 +65,7 @@ class OpponentInfoOverlay extends Overlay
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
private Integer lastMaxHealth;
|
||||
private int lastMaxHealth;
|
||||
private int lastRatio = 0;
|
||||
private int lastHealthScale = 0;
|
||||
private String opponentName;
|
||||
@@ -111,7 +111,7 @@ class OpponentInfoOverlay extends Overlay
|
||||
lastHealthScale = opponent.getHealth();
|
||||
opponentName = Text.removeTags(opponent.getName());
|
||||
|
||||
lastMaxHealth = null;
|
||||
lastMaxHealth = -1;
|
||||
if (opponent instanceof NPC)
|
||||
{
|
||||
lastMaxHealth = npcManager.getHealth(((NPC) opponent).getId());
|
||||
@@ -167,7 +167,7 @@ class OpponentInfoOverlay extends Overlay
|
||||
final HitpointsDisplayStyle displayStyle = opponentInfoConfig.hitpointsDisplayStyle();
|
||||
|
||||
if ((displayStyle == HitpointsDisplayStyle.HITPOINTS || displayStyle == HitpointsDisplayStyle.BOTH)
|
||||
&& lastMaxHealth != null)
|
||||
&& lastMaxHealth != -1)
|
||||
{
|
||||
// This is the reverse of the calculation of healthRatio done by the server
|
||||
// which is: healthRatio = 1 + (healthScale - 1) * health / maxHealth (if health > 0, 0 otherwise)
|
||||
|
||||
@@ -98,9 +98,9 @@ class TargetWeaknessOverlay extends Overlay
|
||||
|
||||
final int healthScale = target.getHealth();
|
||||
final int healthRatio = target.getHealthRatio();
|
||||
final Integer maxHealth = npcManager.getHealth(target.getId());
|
||||
final int maxHealth = npcManager.getHealth(target.getId());
|
||||
|
||||
if (healthRatio < 0 || healthScale <= 0 || maxHealth == null)
|
||||
if (healthRatio < 0 || healthScale <= 0 || maxHealth == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.ticktimers;
|
||||
|
||||
import java.awt.Font;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum FontStyle
|
||||
{
|
||||
BOLD("Bold", Font.BOLD),
|
||||
ITALIC("Italic", Font.ITALIC),
|
||||
PLAIN("Plain", Font.PLAIN);
|
||||
|
||||
private String name;
|
||||
private int font;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* Copyright (c) 2019, Ganom <https://github.com/Ganom>
|
||||
* Copyright (c) 2019, Lucas <https://github.com/lucwousin>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -25,65 +25,125 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.ticktimers;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.awt.Color;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Prayer;
|
||||
|
||||
@Getter
|
||||
class NPCContainer
|
||||
{
|
||||
@Getter
|
||||
private NPC npc;
|
||||
@Getter
|
||||
private int npcIndex;
|
||||
@Getter
|
||||
private String npcName;
|
||||
@Getter
|
||||
private int npcSize;
|
||||
private ImmutableSet<Integer> animations;
|
||||
private int attackSpeed;
|
||||
@Setter
|
||||
@Getter
|
||||
private int TicksUntilAttack;
|
||||
private int ticksUntilAttack;
|
||||
@Setter
|
||||
@Getter
|
||||
private int npcSpeed;
|
||||
@Setter
|
||||
@Getter
|
||||
private Actor npcInteracting;
|
||||
@Setter
|
||||
@Getter
|
||||
private Attackstyle attackStyle;
|
||||
private AttackStyle attackStyle;
|
||||
|
||||
NPCContainer(NPC npc)
|
||||
NPCContainer(NPC npc, int attackSpeed)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.npcName = npc.getName();
|
||||
this.npcIndex = npc.getIndex();
|
||||
this.npcInteracting = npc.getInteracting();
|
||||
this.npcSpeed = 0;
|
||||
this.attackStyle = Attackstyle.UNKNOWN;
|
||||
this.TicksUntilAttack = 0;
|
||||
this.attackStyle = AttackStyle.UNKNOWN;
|
||||
this.attackSpeed = attackSpeed;
|
||||
this.ticksUntilAttack = -1;
|
||||
final NPCDefinition composition = npc.getTransformedDefinition();
|
||||
|
||||
BossMonsters monster = BossMonsters.of(npc.getId());
|
||||
|
||||
if (monster == null)
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
this.animations = monster.animations;
|
||||
this.attackStyle = monster.attackStyle;
|
||||
|
||||
if (composition != null)
|
||||
{
|
||||
this.npcSize = composition.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
enum BossMonsters
|
||||
{
|
||||
SERGEANT_STRONGSTACK(NpcID.SERGEANT_STRONGSTACK, AttackStyle.MELEE, ImmutableSet.of(AnimationID.MINION_AUTO1, AnimationID.MINION_AUTO2, AnimationID.MINION_AUTO3)),
|
||||
SERGEANT_STEELWILL(NpcID.SERGEANT_STEELWILL, AttackStyle.MAGE, ImmutableSet.of(AnimationID.MINION_AUTO1, AnimationID.MINION_AUTO2, AnimationID.MINION_AUTO3)),
|
||||
SERGEANT_GRIMSPIKE(NpcID.SERGEANT_GRIMSPIKE, AttackStyle.RANGE, ImmutableSet.of(AnimationID.MINION_AUTO1, AnimationID.MINION_AUTO2, AnimationID.MINION_AUTO4)),
|
||||
GENERAL_GRAARDOR(NpcID.GENERAL_GRAARDOR, AttackStyle.MELEE, ImmutableSet.of(AnimationID.GENERAL_AUTO1, AnimationID.GENERAL_AUTO2, AnimationID.GENERAL_AUTO3)),
|
||||
|
||||
TSTANON_KARLAK(NpcID.TSTANON_KARLAK, AttackStyle.MELEE, ImmutableSet.of(AnimationID.ZAMMY_GENERIC_AUTO)),
|
||||
BALFRUG_KREEYATH(NpcID.BALFRUG_KREEYATH, AttackStyle.MAGE, ImmutableSet.of(AnimationID.ZAMMY_GENERIC_AUTO, AnimationID.BALFRUG_AUTO)),
|
||||
ZAKLN_GRITCH(NpcID.ZAKLN_GRITCH, AttackStyle.RANGE, ImmutableSet.of(AnimationID.ZAMMY_GENERIC_AUTO, AnimationID.ZAKL_AUTO)),
|
||||
KRIL_TSUTSAROTH(NpcID.KRIL_TSUTSAROTH, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.KRIL_SPEC, AnimationID.KRIL_AUTO)),
|
||||
|
||||
STARLIGHT(NpcID.STARLIGHT, AttackStyle.MELEE, ImmutableSet.of(AnimationID.STARLIGHT_AUTO)),
|
||||
GROWLER(NpcID.GROWLER, AttackStyle.MAGE, ImmutableSet.of(AnimationID.GROWLER_AUTO)),
|
||||
BREE(NpcID.BREE, AttackStyle.RANGE, ImmutableSet.of(AnimationID.BREE_AUTO)),
|
||||
COMMANDER_ZILYANA(NpcID.COMMANDER_ZILYANA, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.ZILYANA_AUTO, AnimationID.ZILYANA_MELEE_AUTO, AnimationID.ZILYANA_SPEC)),
|
||||
|
||||
FLIGHT_KILISA(NpcID.FLIGHT_KILISA, AttackStyle.MELEE, ImmutableSet.of(AnimationID.KILISA_AUTO)),
|
||||
FLOCKLEADER_GEERIN(NpcID.FLOCKLEADER_GEERIN, AttackStyle.MAGE, ImmutableSet.of(AnimationID.GEERIN_AUTO, AnimationID.GEERIN_FLINCH)),
|
||||
WINGMAN_SKREE(NpcID.WINGMAN_SKREE, AttackStyle.RANGE, ImmutableSet.of(AnimationID.SKREE_AUTO)),
|
||||
KREEARRA(NpcID.KREEARRA, AttackStyle.RANGE, ImmutableSet.of(AnimationID.KREE_RANGED)),
|
||||
|
||||
DAGANNOTH_REX(NpcID.DAGANNOTH_REX, AttackStyle.MAGE, ImmutableSet.of(AnimationID.DAG_REX)),
|
||||
DAGANNOTH_SUPREME(NpcID.DAGANNOTH_SUPREME, AttackStyle.RANGE, ImmutableSet.of(AnimationID.DAG_SUPREME)),
|
||||
DAGANNOTH_PRIME(NpcID.DAGANNOTH_PRIME, AttackStyle.MAGE, ImmutableSet.of(AnimationID.DAG_PRIME));
|
||||
|
||||
private static ImmutableMap<Integer, BossMonsters> idMap;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, BossMonsters> builder = ImmutableMap.builder();
|
||||
|
||||
for (BossMonsters monster : values())
|
||||
{
|
||||
builder.put(monster.npcID, monster);
|
||||
}
|
||||
|
||||
idMap = builder.build();
|
||||
}
|
||||
|
||||
private final int npcID;
|
||||
private final AttackStyle attackStyle;
|
||||
private final ImmutableSet<Integer> animations;
|
||||
|
||||
static BossMonsters of(int npcID)
|
||||
{
|
||||
return idMap.get(npcID);
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum Attackstyle
|
||||
public enum AttackStyle
|
||||
{
|
||||
MAGE("Mage", Color.CYAN),
|
||||
RANGE("Range", Color.GREEN),
|
||||
MELEE("Melee", Color.RED),
|
||||
UNKNOWN("Unknown", Color.WHITE);
|
||||
MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES),
|
||||
MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE),
|
||||
UNKNOWN("Unknown", Color.WHITE, null);
|
||||
|
||||
private String name = "";
|
||||
private String name;
|
||||
private Color color;
|
||||
private Prayer prayer;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,9 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.ticktimers;
|
||||
|
||||
import java.awt.Font;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
@@ -34,6 +37,54 @@ public interface TickTimersConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "mainConfig",
|
||||
name = "Main Config",
|
||||
description = ""
|
||||
)
|
||||
default Stub mainConfig()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "prayerWidgetHelper",
|
||||
name = "Prayer Widget Helper",
|
||||
description = "Shows you which prayer to click and the time until click.",
|
||||
parent = "mainConfig"
|
||||
)
|
||||
default boolean showPrayerWidgetHelper()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "showHitSquares",
|
||||
name = "Show Hit Squares",
|
||||
description = "Shows you where the melee bosses can hit you from.",
|
||||
parent = "mainConfig"
|
||||
)
|
||||
default boolean showHitSquares()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "changeTickColor",
|
||||
name = "Change Tick Color",
|
||||
description = "If this is enabled, it will change the tick color to white" +
|
||||
"<br> at 1 tick remaining, signaling you to swap.",
|
||||
parent = "mainConfig"
|
||||
)
|
||||
default boolean changeTickColor()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "bosses",
|
||||
name = "Bosses",
|
||||
description = ""
|
||||
@@ -44,19 +95,31 @@ public interface TickTimersConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "graardor",
|
||||
name = "General Graardor",
|
||||
description = "Show tick timers for General Graardor",
|
||||
position = 5,
|
||||
keyName = "gwd",
|
||||
name = "God Wars Dungeon",
|
||||
description = "Show tick timers for GWD Bosses. This must be enabled before you zone in.",
|
||||
parent = "bosses"
|
||||
)
|
||||
default boolean graardor()
|
||||
default boolean gwd()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 22,
|
||||
position = 6,
|
||||
keyName = "dks",
|
||||
name = "Dagannoth Kings",
|
||||
description = "Show tick timers for Dagannoth Kings. This must be enabled before you zone in.",
|
||||
parent = "bosses"
|
||||
)
|
||||
default boolean dks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "text",
|
||||
name = "Text",
|
||||
description = ""
|
||||
@@ -67,7 +130,7 @@ public interface TickTimersConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 23,
|
||||
position = 8,
|
||||
keyName = "fontStyle",
|
||||
name = "Font Style",
|
||||
description = "Plain | Bold | Italics",
|
||||
@@ -75,7 +138,7 @@ public interface TickTimersConfig extends Config
|
||||
)
|
||||
default FontStyle fontStyle()
|
||||
{
|
||||
return FontStyle.PLAIN;
|
||||
return FontStyle.BOLD;
|
||||
}
|
||||
|
||||
@Range(
|
||||
@@ -83,7 +146,7 @@ public interface TickTimersConfig extends Config
|
||||
max = 40
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 24,
|
||||
position = 9,
|
||||
keyName = "textSize",
|
||||
name = "Text Size",
|
||||
description = "Text Size for Timers.",
|
||||
@@ -95,7 +158,7 @@ public interface TickTimersConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 25,
|
||||
position = 10,
|
||||
keyName = "shadows",
|
||||
name = "Shadows",
|
||||
description = "Adds Shadows to text.",
|
||||
@@ -105,4 +168,22 @@ public interface TickTimersConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
enum FontStyle
|
||||
{
|
||||
BOLD("Bold", Font.BOLD),
|
||||
ITALIC("Italic", Font.ITALIC),
|
||||
PLAIN("Plain", Font.PLAIN);
|
||||
|
||||
private String name;
|
||||
private int font;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* Copyright (c) 2019, Ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -24,13 +24,13 @@
|
||||
package net.runelite.client.plugins.ticktimers;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.NPC;
|
||||
@@ -41,11 +41,11 @@ import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.NPCManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Boss Tick Timers",
|
||||
@@ -59,21 +59,24 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
public class TickTimersPlugin extends Plugin
|
||||
{
|
||||
private static final int GENERAL_REGION = 11347;
|
||||
private static final int ARMA_REGION = 11346;
|
||||
private static final int SARA_REGION = 11601;
|
||||
private static final int ZAMMY_REGION = 11603;
|
||||
private static final int WATERBITH_REGION = 11589;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private TimersOverlay timersOverlay;
|
||||
|
||||
@Inject
|
||||
private TickTimersConfig config;
|
||||
|
||||
@Inject
|
||||
private NPCManager npcManager;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> npcContainer = new HashMap<>();
|
||||
private Set<NPCContainer> npcContainer = new HashSet<>();
|
||||
private boolean validRegion;
|
||||
|
||||
@Provides
|
||||
TickTimersConfig getConfig(ConfigManager configManager)
|
||||
@@ -91,41 +94,71 @@ public class TickTimersPlugin extends Plugin
|
||||
public void shutDown()
|
||||
{
|
||||
npcContainer.clear();
|
||||
overlayManager.remove(timersOverlay);
|
||||
validRegion = false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
if (isInGeneralRegion())
|
||||
{
|
||||
overlayManager.add(timersOverlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayManager.remove(timersOverlay);
|
||||
}
|
||||
}
|
||||
if (gameStateChanged.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionCheck())
|
||||
{
|
||||
validRegion = true;
|
||||
overlayManager.add(timersOverlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
validRegion = false;
|
||||
overlayManager.remove(timersOverlay);
|
||||
}
|
||||
npcContainer.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
if (!validRegion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.SERGEANT_STRONGSTACK:
|
||||
case NpcID.SERGEANT_STEELWILL:
|
||||
case NpcID.SERGEANT_GRIMSPIKE:
|
||||
case NpcID.GENERAL_GRAARDOR:
|
||||
case NpcID.GENERAL_GRAARDOR_6494:
|
||||
npcContainer.put(npc, new NPCContainer(npc));
|
||||
case NpcID.TSTANON_KARLAK:
|
||||
case NpcID.BALFRUG_KREEYATH:
|
||||
case NpcID.ZAKLN_GRITCH:
|
||||
case NpcID.KRIL_TSUTSAROTH:
|
||||
case NpcID.STARLIGHT:
|
||||
case NpcID.BREE:
|
||||
case NpcID.GROWLER:
|
||||
case NpcID.COMMANDER_ZILYANA:
|
||||
case NpcID.FLIGHT_KILISA:
|
||||
case NpcID.FLOCKLEADER_GEERIN:
|
||||
case NpcID.WINGMAN_SKREE:
|
||||
case NpcID.KREEARRA:
|
||||
if (config.gwd())
|
||||
{
|
||||
npcContainer.add(new NPCContainer(npc, npcManager.getAttackSpeed(npc.getId())));
|
||||
}
|
||||
break;
|
||||
case NpcID.DAGANNOTH_REX:
|
||||
case NpcID.DAGANNOTH_SUPREME:
|
||||
case NpcID.DAGANNOTH_PRIME:
|
||||
if (config.dks())
|
||||
{
|
||||
npcContainer.add(new NPCContainer(npc, npcManager.getAttackSpeed(npc.getId())));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -133,92 +166,76 @@ public class TickTimersPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (npcContainer.remove(event.getNpc()) != null && !npcContainer.isEmpty())
|
||||
if (!validRegion)
|
||||
{
|
||||
npcContainer.remove(event.getNpc());
|
||||
return;
|
||||
}
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.SERGEANT_STRONGSTACK:
|
||||
case NpcID.SERGEANT_STEELWILL:
|
||||
case NpcID.SERGEANT_GRIMSPIKE:
|
||||
case NpcID.GENERAL_GRAARDOR:
|
||||
case NpcID.TSTANON_KARLAK:
|
||||
case NpcID.BALFRUG_KREEYATH:
|
||||
case NpcID.ZAKLN_GRITCH:
|
||||
case NpcID.KRIL_TSUTSAROTH:
|
||||
case NpcID.STARLIGHT:
|
||||
case NpcID.BREE:
|
||||
case NpcID.GROWLER:
|
||||
case NpcID.COMMANDER_ZILYANA:
|
||||
case NpcID.FLIGHT_KILISA:
|
||||
case NpcID.FLOCKLEADER_GEERIN:
|
||||
case NpcID.WINGMAN_SKREE:
|
||||
case NpcID.KREEARRA:
|
||||
case NpcID.DAGANNOTH_REX:
|
||||
case NpcID.DAGANNOTH_SUPREME:
|
||||
case NpcID.DAGANNOTH_PRIME:
|
||||
npcContainer.removeIf(c -> c.getNpc() == npc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick Event)
|
||||
{
|
||||
if (config.graardor())
|
||||
if (!validRegion)
|
||||
{
|
||||
graardorHandler();
|
||||
return;
|
||||
}
|
||||
|
||||
handleBosses();
|
||||
}
|
||||
|
||||
private void graardorHandler()
|
||||
private void handleBosses()
|
||||
{
|
||||
for (NPCContainer npcs : getNpcContainer().values())
|
||||
for (NPCContainer npcs : getNpcContainer())
|
||||
{
|
||||
switch (npcs.getNpc().getId())
|
||||
if (npcs.getTicksUntilAttack() >= 0)
|
||||
{
|
||||
case NpcID.SERGEANT_STRONGSTACK:
|
||||
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MELEE);
|
||||
switch (npcs.getNpc().getAnimation())
|
||||
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
|
||||
}
|
||||
|
||||
for (int anims : npcs.getAnimations())
|
||||
{
|
||||
if (anims == npcs.getNpc().getAnimation())
|
||||
{
|
||||
if (npcs.getTicksUntilAttack() < 1)
|
||||
{
|
||||
case AnimationID.MINION_AUTO1:
|
||||
case AnimationID.MINION_AUTO2:
|
||||
if (npcs.getTicksUntilAttack() < 1)
|
||||
{
|
||||
npcs.setTicksUntilAttack(5);
|
||||
}
|
||||
break;
|
||||
npcs.setTicksUntilAttack(npcs.getAttackSpeed());
|
||||
}
|
||||
break;
|
||||
case NpcID.SERGEANT_STEELWILL:
|
||||
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MAGE);
|
||||
switch (npcs.getNpc().getAnimation())
|
||||
{
|
||||
case AnimationID.MINION_AUTO1:
|
||||
case AnimationID.MINION_AUTO2:
|
||||
case AnimationID.MINION_AUTO3:
|
||||
if (npcs.getTicksUntilAttack() < 1)
|
||||
{
|
||||
npcs.setTicksUntilAttack(5);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NpcID.SERGEANT_GRIMSPIKE:
|
||||
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.RANGE);
|
||||
switch (npcs.getNpc().getAnimation())
|
||||
{
|
||||
case AnimationID.MINION_AUTO1:
|
||||
case AnimationID.MINION_AUTO2:
|
||||
case AnimationID.MINION_AUTO4:
|
||||
if (npcs.getTicksUntilAttack() < 1)
|
||||
{
|
||||
npcs.setTicksUntilAttack(5);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NpcID.GENERAL_GRAARDOR:
|
||||
case NpcID.GENERAL_GRAARDOR_6494:
|
||||
npcs.setTicksUntilAttack(npcs.getTicksUntilAttack() - 1);
|
||||
npcs.setAttackStyle(NPCContainer.Attackstyle.MELEE);
|
||||
switch (npcs.getNpc().getAnimation())
|
||||
{
|
||||
case AnimationID.GENERAL_AUTO1:
|
||||
case AnimationID.GENERAL_AUTO2:
|
||||
case AnimationID.GENERAL_AUTO3:
|
||||
if (npcs.getTicksUntilAttack() < 1)
|
||||
{
|
||||
npcs.setTicksUntilAttack(6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInGeneralRegion()
|
||||
private boolean regionCheck()
|
||||
{
|
||||
return ArrayUtils.contains(client.getMapRegions(), GENERAL_REGION);
|
||||
return Arrays.stream(client.getMapRegions()).anyMatch(
|
||||
x -> x == ARMA_REGION || x == GENERAL_REGION || x == ZAMMY_REGION || x == SARA_REGION || x == WATERBITH_REGION
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,19 +24,17 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.ticktimers;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldArea;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -63,67 +61,91 @@ public class TimersOverlay extends Overlay
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Color tickcolor;
|
||||
|
||||
for (NPCContainer npcs : plugin.getNpcContainer().values())
|
||||
for (NPCContainer npc : plugin.getNpcContainer())
|
||||
{
|
||||
renderNpcOverlay(graphics, npcs.getNpc(), npcs.getAttackStyle().getColor(), 100, 10);
|
||||
final int ticksLeft = npcs.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
if (npc.getNpc() == null)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
continue;
|
||||
}
|
||||
|
||||
int ticksLeft = npc.getTicksUntilAttack();
|
||||
final List<WorldPoint> hitSquares = getHitSquares(npc.getNpc().getWorldLocation(), npc.getNpcSize(), 1, false);
|
||||
final NPCContainer.AttackStyle attackStyle = npc.getAttackStyle();
|
||||
|
||||
if (config.showHitSquares() && attackStyle.getName().equals("Melee"))
|
||||
{
|
||||
for (WorldPoint p : hitSquares)
|
||||
{
|
||||
tickcolor = npcs.getAttackStyle().getColor();
|
||||
OverlayUtil.drawTile(graphics, client, p, client.getLocalPlayer().getWorldLocation(), attackStyle.getColor(), 0, 0, 50);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
if (ticksLeft <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
final int font = config.fontStyle().getFont();
|
||||
final boolean shadows = config.shadows();
|
||||
Color color = (ticksLeft <= 1 ? Color.WHITE : attackStyle.getColor());
|
||||
|
||||
if (!config.changeTickColor())
|
||||
{
|
||||
color = attackStyle.getColor();
|
||||
}
|
||||
|
||||
final Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, Integer.toString(ticksLeft), 0);
|
||||
|
||||
OverlayUtil.renderTextLocation(graphics, ticksLeftStr, config.textSize(), font, color, canvasPoint, shadows, 0);
|
||||
|
||||
if (config.showPrayerWidgetHelper() && attackStyle.getPrayer() != null)
|
||||
{
|
||||
Rectangle bounds = OverlayUtil.renderPrayerOverlay(graphics, client, attackStyle.getPrayer(), color);
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
tickcolor = Color.WHITE;
|
||||
renderTextLocation(graphics, ticksLeftStr, 16, config.fontStyle().getFont(), color, centerPoint(bounds), shadows);
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npcs.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, config.textSize(), config.fontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = actor.getTransformedDefinition();
|
||||
if (composition != null)
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
LocalPoint lp = actor.getLocalLocation();
|
||||
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size);
|
||||
|
||||
if (tilePoly != null)
|
||||
{
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(tilePoly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(tilePoly);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint)
|
||||
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", fontStyle, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY());
|
||||
canvasPoint.getX() - 3,
|
||||
canvasPoint.getY() + 6);
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 1);
|
||||
if (config.shadows())
|
||||
canvasPoint.getX() - 2,
|
||||
canvasPoint.getY() + 7);
|
||||
if (shadows)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
private List<WorldPoint> getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder)
|
||||
{
|
||||
List<WorldPoint> little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList();
|
||||
List<WorldPoint> big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList();
|
||||
if (!includeUnder)
|
||||
{
|
||||
big.removeIf(little::contains);
|
||||
}
|
||||
return big;
|
||||
}
|
||||
|
||||
private Point centerPoint(Rectangle rect)
|
||||
{
|
||||
int x = (int) (rect.getX() + rect.getWidth() / 2);
|
||||
int y = (int) (rect.getY() + rect.getHeight() / 2);
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,9 +126,9 @@ class XpState
|
||||
* @param npc currently interacted NPC
|
||||
* @param npcHealth health of currently interacted NPC
|
||||
*/
|
||||
void updateNpcExperience(Skill skill, NPC npc, Integer npcHealth)
|
||||
void updateNpcExperience(Skill skill, NPC npc, int npcHealth)
|
||||
{
|
||||
if (npc == null || npc.getCombatLevel() <= 0 || npcHealth == null)
|
||||
if (npc == null || npc.getCombatLevel() <= 0 || npcHealth == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -170,11 +170,11 @@ class XpState
|
||||
* @param npcHealth max health of npc that just died
|
||||
* @return UPDATED in case new kill was successfully added
|
||||
*/
|
||||
XpUpdateResult updateNpcKills(Skill skill, NPC npc, Integer npcHealth)
|
||||
XpUpdateResult updateNpcKills(Skill skill, NPC npc, int npcHealth)
|
||||
{
|
||||
XpStateSingle state = getSkill(skill);
|
||||
|
||||
if (state.getXpGained() <= 0 || npcHealth == null || npc != interactedNPC)
|
||||
if (state.getXpGained() <= 0 || npcHealth == -1 || npc != interactedNPC)
|
||||
{
|
||||
return XpUpdateResult.NO_CHANGE;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ import com.google.common.base.Strings;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.geom.Area;
|
||||
@@ -38,8 +40,11 @@ import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
|
||||
|
||||
/**
|
||||
@@ -259,8 +264,7 @@ public class OverlayUtil
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color,
|
||||
BufferedImage image, int yOffset, int xOffset)
|
||||
public static void renderActorTextAndImage(Graphics2D graphics, Actor actor, String text, Color color, BufferedImage image, int yOffset, int xOffset)
|
||||
{
|
||||
Point textLocation = new Point(actor.getConvexHull().getBounds().x + xOffset,
|
||||
actor.getConvexHull().getBounds().y + yOffset);
|
||||
@@ -271,4 +275,69 @@ public class OverlayUtil
|
||||
textLocation = new Point(textLocation.getX() + xOffset, textLocation.getY() + image.getHeight() - yOffset);
|
||||
renderTextLocation(graphics, textLocation, text, color);
|
||||
}
|
||||
|
||||
public static void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows, int yOffset)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", fontStyle, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY() + yOffset);
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 1);
|
||||
if (shadows)
|
||||
{
|
||||
renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawTile(Graphics2D graphics, Client client, WorldPoint point, WorldPoint playerPoint, Color color, int strokeWidth, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
if (point.distanceTo(playerPoint) >= 32)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, point);
|
||||
if (lp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
if (poly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
public static Rectangle renderPrayerOverlay(Graphics2D graphics, Client client, Prayer prayer, Color color)
|
||||
{
|
||||
Widget widget = client.getWidget(prayer.getWidgetInfo());
|
||||
|
||||
if (widget == null || widget.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Rectangle bounds = widget.getBounds();
|
||||
renderPolygon(graphics, rectangleToPolygon(bounds), color);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user