Rework and Improve Fight Caves (#801)
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR 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;;
|
||||
package net.runelite.api;
|
||||
|
||||
/**
|
||||
* Utility class used for mapping animation IDs.
|
||||
@@ -166,8 +166,15 @@ public final class AnimationID
|
||||
public static final int BLOCK_UNARMED = 424; // Same Animation as failed pickpocked
|
||||
|
||||
// NPC animations
|
||||
public static final int TZTOK_JAD_MAGIC_ATTACK = 2656;
|
||||
public static final int TZTOK_JAD_RANGE_ATTACK = 2652;
|
||||
public static final int TZTOK_JAD_MELEE_ATTACK = 2655;
|
||||
public static final int TZTOK_JAD_MAGIC_ATTACK = 2656;
|
||||
public static final int TOK_XIL_RANGE_ATTACK = 2633;
|
||||
public static final int TOK_XIL_MELEE_ATTACK = 2628;
|
||||
public static final int KET_ZEK_MELEE_ATTACK = 2644;
|
||||
public static final int KET_ZEK_MAGE_ATTACK = 2647;
|
||||
public static final int MEJ_KOT_MELEE_ATTACK = 2637;
|
||||
public static final int MEJ_KOT_HEAL_ATTACK = 2639;
|
||||
public static final int HELLHOUND_DEFENCE = 6566;
|
||||
public static final int VORKATH_WAKE_UP = 7950;
|
||||
public static final int VORKATH_DEATH = 7949;
|
||||
|
||||
@@ -24,20 +24,119 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcave;
|
||||
|
||||
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;
|
||||
import net.runelite.client.config.Range;
|
||||
import net.runelite.client.config.Stub;
|
||||
|
||||
@ConfigGroup("fightcave")
|
||||
public interface FightCaveConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "mainConfig",
|
||||
name = "Main Config",
|
||||
description = ""
|
||||
)
|
||||
default Stub mainConfig()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "waveDisplay",
|
||||
name = "Wave display",
|
||||
description = "Shows monsters that will spawn on the selected wave(s)."
|
||||
description = "Shows monsters that will spawn on the selected wave(s).",
|
||||
parent = "mainConfig"
|
||||
)
|
||||
default WaveDisplayMode waveDisplay()
|
||||
{
|
||||
return WaveDisplayMode.BOTH;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "tickTimersWidget",
|
||||
name = "Tick Timers in Prayer",
|
||||
description = "Adds an overlay to the Praayer Interface with the ticks until next attack for that prayer.",
|
||||
parent = "mainConfig"
|
||||
)
|
||||
default boolean tickTimersWidget()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "text",
|
||||
name = "Text",
|
||||
description = ""
|
||||
)
|
||||
default Stub text()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "fontStyle",
|
||||
name = "Font Style",
|
||||
description = "Plain | Bold | Italics",
|
||||
parent = "text"
|
||||
)
|
||||
default FontStyle fontStyle()
|
||||
{
|
||||
return FontStyle.BOLD;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 14,
|
||||
max = 40
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "textSize",
|
||||
name = "Text Size",
|
||||
description = "Text Size for Timers.",
|
||||
parent = "text"
|
||||
)
|
||||
default int textSize()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "shadows",
|
||||
name = "Shadows",
|
||||
description = "Adds Shadows to text.",
|
||||
parent = "text"
|
||||
)
|
||||
default boolean shadows()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.fightcave;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.awt.Color;
|
||||
import lombok.AccessLevel;
|
||||
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 FightCaveContainer
|
||||
{
|
||||
private NPC npc;
|
||||
private String npcName;
|
||||
private int npcIndex;
|
||||
private int npcSize;
|
||||
private int attackSpeed;
|
||||
private int priority;
|
||||
private ImmutableSet<Integer> animations;
|
||||
@Setter
|
||||
private int ticksUntilAttack;
|
||||
@Setter
|
||||
private Actor npcInteracting;
|
||||
@Setter
|
||||
private AttackStyle attackStyle;
|
||||
|
||||
FightCaveContainer(NPC npc, int attackSpeed)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.npcName = npc.getName();
|
||||
this.npcIndex = npc.getIndex();
|
||||
this.npcInteracting = npc.getInteracting();
|
||||
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;
|
||||
this.priority = monster.priority;
|
||||
|
||||
if (composition != null)
|
||||
{
|
||||
this.npcSize = composition.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
enum BossMonsters
|
||||
{
|
||||
TOK_XIL1(NpcID.TOKXIL_3121, AttackStyle.RANGE, ImmutableSet.of(AnimationID.TOK_XIL_RANGE_ATTACK, AnimationID.TOK_XIL_MELEE_ATTACK), 1),
|
||||
TOK_XIL2(NpcID.TOKXIL_3122, AttackStyle.RANGE, ImmutableSet.of(AnimationID.TOK_XIL_RANGE_ATTACK, AnimationID.TOK_XIL_MELEE_ATTACK), 1),
|
||||
KETZEK1(NpcID.KETZEK, AttackStyle.MAGE, ImmutableSet.of(AnimationID.KET_ZEK_MAGE_ATTACK, AnimationID.KET_ZEK_MELEE_ATTACK), 0),
|
||||
KETZEK2(NpcID.KETZEK_3126, AttackStyle.MAGE, ImmutableSet.of(AnimationID.KET_ZEK_MAGE_ATTACK, AnimationID.KET_ZEK_MELEE_ATTACK), 0),
|
||||
YTMEJKOT1(NpcID.YTMEJKOT, AttackStyle.MELEE, ImmutableSet.of(AnimationID.MEJ_KOT_HEAL_ATTACK, AnimationID.MEJ_KOT_MELEE_ATTACK), 2),
|
||||
YTMEJKOT2(NpcID.YTMEJKOT_3124, AttackStyle.MELEE, ImmutableSet.of(AnimationID.MEJ_KOT_HEAL_ATTACK, AnimationID.MEJ_KOT_MELEE_ATTACK), 2),
|
||||
TZTOKJAD1(NpcID.TZTOKJAD, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.TZTOK_JAD_MAGIC_ATTACK, AnimationID.TZTOK_JAD_RANGE_ATTACK, AnimationID.TZTOK_JAD_MELEE_ATTACK), 0),
|
||||
TZTOKJAD2(NpcID.TZTOKJAD_6506, AttackStyle.UNKNOWN, ImmutableSet.of(AnimationID.TZTOK_JAD_MAGIC_ATTACK, AnimationID.TZTOK_JAD_RANGE_ATTACK, AnimationID.TZTOK_JAD_MELEE_ATTACK), 0);
|
||||
|
||||
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;
|
||||
private final int priority;
|
||||
|
||||
static BossMonsters of(int npcID)
|
||||
{
|
||||
return idMap.get(npcID);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@AllArgsConstructor
|
||||
enum AttackStyle
|
||||
{
|
||||
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 Color color;
|
||||
private Prayer prayer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.fightcave;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.SpriteID;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
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;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
public class FightCaveOverlay extends Overlay
|
||||
{
|
||||
private FightCavePlugin plugin;
|
||||
private FightCaveConfig config;
|
||||
private Client client;
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Inject
|
||||
FightCaveOverlay(Client client, FightCavePlugin plugin, FightCaveConfig config, SpriteManager spriteManager)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.spriteManager = spriteManager;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (FightCaveContainer npc : plugin.getFightCaveContainer())
|
||||
{
|
||||
if (npc.getNpc() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
final FightCaveContainer.AttackStyle attackStyle = npc.getAttackStyle();
|
||||
|
||||
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());
|
||||
final Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, Integer.toString(ticksLeft), 0);
|
||||
|
||||
if (npc.getNpcName().equals("TzTok-Jad"))
|
||||
{
|
||||
color = (ticksLeft <= 1 || ticksLeft == 8 ? attackStyle.getColor() : Color.WHITE);
|
||||
|
||||
BufferedImage pray = getPrayerImage(npc.getAttackStyle());
|
||||
|
||||
if (pray == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
renderImageLocation(graphics, npc.getNpc().getCanvasImageLocation(ImageUtil.resizeImage(pray, 36, 36), 0), pray, 12, 30);
|
||||
}
|
||||
|
||||
OverlayUtil.renderTextLocation(graphics, ticksLeftStr, config.textSize(), font, color, canvasPoint, shadows, 0);
|
||||
}
|
||||
|
||||
if (config.tickTimersWidget())
|
||||
{
|
||||
|
||||
if (!plugin.getMageTicks().isEmpty())
|
||||
{
|
||||
widgetHandler(graphics,
|
||||
Prayer.PROTECT_FROM_MAGIC,
|
||||
plugin.getMageTicks().get(0) == 1 ? Color.WHITE : Color.CYAN,
|
||||
Integer.toString(plugin.getMageTicks().get(0)),
|
||||
config.shadows()
|
||||
);
|
||||
}
|
||||
if (!plugin.getRangedTicks().isEmpty())
|
||||
{
|
||||
widgetHandler(graphics,
|
||||
Prayer.PROTECT_FROM_MISSILES,
|
||||
plugin.getRangedTicks().get(0) == 1 ? Color.WHITE : Color.GREEN,
|
||||
Integer.toString(plugin.getRangedTicks().get(0)),
|
||||
config.shadows()
|
||||
);
|
||||
}
|
||||
if (!plugin.getMeleeTicks().isEmpty())
|
||||
{
|
||||
widgetHandler(graphics,
|
||||
Prayer.PROTECT_FROM_MELEE,
|
||||
plugin.getMeleeTicks().get(0) == 1 ? Color.WHITE : Color.RED,
|
||||
Integer.toString(plugin.getMeleeTicks().get(0)),
|
||||
config.shadows()
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void widgetHandler(Graphics2D graphics, Prayer prayer, Color color, String ticks, boolean shadows)
|
||||
{
|
||||
if (prayer != null)
|
||||
{
|
||||
Rectangle bounds = OverlayUtil.renderPrayerOverlay(graphics, client, prayer, color);
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
renderTextLocation(graphics, ticks, 16, config.fontStyle().getFont(), color, centerPoint(bounds), shadows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(FightCaveContainer.AttackStyle attackStyle)
|
||||
{
|
||||
switch (attackStyle)
|
||||
{
|
||||
case MAGE:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
case MELEE:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0);
|
||||
case RANGE:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderImageLocation(Graphics2D graphics, Point imgLoc, BufferedImage image, int xOffset, int yOffset)
|
||||
{
|
||||
int x = imgLoc.getX() + xOffset;
|
||||
int y = imgLoc.getY() - yOffset;
|
||||
|
||||
graphics.drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
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() - 3,
|
||||
canvasPoint.getY() + 6);
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() - 2,
|
||||
canvasPoint.getY() + 7);
|
||||
if (shadows)
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -27,22 +27,23 @@ package net.runelite.client.plugins.fightcave;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
@@ -50,6 +51,7 @@ 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;
|
||||
@@ -64,59 +66,16 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
enabledByDefault = false
|
||||
)
|
||||
|
||||
@Slf4j
|
||||
public class FightCavePlugin extends Plugin
|
||||
{
|
||||
static final int MAX_WAVE = 63;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
static final List<EnumMap<WaveMonster, Integer>> WAVES = new ArrayList<>();
|
||||
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;
|
||||
|
||||
@Inject
|
||||
private JadOverlay jadOverlay;
|
||||
|
||||
@Inject
|
||||
private TimersOverlay timersOverlay;
|
||||
|
||||
@Inject
|
||||
private ConfigManager externalConfig;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> Rangers = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> Magers = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> Meleers = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> Drainers = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Map<NPC, NPCContainer> Ignore = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Nullable
|
||||
private JadAttack attack;
|
||||
|
||||
private NPC jad;
|
||||
|
||||
static
|
||||
{
|
||||
final WaveMonster[] waveMonsters = WaveMonster.values();
|
||||
@@ -157,6 +116,36 @@ public class FightCavePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
@Inject
|
||||
private NPCManager npcManager;
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
@Inject
|
||||
private WaveOverlay waveOverlay;
|
||||
@Inject
|
||||
private FightCaveOverlay fightCaveOverlay;
|
||||
@Inject
|
||||
private FightCaveConfig config;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Set<FightCaveContainer> fightCaveContainer = new HashSet<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int currentWave = -1;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean validRegion;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<Integer> mageTicks = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<Integer> rangedTicks = new ArrayList<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private List<Integer> meleeTicks = new ArrayList<>();
|
||||
|
||||
static String formatMonsterQuantity(final WaveMonster monster, final int quantity)
|
||||
{
|
||||
return String.format("%dx %s", quantity, monster);
|
||||
}
|
||||
|
||||
@Provides
|
||||
FightCaveConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -166,21 +155,41 @@ public class FightCavePlugin extends Plugin
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
overlayManager.add(waveOverlay);
|
||||
overlayManager.add(jadOverlay);
|
||||
overlayManager.add(timersOverlay);
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
if (regionCheck())
|
||||
{
|
||||
validRegion = true;
|
||||
overlayManager.add(waveOverlay);
|
||||
overlayManager.add(fightCaveOverlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
overlayManager.remove(waveOverlay);
|
||||
overlayManager.remove(fightCaveOverlay);
|
||||
currentWave = -1;
|
||||
overlayManager.remove(timersOverlay);
|
||||
overlayManager.remove(jadOverlay);
|
||||
jad = null;
|
||||
attack = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (!validRegion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Matcher waveMatcher = WAVE_PATTERN.matcher(event.getMessage());
|
||||
|
||||
if (event.getType() != ChatMessageType.GAMEMESSAGE || !waveMatcher.matches())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentWave = Integer.parseInt(waveMatcher.group(1));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -191,98 +200,43 @@ public class FightCavePlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inFightCave())
|
||||
if (regionCheck())
|
||||
{
|
||||
currentWave = -1;
|
||||
validRegion = true;
|
||||
overlayManager.add(waveOverlay);
|
||||
overlayManager.add(fightCaveOverlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
validRegion = false;
|
||||
overlayManager.remove(fightCaveOverlay);
|
||||
overlayManager.remove(fightCaveOverlay);
|
||||
}
|
||||
|
||||
fightCaveContainer.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick Event)
|
||||
{
|
||||
for (NPCContainer ranger : getRangers().values())
|
||||
{
|
||||
ranger.setTicksUntilAttack(ranger.getTicksUntilAttack() - 1);
|
||||
if (ranger.getNpc().getAnimation() == 2633)
|
||||
{
|
||||
if (ranger.getTicksUntilAttack() < 1)
|
||||
{
|
||||
ranger.setTicksUntilAttack(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (NPCContainer meleer : getMeleers().values())
|
||||
{
|
||||
meleer.setTicksUntilAttack(meleer.getTicksUntilAttack() - 1);
|
||||
if (meleer.getNpc().getAnimation() == 2637 || meleer.getNpc().getAnimation() == 2639)
|
||||
{
|
||||
if (meleer.getTicksUntilAttack() < 1)
|
||||
{
|
||||
meleer.setTicksUntilAttack(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (NPCContainer mager : getMagers().values())
|
||||
{
|
||||
mager.setTicksUntilAttack(mager.getTicksUntilAttack() - 1);
|
||||
if (mager.getNpc().getAnimation() == 2647)
|
||||
{
|
||||
if (mager.getTicksUntilAttack() < 1)
|
||||
{
|
||||
mager.setTicksUntilAttack(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
if (!validRegion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NpcID.TZKIH_3116:
|
||||
case NpcID.TZKIH_3117:
|
||||
Drainers.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.TZKEK_3118:
|
||||
case NpcID.TZKEK_3119:
|
||||
case NpcID.TZKEK_3120:
|
||||
Ignore.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.TOKXIL_3121:
|
||||
case NpcID.TOKXIL_3122:
|
||||
Rangers.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.YTMEJKOT:
|
||||
case NpcID.YTMEJKOT_3124:
|
||||
Meleers.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.KETZEK:
|
||||
case NpcID.KETZEK_3126:
|
||||
Magers.put(npc, new NPCContainer(npc));
|
||||
break;
|
||||
case NpcID.TZTOKJAD:
|
||||
case NpcID.TZTOKJAD_6506:
|
||||
jad = npc;
|
||||
fightCaveContainer.add(new FightCaveContainer(npc, npcManager.getAttackSpeed(npc.getId())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -290,55 +244,106 @@ public class FightCavePlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
if (Rangers.remove(event.getNpc()) != null && Rangers.isEmpty())
|
||||
{
|
||||
Rangers.clear();
|
||||
}
|
||||
if (Meleers.remove(event.getNpc()) != null && Meleers.isEmpty())
|
||||
{
|
||||
Meleers.clear();
|
||||
}
|
||||
if (Magers.remove(event.getNpc()) != null && Magers.isEmpty())
|
||||
{
|
||||
Magers.clear();
|
||||
}
|
||||
if (Drainers.remove(event.getNpc()) != null && Drainers.isEmpty())
|
||||
{
|
||||
Drainers.clear();
|
||||
}
|
||||
if (Ignore.remove(event.getNpc()) != null && Ignore.isEmpty())
|
||||
{
|
||||
Ignore.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged event)
|
||||
{
|
||||
if (event.getActor() != jad)
|
||||
if (!validRegion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (jad.getAnimation() == JadAttack.MAGIC.getAnimation())
|
||||
{
|
||||
attack = JadAttack.MAGIC;
|
||||
}
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
else if (jad.getAnimation() == JadAttack.RANGE.getAnimation())
|
||||
switch (npc.getId())
|
||||
{
|
||||
attack = JadAttack.RANGE;
|
||||
case NpcID.TOKXIL_3121:
|
||||
case NpcID.TOKXIL_3122:
|
||||
case NpcID.YTMEJKOT:
|
||||
case NpcID.YTMEJKOT_3124:
|
||||
case NpcID.KETZEK:
|
||||
case NpcID.KETZEK_3126:
|
||||
case NpcID.TZTOKJAD:
|
||||
case NpcID.TZTOKJAD_6506:
|
||||
fightCaveContainer.removeIf(c -> c.getNpc() == npc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean inFightCave()
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick Event)
|
||||
{
|
||||
if (!validRegion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mageTicks.clear();
|
||||
rangedTicks.clear();
|
||||
meleeTicks.clear();
|
||||
|
||||
for (FightCaveContainer npc : fightCaveContainer)
|
||||
{
|
||||
if (npc.getTicksUntilAttack() >= 0)
|
||||
{
|
||||
npc.setTicksUntilAttack(npc.getTicksUntilAttack() - 1);
|
||||
}
|
||||
|
||||
for (int anims : npc.getAnimations())
|
||||
{
|
||||
if (anims == npc.getNpc().getAnimation())
|
||||
{
|
||||
if (npc.getTicksUntilAttack() < 1)
|
||||
{
|
||||
npc.setTicksUntilAttack(npc.getAttackSpeed());
|
||||
}
|
||||
|
||||
switch (anims)
|
||||
{
|
||||
case AnimationID.TZTOK_JAD_RANGE_ATTACK:
|
||||
npc.setAttackStyle(FightCaveContainer.AttackStyle.RANGE);
|
||||
break;
|
||||
case AnimationID.TZTOK_JAD_MAGIC_ATTACK:
|
||||
npc.setAttackStyle(FightCaveContainer.AttackStyle.MAGE);
|
||||
break;
|
||||
case AnimationID.TZTOK_JAD_MELEE_ATTACK:
|
||||
npc.setAttackStyle(FightCaveContainer.AttackStyle.MELEE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (npc.getNpcName().equals("TzTok-Jad"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (npc.getAttackStyle())
|
||||
{
|
||||
case RANGE:
|
||||
if (npc.getTicksUntilAttack() > 0)
|
||||
{
|
||||
rangedTicks.add(npc.getTicksUntilAttack());
|
||||
}
|
||||
break;
|
||||
case MELEE:
|
||||
if (npc.getTicksUntilAttack() > 0)
|
||||
{
|
||||
meleeTicks.add(npc.getTicksUntilAttack());
|
||||
}
|
||||
break;
|
||||
case MAGE:
|
||||
if (npc.getTicksUntilAttack() > 0)
|
||||
{
|
||||
mageTicks.add(npc.getTicksUntilAttack());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(mageTicks);
|
||||
Collections.sort(rangedTicks);
|
||||
Collections.sort(meleeTicks);
|
||||
}
|
||||
|
||||
private boolean regionCheck()
|
||||
{
|
||||
return ArrayUtils.contains(client.getMapRegions(), FIGHT_CAVE_REGION);
|
||||
}
|
||||
|
||||
static String formatMonsterQuantity(final WaveMonster monster, final int quantity)
|
||||
{
|
||||
return String.format("%dx %s", quantity, monster);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.fightcave;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* 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.fightcave;
|
||||
|
||||
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 JadOverlay extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
|
||||
private final Client client;
|
||||
private final FightCavePlugin plugin;
|
||||
private final SpriteManager spriteManager;
|
||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private JadOverlay(Client client, FightCavePlugin 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);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Woox <https://github.com/wooxsolo>
|
||||
* 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.fightcave;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
|
||||
class NPCContainer
|
||||
{
|
||||
|
||||
@Getter
|
||||
private NPC npc;
|
||||
|
||||
@Getter
|
||||
private int npcIndex;
|
||||
|
||||
@Getter
|
||||
private String npcName;
|
||||
|
||||
@Getter
|
||||
private int npcSize;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private int TicksUntilAttack;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private int npcSpeed;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private Actor npcInteracting;
|
||||
|
||||
|
||||
NPCContainer(NPC npc)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.npcName = npc.getName();
|
||||
this.npcIndex = npc.getIndex();
|
||||
this.npcInteracting = npc.getInteracting();
|
||||
this.npcSpeed = 0;
|
||||
this.TicksUntilAttack = 0;
|
||||
final NPCDefinition composition = npc.getTransformedDefinition();
|
||||
|
||||
if (composition != null)
|
||||
{
|
||||
this.npcSize = composition.getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,184 +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.fightcave;
|
||||
|
||||
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 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.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 TimersOverlay extends Overlay
|
||||
{
|
||||
private FightCavePlugin plugin;
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
TimersOverlay(FightCavePlugin plugin, Client client)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (NPCContainer npc : plugin.getDrainers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.RED, 255, 20);
|
||||
String str = "drainer";
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, str, 0);
|
||||
renderTextLocation(graphics, str, 12, Color.WHITE, canvasPoint);
|
||||
}
|
||||
|
||||
for (NPCContainer npc : plugin.getIgnore().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.BLACK, 50, 5);
|
||||
String str = "ignore";
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, str, 0);
|
||||
renderTextLocation(graphics, str, 10, Color.WHITE, canvasPoint);
|
||||
}
|
||||
|
||||
Color tickcolor;
|
||||
|
||||
for (NPCContainer npc : plugin.getRangers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.GREEN, 100, 10);
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = Color.GREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = Color.WHITE;
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
|
||||
for (NPCContainer npc : plugin.getMagers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.CYAN, 100, 10);
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = Color.CYAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tickcolor = Color.WHITE;
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
|
||||
for (NPCContainer npc : plugin.getMeleers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.RED, 100, 10);
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = Color.RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tickcolor = Color.WHITE;
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, 32, 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, Color fontColor, Point canvasPoint)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY());
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 1);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,12 @@ 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);
|
||||
TZ_KIH("Drainer", 22),
|
||||
TZ_KEK("Blob", 45),
|
||||
TOK_XIL("Range", 90),
|
||||
YT_MEJKOT("Melee", 180),
|
||||
KET_ZEK("Mage", 360),
|
||||
TZKOK_JAD("Jad", 702);
|
||||
|
||||
private final String name;
|
||||
private final int level;
|
||||
|
||||
@@ -37,8 +37,8 @@ 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.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
|
||||
class WaveOverlay extends Overlay
|
||||
{
|
||||
@@ -46,22 +46,38 @@ class WaveOverlay extends Overlay
|
||||
|
||||
private final FightCaveConfig config;
|
||||
private final FightCavePlugin plugin;
|
||||
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private WaveOverlay(FightCaveConfig config, FightCavePlugin plugin)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
this.config = config;
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.TOP_RIGHT);
|
||||
}
|
||||
|
||||
private static Collection<String> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<WaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<String> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<WaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final WaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final String line = FightCavePlugin.formatMonsterQuantity(monster, quantity);
|
||||
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.inFightCave()
|
||||
|| plugin.getCurrentWave() < 0)
|
||||
if (!plugin.isValidRegion() || plugin.getCurrentWave() < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -108,26 +124,8 @@ class WaveOverlay extends Overlay
|
||||
}
|
||||
|
||||
if (!tableComponent.isEmpty())
|
||||
{
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<String> buildWaveLines(final Map<WaveMonster, Integer> wave)
|
||||
{
|
||||
final List<Map.Entry<WaveMonster, Integer>> monsters = new ArrayList<>(wave.entrySet());
|
||||
monsters.sort(Map.Entry.comparingByKey());
|
||||
final List<String> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<WaveMonster, Integer> monsterEntry : monsters)
|
||||
{
|
||||
final WaveMonster monster = monsterEntry.getKey();
|
||||
final int quantity = monsterEntry.getValue();
|
||||
final String line = FightCavePlugin.formatMonsterQuantity(monster, quantity);
|
||||
|
||||
outputLines.add(line);
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user