Merge branch 'master' of https://github.com/runelite-extended/runelite
This commit is contained in:
@@ -28,11 +28,12 @@ allprojects {
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
group = 'net.runelite'
|
||||
version = '1.5.30-SNAPSHOT'
|
||||
version = '1.5.31-SNAPSHOT'
|
||||
|
||||
ext {
|
||||
rsversion = 181
|
||||
cacheversion = 165
|
||||
plusVersion = '2.1.2.0'
|
||||
|
||||
gitCommit = localGitCommit
|
||||
gitCommitShort = localGitCommitShort
|
||||
|
||||
@@ -102,11 +102,12 @@ public class ProjectileID
|
||||
public static final int HYDRA_LIGHTNING_2 = 1665;
|
||||
public static final int DRAKE_BREATH = 1637;
|
||||
|
||||
public static final int HUNLEFF_MAGE_ATTACK = 1707;
|
||||
public static final int HUNLEFF_CORRUPTED_MAGE_ATTACK = 1708;
|
||||
public static final int HUNLEFF_RANGE_ATTACK = 1711;
|
||||
public static final int HUNLEFF_CORRUPTED_RANGE_ATTACK = 1712;
|
||||
|
||||
public static final int HUNLLEF_MAGE_ATTACK = 1707;
|
||||
public static final int HUNLLEF_CORRUPTED_MAGE_ATTACK = 1708;
|
||||
public static final int HUNLLEF_RANGE_ATTACK = 1711;
|
||||
public static final int HUNLLEF_CORRUPTED_RANGE_ATTACK = 1712;
|
||||
public static final int HUNLLEF_PRAYER_ATTACK = 1713;
|
||||
public static final int HUNLLEF_CORRUPTED_PRAYER_ATTACK = 1714;
|
||||
|
||||
public static final int ZALCANO_PROJECTILE = 1728;
|
||||
|
||||
}
|
||||
|
||||
@@ -692,7 +692,12 @@ public enum Varbits
|
||||
/**
|
||||
* 1 is true, 0 is false.
|
||||
*/
|
||||
GAUNTLET_FINAL_ROOM_ENTERED(9177);
|
||||
GAUNTLET_FINAL_ROOM_ENTERED(9177),
|
||||
|
||||
/**
|
||||
* 1 is true, 0 is false.
|
||||
*/
|
||||
GAUNTLET_ENTERED(9178);
|
||||
|
||||
/**
|
||||
* The raw varbit ID.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '5.1.0'
|
||||
id 'java'
|
||||
@@ -60,6 +63,23 @@ dependencies {
|
||||
compileOnly group: 'net.runelite', name: 'orange-extensions', version: '1.0'
|
||||
}
|
||||
|
||||
static def getDate() {
|
||||
return new SimpleDateFormat("MM-dd-yyyy", Locale.forLanguageTag("en-US")).format(new Date())
|
||||
}
|
||||
|
||||
def buildDate = getDate()
|
||||
|
||||
processResources {
|
||||
from file("src/main/resources/runelite.plus.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"project.version": project.version,
|
||||
"rs.version": rsversion.toString(),
|
||||
"runelite.plus.version": plusVersion.toString(),
|
||||
"runelite.plus.builddate": buildDate.toString()
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(AbstractArchiveTask) {
|
||||
preserveFileTimestamps = false
|
||||
reproducibleFileOrder = true
|
||||
|
||||
@@ -24,18 +24,29 @@
|
||||
*/
|
||||
package net.runelite.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.config.RuneLitePlusConfig;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class RuneLiteProperties
|
||||
{
|
||||
private static final String DISCORD_APP_ID_PLUS = "560644885250572289";
|
||||
private static final String RUNELITE_TITLE = "runelite.plus.title";
|
||||
private static final String RUNELITE_VERSION = "runelite.version";
|
||||
private static final String RUNELITE_PLUS_VERSION = "runelite.plus.version";
|
||||
private static final String RUNELITE_PLUS_DATE = "runelite.plus.builddate";
|
||||
private static final String RUNESCAPE_VERSION = "runescape.version";
|
||||
private static final String DISCORD_APP_ID = "runelite.plus.discord.appid";
|
||||
private static final String DISCORD_INVITE = "runelite.discord.invite";
|
||||
private static final String GITHUB_LINK = "runelite.github.link";
|
||||
private static final String WIKI_LINK = "runelite.wiki.link";
|
||||
private static final String PATREON_LINK = "runelite.patreon.link";
|
||||
private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
|
||||
|
||||
private final Properties properties = new Properties();
|
||||
|
||||
@@ -45,6 +56,15 @@ public class RuneLiteProperties
|
||||
public RuneLiteProperties(final RuneLitePlusConfig runeLiteConfig)
|
||||
{
|
||||
this.runeLitePlusConfig = runeLiteConfig;
|
||||
|
||||
try (InputStream in = getClass().getResourceAsStream("/runelite.plus.properties"))
|
||||
{
|
||||
properties.load(in);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("unable to load propertries", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public RuneLiteProperties()
|
||||
@@ -54,7 +74,7 @@ public class RuneLiteProperties
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
final StringBuilder sb = new StringBuilder("RuneLitePlus");
|
||||
final StringBuilder sb = new StringBuilder(properties.getProperty(RUNELITE_TITLE));
|
||||
String proxy;
|
||||
if ((proxy = System.getProperty("socksProxyHost")) != null)
|
||||
{
|
||||
@@ -65,41 +85,46 @@ public class RuneLiteProperties
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return RuneLiteAPI.getVersion();
|
||||
return properties.getProperty(RUNELITE_VERSION);
|
||||
}
|
||||
|
||||
public String getPlusVersion()
|
||||
{
|
||||
return RuneLite.PLUS_VERSION;
|
||||
return properties.getProperty(RUNELITE_PLUS_VERSION);
|
||||
}
|
||||
|
||||
public String getPlusDate()
|
||||
{
|
||||
return properties.getProperty(RUNELITE_PLUS_DATE);
|
||||
}
|
||||
|
||||
public String getRunescapeVersion()
|
||||
{
|
||||
return "" + RuneLiteAPI.getRsVersion();
|
||||
return properties.getProperty(RUNESCAPE_VERSION);
|
||||
}
|
||||
|
||||
public String getDiscordAppId()
|
||||
{
|
||||
return DISCORD_APP_ID_PLUS;
|
||||
return properties.getProperty(DISCORD_APP_ID);
|
||||
}
|
||||
|
||||
public String getDiscordInvite()
|
||||
{
|
||||
return "https://discord.gg/HN5gf3m";
|
||||
return properties.getProperty(DISCORD_INVITE);
|
||||
}
|
||||
|
||||
public String getGithubLink()
|
||||
{
|
||||
return "https://github.com/runelite-extended/runelite";
|
||||
return properties.getProperty(GITHUB_LINK);
|
||||
}
|
||||
|
||||
public String getWikiLink()
|
||||
{
|
||||
return "https://github.com/runelite-extended/runelite/wiki";
|
||||
return properties.getProperty(WIKI_LINK);
|
||||
}
|
||||
|
||||
public String getPatreonLink()
|
||||
{
|
||||
return "https://www.patreon.com/RuneLitePlus";
|
||||
return properties.getProperty(PATREON_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,13 +37,13 @@ import net.runelite.api.Client;
|
||||
import net.runelite.api.DecorativeObject;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GroundObject;
|
||||
import net.runelite.api.TileItemPile;
|
||||
import net.runelite.api.MainBufferProvider;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.TileItemPile;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
@@ -968,7 +968,7 @@ public class ModelOutlineRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
public void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
{
|
||||
LocalPoint lp = gameObject.getLocalLocation();
|
||||
if (lp != null)
|
||||
@@ -979,7 +979,7 @@ public class ModelOutlineRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
public void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor)
|
||||
{
|
||||
LocalPoint lp = groundObject.getLocalLocation();
|
||||
if (lp != null)
|
||||
|
||||
@@ -39,7 +39,7 @@ enum Boss
|
||||
KREEARRA(NpcID.KREEARRA, 90, ChronoUnit.SECONDS, ItemID.PET_KREEARRA),
|
||||
COMMANDER_ZILYANA(NpcID.COMMANDER_ZILYANA, 90, ChronoUnit.SECONDS, ItemID.PET_ZILYANA),
|
||||
CALLISTO(NpcID.CALLISTO_6609, 30, ChronoUnit.SECONDS, ItemID.CALLISTO_CUB),
|
||||
CHAOS_ELEMENTAL(NpcID.CHAOS_ELEMENTAL, 150, ChronoUnit.SECONDS, ItemID.PET_CHAOS_ELEMENTAL),
|
||||
CHAOS_ELEMENTAL(NpcID.CHAOS_ELEMENTAL, 60, ChronoUnit.SECONDS, ItemID.PET_CHAOS_ELEMENTAL),
|
||||
CHAOS_FANATIC(NpcID.CHAOS_FANATIC, 30, ChronoUnit.SECONDS, ItemID.ANCIENT_STAFF),
|
||||
CRAZY_ARCHAEOLOGIST(NpcID.CRAZY_ARCHAEOLOGIST, 30, ChronoUnit.SECONDS, ItemID.FEDORA),
|
||||
KING_BLACK_DRAGON(NpcID.KING_BLACK_DRAGON, 9, ChronoUnit.SECONDS, ItemID.PRINCE_BLACK_DRAGON),
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* THIS SOFTWARE WRITTEN BY A KEYBOARD-WIELDING MONKEY BOI
|
||||
* No rights reserved. Use, redistribute, and modify at your own discretion,
|
||||
* and in accordance with Yagex and RuneLite guidelines.
|
||||
* However, aforementioned monkey would prefer if you don't sell this plugin for profit.
|
||||
* Good luck on your raids!
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Range;
|
||||
import net.runelite.client.config.Stub;
|
||||
|
||||
@ConfigGroup("Gauntlet")
|
||||
|
||||
public interface GauntletConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "resources",
|
||||
name = "Resources",
|
||||
description = ""
|
||||
)
|
||||
default Stub resources()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "highlightResources",
|
||||
name = "Highlight Resources",
|
||||
description = "Highlights all the resources in each room with a color.",
|
||||
parent = "resources"
|
||||
)
|
||||
default boolean highlightResources()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "highlightResourcesColor",
|
||||
name = "Highlight Color",
|
||||
description = "Highlights all the resources in each room with this color.",
|
||||
parent = "resources",
|
||||
hidden = true,
|
||||
unhide = "highlightResources"
|
||||
)
|
||||
default Color highlightResourcesColor()
|
||||
{
|
||||
return Color.YELLOW;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "highlightResourcesIcons",
|
||||
name = "Highlight Resources with an Icon",
|
||||
description = "Highlights all the icons in each room with an icon.",
|
||||
parent = "resources",
|
||||
hidden = true,
|
||||
unhide = "highlightResources"
|
||||
)
|
||||
default boolean highlightResourcesIcons()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 1,
|
||||
max = 50
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "resourceIconSize",
|
||||
name = "Resource Icon Size",
|
||||
description = " change the size of resource icons.",
|
||||
hidden = true,
|
||||
unhide = "highlightResources",
|
||||
parent = "resources"
|
||||
)
|
||||
default int resourceIconSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "boss",
|
||||
name = "Boss",
|
||||
description = ""
|
||||
)
|
||||
default Stub boss()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "countBossAttacks",
|
||||
name = "Count Boss Attacks",
|
||||
description = "Count the attacks until the boss switches their style.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean countBossAttacks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "countPlayerAttacks",
|
||||
name = "Count Player Attacks",
|
||||
description = "Count the player attacks until the boss switches their prayer.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean countPlayerAttacks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "highlightWidget",
|
||||
name = "Highlight Correct Prayer",
|
||||
description = "Highlights correct prayer in your prayer book.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean highlightWidget()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "flashOnWrongAttack",
|
||||
name = "Flash on Wrong Attack",
|
||||
description = "This will flash your screen if you attack with the wrong stlye.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean flashOnWrongAttack()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "uniquePrayerAudio",
|
||||
name = "Unique Prayer Audio",
|
||||
description = "Plays a unique sound whenever the boss is about to shut down your prayer.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean uniquePrayerAudio()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "uniquePrayerVisual",
|
||||
name = "Unique Prayer Visual",
|
||||
description = "Prayer attacks will have a unique overlay visual.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean uniquePrayerVisual()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "uniqueAttackVisual",
|
||||
name = "Unique Magic & Range Visuals",
|
||||
description = "Magic and Range attacks will have a unique overlay visual.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean uniqueAttackVisual()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "overlayBoss",
|
||||
name = "Overlay the Boss (Color)",
|
||||
description = "Overlay the boss with an color denoting it's current attack style.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean overlayBoss()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "overlayBossPrayer",
|
||||
name = "Overlay the Boss (Icon)",
|
||||
description = "Overlay the boss with an icon denoting it's current attack style.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean overlayBossPrayer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "overlayTornadoes",
|
||||
name = "Show Tornado Decay",
|
||||
description = "Display the amount of ticks left until the tornadoes decay.",
|
||||
parent = "boss"
|
||||
)
|
||||
default boolean overlayTornadoes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Range(
|
||||
min = 1,
|
||||
max = 50
|
||||
)
|
||||
@ConfigItem(
|
||||
position = 15,
|
||||
keyName = "projectileIconSize",
|
||||
name = "Boss Projectile Icon Size",
|
||||
description = " change the size of Projectile icons.",
|
||||
parent = "boss"
|
||||
)
|
||||
default int projectileIconSize()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 16,
|
||||
keyName = "timer",
|
||||
name = "Timer",
|
||||
description = ""
|
||||
)
|
||||
default Stub timer()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 17,
|
||||
keyName = "displayTimerWidget",
|
||||
name = "Show Custom Timer (Widget)",
|
||||
description = "Display a timer widget that tracks your gauntlet progress.",
|
||||
parent = "timer"
|
||||
)
|
||||
default boolean displayTimerWidget()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 18,
|
||||
keyName = "displayTimerChat",
|
||||
name = "Show Custom Timer (Chat)",
|
||||
description = "Display a chat message that tracks your gauntlet progress.",
|
||||
parent = "timer"
|
||||
)
|
||||
default boolean displayTimerChat()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class GauntletCounter extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
private final GauntletPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
GauntletCounter(final GauntletPlugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (plugin.getHunllef() == null || !plugin.isInRoom())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Hunllef")
|
||||
.color(Color.pink)
|
||||
.build());
|
||||
|
||||
Color color = plugin.getPlayerAttacks() == 1 ? Color.RED : Color.WHITE;
|
||||
final String pHits = ColorUtil.prependColorTag(Integer.toString(plugin.getPlayerAttacks()), color);
|
||||
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
tableComponent.addRow("Hunllef Hits: ", Integer.toString(plugin.getAttacks()));
|
||||
tableComponent.addRow("Player Hits Left: ", pHits);
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -1,133 +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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
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.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class GauntletInfoBox extends Overlay
|
||||
{
|
||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||
private final Client client;
|
||||
private final GauntletPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
private final SpriteManager spriteManager;
|
||||
|
||||
@Inject
|
||||
GauntletInfoBox(final @Nullable Client client, final GauntletPlugin plugin, final SpriteManager spriteManager)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.spriteManager = spriteManager;
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (plugin.getHunllef() == null || !plugin.isInRoom())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Prayer prayer = plugin.getNextPrayer();
|
||||
|
||||
if (prayer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
InfoBoxComponent prayComponent = new InfoBoxComponent();
|
||||
BufferedImage prayImg = scaleImg(getPrayerImage(prayer));
|
||||
prayComponent.setImage(prayImg);
|
||||
prayComponent.setColor(Color.WHITE);
|
||||
prayComponent.setBackgroundColor(client.isPrayerActive(prayer)
|
||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||
prayComponent.setPreferredSize(new Dimension(40, 40));
|
||||
panelComponent.getChildren().add(prayComponent);
|
||||
panelComponent.setPreferredSize(new Dimension(40, 40));
|
||||
panelComponent.setBorder(new Rectangle(0, 0, 0, 0));
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private BufferedImage getPrayerImage(Prayer prayer)
|
||||
{
|
||||
switch (prayer)
|
||||
{
|
||||
case PROTECT_FROM_MAGIC:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||
case PROTECT_FROM_MELEE:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0);
|
||||
case PROTECT_FROM_MISSILES:
|
||||
return spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BufferedImage scaleImg(final BufferedImage img)
|
||||
{
|
||||
if (img == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final double width = img.getWidth(null);
|
||||
final double height = img.getHeight(null);
|
||||
final double size = 36; // Limit size to 2 as that is minimum size not causing breakage
|
||||
final double scalex = size / width;
|
||||
final double scaley = size / height;
|
||||
final double scale = Math.min(scalex, scaley);
|
||||
final int newWidth = (int) (width * scale);
|
||||
final int newHeight = (int) (height * scale);
|
||||
final BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics g = scaledImage.createGraphics();
|
||||
g.drawImage(img, 0, 0, newWidth, newHeight, null);
|
||||
g.dispose();
|
||||
return scaledImage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (c) 2019, kThisIsCvpv <https://github.com/kThisIsCvpv>
|
||||
* 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.gauntlet;
|
||||
|
||||
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.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Model;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.model.Jarvis;
|
||||
import net.runelite.api.model.Vertex;
|
||||
import net.runelite.client.graphics.ModelOutlineRenderer;
|
||||
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 static net.runelite.client.util.ImageUtil.resizeImage;
|
||||
|
||||
public class GauntletOverlay extends Overlay
|
||||
{
|
||||
private static final Color FLASH_COLOR = new Color(255, 0, 0, 70);
|
||||
private static final int MAX_DISTANCE = 2400;
|
||||
private final Client client;
|
||||
private final GauntletPlugin plugin;
|
||||
private final ModelOutlineRenderer outlineRenderer;
|
||||
private int timeout;
|
||||
|
||||
@Inject
|
||||
private GauntletOverlay(Client client, GauntletPlugin plugin, ModelOutlineRenderer outlineRenderer)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.outlineRenderer = outlineRenderer;
|
||||
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
// Save resources. There's nothing to render if the user is not in a raid.
|
||||
|
||||
if (!plugin.startedGauntlet())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (plugin.fightingBoss())
|
||||
{
|
||||
// This section handles the visuals when the player is in the boss room.
|
||||
// This section handles the projectile overlays.
|
||||
Set<Missiles> projectiles = plugin.getProjectiles();
|
||||
projectiles.forEach(projectile ->
|
||||
{
|
||||
BufferedImage icon = resizeImage(projectile.getImage(), plugin.getProjectileIconSize(), plugin.getProjectileIconSize());
|
||||
Color color = projectile.getColor();
|
||||
|
||||
Polygon polygon = boundProjectile(projectile.getProjectile());
|
||||
if (polygon == null)
|
||||
{
|
||||
int x = (int) projectile.getProjectile().getX();
|
||||
int y = (int) projectile.getProjectile().getY();
|
||||
|
||||
LocalPoint point = new LocalPoint(x, y);
|
||||
Point loc = Perspective.getCanvasImageLocation(client, point, icon, -(int) projectile.getProjectile().getZ());
|
||||
|
||||
if (loc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.isUniqueAttackVisual())
|
||||
{
|
||||
graphics.drawImage(icon, loc.getX(), loc.getY(), null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.setColor(color);
|
||||
graphics.draw(polygon);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 50));
|
||||
graphics.fill(polygon);
|
||||
if (plugin.isUniqueAttackVisual())
|
||||
{
|
||||
Rectangle bounds = polygon.getBounds();
|
||||
int x = (int) bounds.getCenterX() - (icon.getWidth() / 2);
|
||||
int y = (int) bounds.getCenterY() - (icon.getHeight() / 2);
|
||||
graphics.drawImage(icon, x, y, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
projectiles.removeIf(proj -> proj.getProjectile().getRemainingCycles() <= 0);
|
||||
|
||||
plugin.getTornadoes().forEach(tornado ->
|
||||
{
|
||||
if (plugin.isOverlayTornadoes())
|
||||
{
|
||||
if (tornado.getTimeLeft() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String textOverlay = Integer.toString(tornado.getTimeLeft());
|
||||
final Point textLoc = Perspective.getCanvasTextLocation(client, graphics, tornado.getNpc().getLocalLocation(), textOverlay, 0);
|
||||
final LocalPoint lp = LocalPoint.fromWorld(client, tornado.getNpc().getWorldLocation());
|
||||
|
||||
if (lp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Polygon tilePoly = Perspective.getCanvasTilePoly(client, lp);
|
||||
OverlayUtil.renderPolygon(graphics, tilePoly, Color.YELLOW);
|
||||
|
||||
if (textLoc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Font oldFont = graphics.getFont();
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, 20));
|
||||
Point pointShadow = new Point(textLoc.getX() + 1, textLoc.getY() + 1);
|
||||
OverlayUtil.renderTextLocation(graphics, pointShadow, textOverlay, Color.BLACK);
|
||||
OverlayUtil.renderTextLocation(graphics, textLoc, textOverlay, Color.YELLOW);
|
||||
graphics.setFont(oldFont);
|
||||
}
|
||||
});
|
||||
|
||||
if (plugin.getHunllef() != null)
|
||||
{
|
||||
final Hunllef hunllef = plugin.getHunllef();
|
||||
final Hunllef.BossAttackPhase phase = hunllef.getCurrentPhase();
|
||||
final NPC boss = hunllef.getNpc();
|
||||
final LocalPoint point = boss.getLocalLocation();
|
||||
|
||||
if (plugin.isFlash())
|
||||
{
|
||||
final Color flash = graphics.getColor();
|
||||
graphics.setColor(FLASH_COLOR);
|
||||
graphics.fill(new Rectangle(client.getCanvas().getSize()));
|
||||
graphics.setColor(flash);
|
||||
timeout++;
|
||||
if (timeout >= 15)
|
||||
{
|
||||
timeout = 0;
|
||||
plugin.setFlash(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isOverlayBoss())
|
||||
{
|
||||
Polygon polygon = boss.getConvexHull();
|
||||
|
||||
if (polygon == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (phase.getPrayer() != null && !client.isPrayerActive(phase.getPrayer()))
|
||||
{
|
||||
Color color = phase.getColor();
|
||||
outlineRenderer.drawOutline(boss, 12, color, new Color(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isOverlayBossPrayer())
|
||||
{
|
||||
BufferedImage attackIcon = null;
|
||||
|
||||
switch (phase)
|
||||
{
|
||||
case MAGIC:
|
||||
attackIcon = resizeImage(hunllef.getMage(), plugin.getProjectileIconSize(), plugin.getProjectileIconSize());
|
||||
break;
|
||||
case RANGE:
|
||||
attackIcon = resizeImage(hunllef.getRange(), plugin.getProjectileIconSize(), plugin.getProjectileIconSize());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (attackIcon == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Point imageLoc = Perspective.getCanvasImageLocation(client, point, attackIcon, boss.getLogicalHeight() / 2);
|
||||
|
||||
if (imageLoc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
graphics.drawImage(attackIcon, imageLoc.getX(), imageLoc.getY(), null);
|
||||
}
|
||||
|
||||
if (plugin.isHighlightWidget())
|
||||
{
|
||||
if (phase.getPrayer() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Rectangle bounds = OverlayUtil.renderPrayerOverlay(graphics, client, phase.getPrayer(), phase.getColor());
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
final Color color = hunllef.getTicksUntilAttack() == 1 ? Color.WHITE : phase.getColor();
|
||||
renderTextLocation(graphics, Integer.toString(hunllef.getTicksUntilAttack()), 16, Font.BOLD, color, centerPoint(bounds), false);
|
||||
}
|
||||
}
|
||||
|
||||
// This section handles any text overlays.
|
||||
String textOverlay = "";
|
||||
|
||||
// Handles the counter for the boss.
|
||||
if (plugin.isCountBossAttacks())
|
||||
{
|
||||
textOverlay = Integer.toString(hunllef.getBossAttacks());
|
||||
}
|
||||
|
||||
// Handles the counter for the player.
|
||||
if (plugin.isCountPlayerAttacks())
|
||||
{
|
||||
if (textOverlay.length() > 0)
|
||||
{
|
||||
textOverlay += " | ";
|
||||
}
|
||||
textOverlay += Integer.toString(hunllef.getPlayerAttacks());
|
||||
}
|
||||
|
||||
// Handles drawing the text onto the boss.
|
||||
if (textOverlay.length() > 0)
|
||||
{
|
||||
Point textLoc = Perspective.getCanvasTextLocation(client, graphics, point, textOverlay, boss.getLogicalHeight() / 2);
|
||||
|
||||
if (textLoc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
textLoc = new Point(textLoc.getX(), textLoc.getY() + 35);
|
||||
|
||||
Font oldFont = graphics.getFont();
|
||||
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, 20));
|
||||
Point pointShadow = new Point(textLoc.getX() + 1, textLoc.getY() + 1);
|
||||
|
||||
OverlayUtil.renderTextLocation(graphics, pointShadow, textOverlay, Color.BLACK);
|
||||
OverlayUtil.renderTextLocation(graphics, textLoc, textOverlay, phase.getColor());
|
||||
|
||||
graphics.setFont(oldFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This section overlays all resources.
|
||||
final LocalPoint playerLocation = client.getLocalPlayer().getLocalLocation();
|
||||
|
||||
final Set<Resources> resources = plugin.getResources();
|
||||
resources.forEach(object ->
|
||||
{
|
||||
if (object.getGameObject().getLocalLocation().distanceTo(playerLocation) < MAX_DISTANCE)
|
||||
{
|
||||
|
||||
// Don't use Convex Hull click box. As the room start to fill up, your FPS will dip.
|
||||
Polygon polygon = object.getGameObject().getConvexHull();
|
||||
|
||||
if (polygon == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// This section will highlight the resource with color.
|
||||
if (plugin.isHighlightResources())
|
||||
{
|
||||
outlineRenderer.drawOutline(object.getGameObject(), 2, plugin.getHighlightResourcesColor());
|
||||
}
|
||||
|
||||
// This section will overlay the resource with an icon.
|
||||
if (plugin.isHighlightResourcesIcons())
|
||||
{
|
||||
BufferedImage icon = resizeImage(object.getImage(), plugin.getResourceIconSize(), plugin.getResourceIconSize());
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
Rectangle bounds = polygon.getBounds();
|
||||
int startX = (int) bounds.getCenterX() - (icon.getWidth() / 2);
|
||||
int startY = (int) bounds.getCenterY() - (icon.getHeight() / 2);
|
||||
graphics.drawImage(icon, startX, startY, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Polygon boundProjectile(Projectile proj)
|
||||
{
|
||||
if (proj == null || proj.getModel() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Model model = proj.getModel();
|
||||
LocalPoint point = new LocalPoint((int) proj.getX(), (int) proj.getY());
|
||||
int tileHeight = Perspective.getTileHeight(client, point, client.getPlane());
|
||||
|
||||
double angle = Math.atan(proj.getVelocityY() / proj.getVelocityX());
|
||||
angle = Math.toDegrees(angle) + (proj.getVelocityX() < 0 ? 180 : 0);
|
||||
angle = angle < 0 ? angle + 360 : angle;
|
||||
angle = 360 - angle - 90;
|
||||
|
||||
double ori = angle * (512d / 90d);
|
||||
ori = ori < 0 ? ori + 2048 : ori;
|
||||
|
||||
int orientation = (int) Math.round(ori);
|
||||
|
||||
List<Vertex> vertices = model.getVertices();
|
||||
for (int i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
vertices.set(i, vertices.get(i).rotate(orientation));
|
||||
}
|
||||
|
||||
List<Point> list = new ArrayList<>();
|
||||
|
||||
for (Vertex vertex : vertices)
|
||||
{
|
||||
final Point localToCanvas = Perspective.localToCanvas(client, point.getX() - vertex.getX(), point.getY() - vertex.getZ(), tileHeight + vertex.getY() + (int) proj.getZ());
|
||||
if (localToCanvas != null)
|
||||
{
|
||||
list.add(localToCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
final List<Point> convexHull = Jarvis.convexHull(list);
|
||||
if (convexHull == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Polygon polygon = new Polygon();
|
||||
for (final Point hullPoint : convexHull)
|
||||
{
|
||||
polygon.addPoint(hullPoint.getX(), hullPoint.getY());
|
||||
}
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
|
||||
* Copyright (c) 2019, kThisIsCvpv <https://github.com/kThisIsCvpv>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -22,244 +22,430 @@
|
||||
* (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.gauntlet;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.AnimationID;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.HeadIcon;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCDefinition;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.SoundEffectID;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.ConfigChanged;
|
||||
import net.runelite.api.events.GameObjectDespawned;
|
||||
import net.runelite.api.events.GameObjectSpawned;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.NpcDespawned;
|
||||
import net.runelite.api.events.NpcSpawned;
|
||||
import net.runelite.api.events.ProjectileSpawned;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.LIGHTNING;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.MAGIC;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.PRAYER;
|
||||
import static net.runelite.client.plugins.gauntlet.Hunllef.BossAttack.RANGE;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Gauntlet Boss Helper",
|
||||
description = "Prayer Overlay For The Gauntlet Boss",
|
||||
tags = {"gauntlet"},
|
||||
type = PluginType.PVM,
|
||||
enabledByDefault = false
|
||||
name = "Gauntlet",
|
||||
description = "All-in-one plugin for the Gauntlet.",
|
||||
tags = {"Gauntlet"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.PVM
|
||||
)
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
public class GauntletPlugin extends Plugin
|
||||
{
|
||||
private static final Set<Integer> PLAYER_ANIMATIONS = ImmutableSet.of(426, 1167, 422, 423, 440, 428);
|
||||
private static final Set<Integer> HUNLEFF_ANIMATIONS = ImmutableSet.of(AnimationID.HUNLEFF_ATTACK, AnimationID.HUNLEFF_TORNADO);
|
||||
private static final Set<Integer> HUNLEFF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_MAGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_MAGE_ATTACK);
|
||||
private static final Set<Integer> HUNLEFF_RANGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLEFF_RANGE_ATTACK, ProjectileID.HUNLEFF_CORRUPTED_RANGE_ATTACK);
|
||||
private static final int BOW_ATTACK = 426;
|
||||
private static final int STAFF_ATTACK = 1167;
|
||||
private static final int LIGHTNING_ANIMATION = 8418;
|
||||
private static final Set<Integer> TORNADO_NPC_IDS = ImmutableSet.of(9025, 9039);
|
||||
private static final Set<Integer> MELEE_ANIMATIONS = ImmutableSet.of(395, 401, 400, 401, 386, 390, 422, 423, 401, 428, 440);
|
||||
private static final Set<Integer> PLAYER_ANIMATIONS = ImmutableSet.of(395, 401, 400, 401, 386, 390, 422, 423, 401, 428, 440, 426, 1167);
|
||||
private static final Set<Integer> HUNLLEF_MAGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_MAGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK);
|
||||
private static final Set<Integer> HUNLLEF_RANGE_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_RANGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK);
|
||||
private static final Set<Integer> HUNLLEF_PRAYER_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_PRAYER_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK);
|
||||
private static final Set<Integer> HUNLLEF_PROJECTILES = ImmutableSet.of(ProjectileID.HUNLLEF_PRAYER_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK,
|
||||
ProjectileID.HUNLLEF_RANGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK, ProjectileID.HUNLLEF_MAGE_ATTACK, ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK
|
||||
);
|
||||
private static final Set<Integer> HUNLLEF_NPC_IDS = ImmutableSet.of(NpcID.CRYSTALLINE_HUNLLEF, NpcID.CRYSTALLINE_HUNLLEF_9022, NpcID.CRYSTALLINE_HUNLLEF_9023,
|
||||
NpcID.CRYSTALLINE_HUNLLEF_9024, NpcID.CORRUPTED_HUNLLEF, NpcID.CORRUPTED_HUNLLEF_9036, NpcID.CORRUPTED_HUNLLEF_9037, NpcID.CORRUPTED_HUNLLEF_9038
|
||||
);
|
||||
private static final Set<Integer> RESOURCES = ImmutableSet.of(ObjectID.CRYSTAL_DEPOSIT, ObjectID.CORRUPT_DEPOSIT, ObjectID.PHREN_ROOTS,
|
||||
ObjectID.PHREN_ROOTS_36066, ObjectID.FISHING_SPOT_36068, ObjectID.FISHING_SPOT_35971, ObjectID.GRYM_ROOT, ObjectID.GRYM_ROOT_36070,
|
||||
ObjectID.LINUM_TIRINUM, ObjectID.LINUM_TIRINUM_36072
|
||||
);
|
||||
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private Client client;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private EventBus eventBus;
|
||||
private ClientThread clientThread;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private OverlayManager overlayManager;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private GauntletInfoBox GauntletInfoBox;
|
||||
private GauntletOverlay overlay;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private GauntletCounter GauntletCounter;
|
||||
private int attacks = 0;
|
||||
private int playerAttacks = 0;
|
||||
private Prayer nextPrayer;
|
||||
private NPC hunllef;
|
||||
private boolean firstHitDetected;
|
||||
private HeadIcon currentPrayer;
|
||||
private GauntletConfig config;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private EventBus eventBus;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private GauntletTimer timer;
|
||||
@Inject
|
||||
@Getter(AccessLevel.NONE)
|
||||
private SkillIconManager skillIconManager;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private Hunllef hunllef;
|
||||
private final Set<Resources> resources = new HashSet<>();
|
||||
private final Set<Missiles> projectiles = new HashSet<>();
|
||||
private final Map<String, Integer> items = new HashMap<>();
|
||||
private Set<Tornado> tornadoes = new HashSet<>();
|
||||
private boolean completeStartup = false;
|
||||
private boolean countBossAttacks;
|
||||
private boolean countPlayerAttacks;
|
||||
private boolean displayTimerChat;
|
||||
private boolean highlightResources;
|
||||
private boolean highlightResourcesIcons;
|
||||
private boolean highlightWidget;
|
||||
private boolean overlayBoss;
|
||||
private boolean overlayBossPrayer;
|
||||
private boolean overlayTornadoes;
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean flash;
|
||||
private boolean flashOnWrongAttack;
|
||||
private Color highlightResourcesColor;
|
||||
private boolean displayTimerWidget;
|
||||
private boolean timerVisible = true;
|
||||
private boolean uniqueAttackVisual;
|
||||
private boolean uniquePrayerAudio;
|
||||
private boolean uniquePrayerVisual;
|
||||
private int resourceIconSize;
|
||||
private int projectileIconSize;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
@Provides
|
||||
GauntletConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
addSubscriptions();
|
||||
overlayManager.add(GauntletInfoBox);
|
||||
overlayManager.add(GauntletCounter);
|
||||
reset();
|
||||
return configManager.getConfig(GauntletConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
protected void startUp()
|
||||
{
|
||||
addSubscriptions();
|
||||
updateConfig();
|
||||
timerVisible = this.displayTimerWidget;
|
||||
timer.resetStates();
|
||||
if (timerVisible)
|
||||
{
|
||||
overlayManager.add(timer);
|
||||
}
|
||||
overlayManager.add(overlay);
|
||||
if (client.getGameState() != GameState.STARTING && client.getGameState() != GameState.UNKNOWN)
|
||||
{
|
||||
completeStartup = false;
|
||||
clientThread.invoke(() -> {
|
||||
timer.initStates();
|
||||
completeStartup = true;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
completeStartup = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
eventBus.unregister(this);
|
||||
overlayManager.remove(GauntletInfoBox);
|
||||
overlayManager.remove(GauntletCounter);
|
||||
reset();
|
||||
timer.resetStates();
|
||||
if (timerVisible)
|
||||
{
|
||||
overlayManager.remove(timer);
|
||||
timerVisible = false;
|
||||
}
|
||||
overlayManager.remove(overlay);
|
||||
resources.clear();
|
||||
projectiles.clear();
|
||||
tornadoes.clear();
|
||||
setHunllef(null);
|
||||
}
|
||||
|
||||
private void addSubscriptions()
|
||||
{
|
||||
eventBus.subscribe(AnimationChanged.class, this, this::onAnimationChanged);
|
||||
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
|
||||
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
|
||||
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
|
||||
eventBus.subscribe(GameObjectDespawned.class, this, this::onGameObjectDespawned);
|
||||
eventBus.subscribe(GameObjectSpawned.class, this, this::onGameObjectSpawned);
|
||||
eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged);
|
||||
eventBus.subscribe(GameTick.class, this, this::onGameTick);
|
||||
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
|
||||
eventBus.subscribe(NpcSpawned.class, this, this::onNpcSpawned);
|
||||
eventBus.subscribe(ProjectileSpawned.class, this, this::onProjectileSpawned);
|
||||
eventBus.subscribe(VarbitChanged.class, this, this::onVarbitChanged);
|
||||
}
|
||||
|
||||
private void onAnimationChanged(AnimationChanged event)
|
||||
{
|
||||
if (getHunllef() == null || !isInRoom())
|
||||
final Actor actor = event.getActor();
|
||||
|
||||
// This section handles the player counter.
|
||||
if (actor instanceof Player && fightingBoss())
|
||||
{
|
||||
final Player player = (Player) actor;
|
||||
final int anim = player.getAnimation();
|
||||
|
||||
if (!player.getName().equals(client.getLocalPlayer().getName()) || anim == -1 || !PLAYER_ANIMATIONS.contains(anim))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NPCDefinition comp = hunllef.getNpc().getDefinition();
|
||||
|
||||
if (comp == null || comp.getOverheadIcon() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final HeadIcon prayer = comp.getOverheadIcon();
|
||||
|
||||
switch (prayer)
|
||||
{
|
||||
case MELEE:
|
||||
if (MELEE_ANIMATIONS.contains(anim))
|
||||
{
|
||||
setFlash(true);
|
||||
return;
|
||||
}
|
||||
hunllef.updatePlayerAttack();
|
||||
break;
|
||||
case RANGED:
|
||||
if (BOW_ATTACK == anim)
|
||||
{
|
||||
setFlash(true);
|
||||
return;
|
||||
}
|
||||
hunllef.updatePlayerAttack();
|
||||
break;
|
||||
case MAGIC:
|
||||
if (STAFF_ATTACK == anim)
|
||||
{
|
||||
setFlash(true);
|
||||
return;
|
||||
}
|
||||
hunllef.updatePlayerAttack();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This section handles the boss attack counter if they perform a lightning attack.
|
||||
if (actor instanceof NPC)
|
||||
{
|
||||
final NPC npc = (NPC) actor;
|
||||
|
||||
if (npc.getAnimation() == LIGHTNING_ANIMATION)
|
||||
{
|
||||
hunllef.updateAttack(LIGHTNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (!event.getGroup().equals("Gauntlet"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int anim = event.getActor().getAnimation();
|
||||
updateConfig();
|
||||
|
||||
if (HUNLEFF_ANIMATIONS.contains(anim))
|
||||
if (event.getKey().equals("displayTimerWidget"))
|
||||
{
|
||||
setAttacks(getAttacks() + 1);
|
||||
|
||||
if (getAttacks() == 4)
|
||||
if (this.displayTimerWidget && !timerVisible)
|
||||
{
|
||||
if (getNextPrayer() == Prayer.PROTECT_FROM_MISSILES)
|
||||
{
|
||||
log.debug("Attacks are: {}, switching to prot mage", getAttacks());
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MAGIC);
|
||||
}
|
||||
else if (getNextPrayer() == Prayer.PROTECT_FROM_MAGIC)
|
||||
{
|
||||
log.debug("Attacks are: {}, switching to prot missiles", getAttacks());
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MISSILES);
|
||||
}
|
||||
setAttacks(0);
|
||||
overlayManager.add(timer);
|
||||
timerVisible = true;
|
||||
}
|
||||
else if (!this.displayTimerWidget && timerVisible)
|
||||
{
|
||||
overlayManager.remove(timer);
|
||||
timerVisible = false;
|
||||
}
|
||||
}
|
||||
else if (PLAYER_ANIMATIONS.contains(anim))
|
||||
}
|
||||
|
||||
private void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
final GameObject obj = event.getGameObject();
|
||||
if (RESOURCES.contains(obj.getId()))
|
||||
{
|
||||
setPlayerAttacks(getPlayerAttacks() - 1);
|
||||
if (getPlayerAttacks() == 0)
|
||||
{
|
||||
setPlayerAttacks(6);
|
||||
}
|
||||
resources.removeIf(object -> object.getGameObject() == obj);
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
final GameObject obj = event.getGameObject();
|
||||
if (RESOURCES.contains(obj.getId()))
|
||||
{
|
||||
resources.add(new Resources(obj, event.getTile(), skillIconManager));
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
resources.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void onGameTick(GameTick event)
|
||||
{
|
||||
if (getHunllef() == null || !isInRoom())
|
||||
// This handles the timer based on player health.
|
||||
if (this.completeStartup)
|
||||
{
|
||||
return;
|
||||
timer.checkStates(false);
|
||||
}
|
||||
|
||||
HeadIcon overhead = getOverheadIcon(getHunllef());
|
||||
|
||||
if (overhead == null)
|
||||
if (!tornadoes.isEmpty())
|
||||
{
|
||||
return;
|
||||
tornadoes.forEach(Tornado::updateTimeLeft);
|
||||
}
|
||||
|
||||
switch (overhead)
|
||||
if (hunllef != null)
|
||||
{
|
||||
case MELEE:
|
||||
case MAGIC:
|
||||
case RANGED:
|
||||
if (currentPrayer == overhead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
currentPrayer = overhead;
|
||||
setPlayerAttacks(6);
|
||||
break;
|
||||
if (hunllef.getTicksUntilAttack() > 0)
|
||||
{
|
||||
hunllef.setTicksUntilAttack(hunllef.getTicksUntilAttack() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef"))
|
||||
if (HUNLLEF_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
return;
|
||||
setHunllef(null);
|
||||
}
|
||||
else if (TORNADO_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
tornadoes.removeIf(tornado -> tornado.getNpc() == npc);
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
private void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
final NPC npc = event.getNpc();
|
||||
|
||||
if (npc.getName() == null || !npc.getName().toLowerCase().contains("hunllef"))
|
||||
if (HUNLLEF_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
return;
|
||||
setHunllef(new Hunllef(npc, skillIconManager));
|
||||
}
|
||||
else if (TORNADO_NPC_IDS.contains(npc.getId()))
|
||||
{
|
||||
tornadoes.add(new Tornado(npc));
|
||||
}
|
||||
|
||||
setPlayerAttacks(6);
|
||||
setAttacks(0);
|
||||
setHunllef(npc);
|
||||
}
|
||||
|
||||
private void onProjectileSpawned(ProjectileSpawned event)
|
||||
{
|
||||
if (getHunllef() == null || !isInRoom() || isFirstHitDetected())
|
||||
if (hunllef == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int projectileID = event.getProjectile().getId();
|
||||
final Projectile proj = event.getProjectile();
|
||||
|
||||
if (HUNLEFF_MAGE_PROJECTILES.contains(projectileID))
|
||||
if (HUNLLEF_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MAGIC);
|
||||
setFirstHitDetected(true);
|
||||
}
|
||||
else if (HUNLEFF_RANGE_PROJECTILES.contains(projectileID))
|
||||
{
|
||||
setNextPrayer(Prayer.PROTECT_FROM_MISSILES);
|
||||
setFirstHitDetected(true);
|
||||
projectiles.add(new Missiles(proj, skillIconManager));
|
||||
if (HUNLLEF_MAGE_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
hunllef.updateAttack(MAGIC);
|
||||
}
|
||||
else if (HUNLLEF_PRAYER_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
hunllef.updateAttack(PRAYER);
|
||||
if (this.uniquePrayerAudio)
|
||||
{
|
||||
client.playSoundEffect(SoundEffectID.MAGIC_SPLASH_BOING);
|
||||
}
|
||||
}
|
||||
else if (HUNLLEF_RANGE_PROJECTILES.contains(proj.getId()))
|
||||
{
|
||||
hunllef.updateAttack(RANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void reset()
|
||||
private void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
setHunllef(null);
|
||||
setNextPrayer(null);
|
||||
setCurrentPrayer(null);
|
||||
setFirstHitDetected(false);
|
||||
setAttacks(0);
|
||||
setPlayerAttacks(6);
|
||||
}
|
||||
|
||||
private HeadIcon getOverheadIcon(NPC npc)
|
||||
{
|
||||
NPCDefinition composition = npc.getDefinition();
|
||||
if (composition != null)
|
||||
if (this.completeStartup)
|
||||
{
|
||||
return composition.getOverheadIcon();
|
||||
timer.checkStates(true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isInRoom()
|
||||
boolean fightingBoss()
|
||||
{
|
||||
return client.getVar(Varbits.GAUNTLET_FINAL_ROOM_ENTERED) == 1;
|
||||
}
|
||||
|
||||
boolean startedGauntlet()
|
||||
{
|
||||
return client.getVar(Varbits.GAUNTLET_ENTERED) == 1;
|
||||
}
|
||||
|
||||
private void updateConfig()
|
||||
{
|
||||
this.highlightResources = config.highlightResources();
|
||||
this.highlightResourcesColor = config.highlightResourcesColor();
|
||||
this.highlightResourcesIcons = config.highlightResourcesIcons();
|
||||
this.flashOnWrongAttack = config.flashOnWrongAttack();
|
||||
this.highlightWidget = config.highlightWidget();
|
||||
this.resourceIconSize = config.resourceIconSize();
|
||||
this.projectileIconSize = config.projectileIconSize();
|
||||
this.countBossAttacks = config.countBossAttacks();
|
||||
this.countPlayerAttacks = config.countPlayerAttacks();
|
||||
this.uniquePrayerAudio = config.uniquePrayerAudio();
|
||||
this.uniquePrayerVisual = config.uniquePrayerVisual();
|
||||
this.uniqueAttackVisual = config.uniqueAttackVisual();
|
||||
this.overlayBoss = config.overlayBoss();
|
||||
this.overlayBossPrayer = config.overlayBossPrayer();
|
||||
this.overlayTornadoes = config.overlayTornadoes();
|
||||
this.displayTimerWidget = config.displayTimerWidget();
|
||||
this.displayTimerChat = config.displayTimerChat();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <http://github.com/sethtroll>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import static net.runelite.client.plugins.gauntlet.GauntletTimer.RaidState.IN_BOSS;
|
||||
import static net.runelite.client.plugins.gauntlet.GauntletTimer.RaidState.IN_RAID;
|
||||
import static net.runelite.client.plugins.gauntlet.GauntletTimer.RaidState.UNKNOWN;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
||||
|
||||
class GauntletTimer extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
private final GauntletPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
private long timeRaidStart = -1L;
|
||||
private long timeBossEnter = -1L;
|
||||
private RaidState currentState = UNKNOWN;
|
||||
|
||||
@Inject
|
||||
public GauntletTimer(Client client, GauntletPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
|
||||
setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Gauntlet Timer Overlay"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the timer.
|
||||
*/
|
||||
void resetStates()
|
||||
{
|
||||
timeRaidStart = -1L;
|
||||
timeBossEnter = -1L;
|
||||
|
||||
currentState = UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the player resets the plugin mid-raid. We do not want to confuse the timer.
|
||||
* <p>
|
||||
* TODO: Originally, this function will disable the timer if the plugin is started mid raid.
|
||||
* Unfortunately, VARBITS can't be checked unless you're on the client thread.
|
||||
* I've no idea how to access RL's task handler.
|
||||
* Good luck to you. If you restart plugin mid raid, oh well. Your timer's going to be inaccurate.
|
||||
*/
|
||||
void initStates()
|
||||
{
|
||||
timeRaidStart = -1L;
|
||||
timeBossEnter = -1L;
|
||||
|
||||
if (plugin.startedGauntlet())
|
||||
{
|
||||
currentState = IN_RAID;
|
||||
if (plugin.fightingBoss())
|
||||
{
|
||||
currentState = IN_BOSS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentState = UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the different between two epoch times into minutes:seconds format.
|
||||
*
|
||||
* @param epochA long
|
||||
* @param epochB long
|
||||
* @return String
|
||||
*/
|
||||
private String calculateElapsedTime(long epochA, long epochB)
|
||||
{
|
||||
long max = Math.max(epochA, epochB);
|
||||
long min = Math.min(epochA, epochB);
|
||||
|
||||
long elapsedEpoch = max - min;
|
||||
long seconds = elapsedEpoch / 1000L;
|
||||
|
||||
long minutes = seconds / 60L;
|
||||
seconds = seconds % 60;
|
||||
|
||||
if (seconds == 0)
|
||||
{
|
||||
return minutes + ":00";
|
||||
}
|
||||
|
||||
if (seconds < 10)
|
||||
{
|
||||
return minutes + ":0" + seconds;
|
||||
}
|
||||
|
||||
return minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when varbit changes. See if the the raid state has changed.
|
||||
*/
|
||||
void checkStates(boolean checkVarps)
|
||||
{
|
||||
final Player p = client.getLocalPlayer();
|
||||
|
||||
if (p == null || !plugin.isCompleteStartup())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkVarps)
|
||||
{
|
||||
switch (currentState)
|
||||
{
|
||||
case UNKNOWN:
|
||||
if (plugin.startedGauntlet() && p.getHealthRatio() != 0)
|
||||
{
|
||||
// Player has started a new raid.
|
||||
if (!plugin.fightingBoss())
|
||||
{
|
||||
currentState = IN_RAID;
|
||||
timeRaidStart = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
currentState = IN_RAID;
|
||||
timeRaidStart = timeBossEnter = System.currentTimeMillis();
|
||||
}
|
||||
break;
|
||||
case IN_RAID:
|
||||
if (!plugin.startedGauntlet())
|
||||
{
|
||||
printPrepTime();
|
||||
resetStates();
|
||||
return;
|
||||
}
|
||||
if (plugin.fightingBoss())
|
||||
{
|
||||
// Player has begun the boss fight.
|
||||
printPrepTime();
|
||||
currentState = IN_BOSS;
|
||||
timeBossEnter = System.currentTimeMillis();
|
||||
}
|
||||
break;
|
||||
case IN_BOSS:
|
||||
if (!plugin.fightingBoss() || !plugin.startedGauntlet())
|
||||
{
|
||||
// Player has killed the boss.
|
||||
resetStates();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentState == IN_BOSS && p.getHealthRatio() == 0)
|
||||
{
|
||||
printBossTime();
|
||||
resetStates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printPrepTime()
|
||||
{
|
||||
if (!plugin.isDisplayTimerChat() || timeRaidStart == -1L)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String elapsedTime = calculateElapsedTime(System.currentTimeMillis(), timeRaidStart);
|
||||
|
||||
final ChatMessageBuilder prepmessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append("Preparation time: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedTime);
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(prepmessage.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
private void printBossTime()
|
||||
{
|
||||
if (!plugin.isDisplayTimerChat() || timeRaidStart == -1L || timeBossEnter == -1L)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String elapsedBossTime = calculateElapsedTime(System.currentTimeMillis(), timeBossEnter);
|
||||
String elapsedPrepTime = calculateElapsedTime(timeRaidStart, timeBossEnter);
|
||||
String elapsedTotalTime = calculateElapsedTime(System.currentTimeMillis(), timeRaidStart);
|
||||
|
||||
final ChatMessageBuilder challengedurationmessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append("Challenge duration: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedTotalTime);
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(challengedurationmessage.build())
|
||||
.build());
|
||||
|
||||
final ChatMessageBuilder prepdeathmessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append("Preparation time: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedPrepTime)
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(" player/boss death time: ")
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(elapsedBossTime);
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(prepdeathmessage.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (currentState == UNKNOWN)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
panelComponent.getChildren().add(TitleComponent.builder().text("Gauntlet Timer").color(Color.WHITE).build());
|
||||
TableComponent tableComponent = new TableComponent();
|
||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
||||
|
||||
if (timeRaidStart == -1L)
|
||||
{ // User restarted the plugin mid raid. Timer is inaccurate.
|
||||
tableComponent.addRow("Inactive", "0:00");
|
||||
}
|
||||
else
|
||||
{
|
||||
String elapsedPrepTime, elapsedBossTime, elapsedTotalTime;
|
||||
elapsedTotalTime = calculateElapsedTime(System.currentTimeMillis(), timeRaidStart);
|
||||
|
||||
if (currentState == IN_RAID)
|
||||
{
|
||||
elapsedPrepTime = calculateElapsedTime(timeRaidStart, System.currentTimeMillis());
|
||||
elapsedBossTime = "0:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
elapsedPrepTime = calculateElapsedTime(timeRaidStart, timeBossEnter);
|
||||
elapsedBossTime = calculateElapsedTime(System.currentTimeMillis(), timeBossEnter);
|
||||
}
|
||||
tableComponent.addRow("Preparation", elapsedPrepTime);
|
||||
tableComponent.addRow("Boss Fight", elapsedBossTime);
|
||||
tableComponent.addRow("Total Time", elapsedTotalTime);
|
||||
panelComponent.getChildren().add(tableComponent);
|
||||
}
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
public enum RaidState
|
||||
{
|
||||
UNKNOWN, IN_RAID, IN_BOSS
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
public class Hunllef
|
||||
{
|
||||
private NPC npc;
|
||||
private int bossAttacks;
|
||||
private int playerAttacks;
|
||||
private int ticksUntilAttack;
|
||||
private BufferedImage mage;
|
||||
private BufferedImage range;
|
||||
private BossAttackPhase currentPhase;
|
||||
|
||||
Hunllef(NPC npc, SkillIconManager skillIconManager)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.bossAttacks = 0;
|
||||
this.playerAttacks = 6;
|
||||
this.ticksUntilAttack = 0;
|
||||
this.mage = skillIconManager.getSkillImage(Skill.MAGIC);
|
||||
this.range = skillIconManager.getSkillImage(Skill.RANGED);
|
||||
this.currentPhase = BossAttackPhase.UNKNOWN;
|
||||
}
|
||||
|
||||
void updatePlayerAttack()
|
||||
{
|
||||
playerAttacks--;
|
||||
if (playerAttacks <= 0)
|
||||
{
|
||||
playerAttacks = 6;
|
||||
}
|
||||
}
|
||||
|
||||
void updateAttack(BossAttack style)
|
||||
{
|
||||
ticksUntilAttack = 6;
|
||||
if (style == BossAttack.PRAYER)
|
||||
{
|
||||
style = BossAttack.MAGIC;
|
||||
}
|
||||
|
||||
if (style == BossAttack.LIGHTNING)
|
||||
{
|
||||
bossAttacks--;
|
||||
}
|
||||
else if (style == BossAttack.RANGE)
|
||||
{
|
||||
if (currentPhase != BossAttackPhase.RANGE)
|
||||
{
|
||||
currentPhase = BossAttackPhase.RANGE;
|
||||
bossAttacks = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
bossAttacks--;
|
||||
}
|
||||
}
|
||||
else if (style == BossAttack.MAGIC)
|
||||
{
|
||||
if (currentPhase != BossAttackPhase.MAGIC)
|
||||
{
|
||||
currentPhase = BossAttackPhase.MAGIC;
|
||||
bossAttacks = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
bossAttacks--;
|
||||
}
|
||||
}
|
||||
|
||||
if (bossAttacks <= 0)
|
||||
{
|
||||
BossAttackPhase nextPhase;
|
||||
|
||||
switch (currentPhase)
|
||||
{
|
||||
case MAGIC:
|
||||
bossAttacks = 4;
|
||||
nextPhase = BossAttackPhase.RANGE;
|
||||
break;
|
||||
case RANGE:
|
||||
bossAttacks = 4;
|
||||
nextPhase = BossAttackPhase.MAGIC;
|
||||
break;
|
||||
default:
|
||||
bossAttacks = 0;
|
||||
nextPhase = BossAttackPhase.UNKNOWN;
|
||||
break;
|
||||
}
|
||||
currentPhase = nextPhase;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
enum BossAttackPhase
|
||||
{
|
||||
MAGIC(Color.CYAN, Prayer.PROTECT_FROM_MAGIC),
|
||||
RANGE(Color.GREEN, Prayer.PROTECT_FROM_MISSILES),
|
||||
UNKNOWN(Color.WHITE, null);
|
||||
|
||||
private Color color;
|
||||
private Prayer prayer;
|
||||
}
|
||||
|
||||
enum BossAttack
|
||||
{
|
||||
MAGIC,
|
||||
RANGE,
|
||||
PRAYER,
|
||||
LIGHTNING
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.Projectile;
|
||||
import net.runelite.api.ProjectileID;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Missiles
|
||||
{
|
||||
private Projectile projectile;
|
||||
private int id;
|
||||
private BufferedImage image;
|
||||
private Color color;
|
||||
|
||||
Missiles(Projectile projectile, SkillIconManager skillIconManager)
|
||||
{
|
||||
this.projectile = projectile;
|
||||
this.id = projectile.getId();
|
||||
this.image = assignedImage(skillIconManager, id);
|
||||
this.color = assignedColor(id);
|
||||
}
|
||||
|
||||
private Color assignedColor(int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case ProjectileID.HUNLLEF_MAGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK:
|
||||
return Color.CYAN;
|
||||
case ProjectileID.HUNLLEF_RANGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK:
|
||||
return Color.GREEN;
|
||||
case ProjectileID.HUNLLEF_PRAYER_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK:
|
||||
return Color.MAGENTA;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage assignedImage(SkillIconManager SkillIconManager, int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case ProjectileID.HUNLLEF_MAGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_MAGE_ATTACK:
|
||||
return SkillIconManager.getSkillImage(Skill.MAGIC);
|
||||
case ProjectileID.HUNLLEF_RANGE_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_RANGE_ATTACK:
|
||||
return SkillIconManager.getSkillImage(Skill.RANGED);
|
||||
case ProjectileID.HUNLLEF_PRAYER_ATTACK:
|
||||
case ProjectileID.HUNLLEF_CORRUPTED_PRAYER_ATTACK:
|
||||
return SkillIconManager.getSkillImage(Skill.PRAYER);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.gauntlet;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.ObjectID;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Resources
|
||||
{
|
||||
private GameObject gameObject;
|
||||
private Tile tile;
|
||||
private BufferedImage image;
|
||||
|
||||
Resources(GameObject object, Tile tile, SkillIconManager skillIconManager)
|
||||
{
|
||||
this.gameObject = object;
|
||||
this.tile = tile;
|
||||
this.image = assignedImage(skillIconManager, object.getId());
|
||||
}
|
||||
|
||||
private BufferedImage assignedImage(SkillIconManager SkillIconManager, int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case ObjectID.CRYSTAL_DEPOSIT:
|
||||
case ObjectID.CORRUPT_DEPOSIT:
|
||||
return SkillIconManager.getSkillImage(Skill.MINING);
|
||||
case ObjectID.PHREN_ROOTS:
|
||||
case ObjectID.PHREN_ROOTS_36066:
|
||||
return SkillIconManager.getSkillImage(Skill.WOODCUTTING);
|
||||
case ObjectID.FISHING_SPOT_36068:
|
||||
case ObjectID.FISHING_SPOT_35971:
|
||||
return SkillIconManager.getSkillImage(Skill.FISHING);
|
||||
case ObjectID.GRYM_ROOT:
|
||||
case ObjectID.GRYM_ROOT_36070:
|
||||
return SkillIconManager.getSkillImage(Skill.HERBLORE);
|
||||
case ObjectID.LINUM_TIRINUM:
|
||||
case ObjectID.LINUM_TIRINUM_36072:
|
||||
return SkillIconManager.getSkillImage(Skill.FARMING);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -22,21 +21,30 @@
|
||||
* (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.gauntlet;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.api.NPC;
|
||||
|
||||
public interface GauntletPluginConfig extends Config
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
class Tornado
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "gauntletEnable",
|
||||
name = "Enable gauntlet",
|
||||
description = "gauntlet boss prayer"
|
||||
)
|
||||
default boolean enableGauntlet()
|
||||
private NPC npc;
|
||||
private int timeLeft;
|
||||
|
||||
Tornado(NPC npc)
|
||||
{
|
||||
return true;
|
||||
this.npc = npc;
|
||||
this.timeLeft = 20;
|
||||
}
|
||||
}
|
||||
|
||||
void updateTimeLeft()
|
||||
{
|
||||
if (timeLeft > 0)
|
||||
{
|
||||
timeLeft--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ enum TransportationPointLocation
|
||||
TELEPORT_RUNE_ARDOUGNE("Teleport to Rune Essence", new WorldPoint(2681, 3325, 0)),
|
||||
TELEPORT_RUNE_YANILLE("Teleport to Rune Essence", new WorldPoint(2592, 3089, 0)),
|
||||
TELEPORT_SORCERESS_GARDEN("Teleport to Sorceress's Garden", new WorldPoint(3320, 3141, 0)),
|
||||
TELEPORT_PRIFDDINAS_LIBRARY("Teleport to Priffdinas Library", new WorldPoint(3254, 6082, 2)),
|
||||
TELEPORT_PRIFDDINAS_LIBRARY("Teleport to Prifddinas Library", new WorldPoint(3254, 6082, 2)),
|
||||
|
||||
//Other
|
||||
ALTER_KOUREND_UNDERGROUND("Altar to Skotizo", new WorldPoint(1662, 10047, 0)),
|
||||
|
||||
@@ -30,6 +30,8 @@ import java.awt.GridBagLayout;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Singleton;
|
||||
import javax.swing.ImageIcon;
|
||||
@@ -40,8 +42,6 @@ import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.RuneLiteProperties;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import org.pushingpixels.substance.internal.SubstanceSynapse;
|
||||
|
||||
@@ -53,7 +53,9 @@ import org.pushingpixels.substance.internal.SubstanceSynapse;
|
||||
@Singleton
|
||||
public class RuneLiteSplashScreen
|
||||
{
|
||||
private final RuneLiteProperties runeLiteProperties = new RuneLiteProperties();
|
||||
private static final String RUNELITE_VERSION = "runelite.version";
|
||||
private static final String RUNELITE_PLUS_VERSION = "runelite.plus.version";
|
||||
private static final String RUNELITE_PLUS_DATE = "runelite.plus.builddate";
|
||||
|
||||
private JFrame frame;
|
||||
private final JPanel panel = new JPanel();
|
||||
@@ -61,6 +63,20 @@ public class RuneLiteSplashScreen
|
||||
private JLabel subMessageLabel;
|
||||
private final JProgressBar progressBar = new JProgressBar();
|
||||
|
||||
private final Properties properties = new Properties();
|
||||
|
||||
public RuneLiteSplashScreen()
|
||||
{
|
||||
try (InputStream in = getClass().getResourceAsStream("/runelite.plus.properties"))
|
||||
{
|
||||
properties.load(in);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.warn("unable to load propertries", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not done in the constructor in order to avoid processing in case the user chooses to not load
|
||||
* the splash screen.
|
||||
@@ -90,7 +106,7 @@ public class RuneLiteSplashScreen
|
||||
panel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
final GridBagLayout layout = new GridBagLayout();
|
||||
layout.columnWeights = new double[]{1};
|
||||
layout.rowWeights = new double[]{1, 0, 0, 1, 0, 1};
|
||||
layout.rowWeights = new double[]{1, 0, 0, 1, 0, 0, 1};
|
||||
panel.setLayout(layout);
|
||||
|
||||
// logo
|
||||
@@ -119,7 +135,7 @@ public class RuneLiteSplashScreen
|
||||
panel.add(title, titleConstraints);
|
||||
|
||||
// version
|
||||
final JLabel version = new JLabel("RuneLite Version : " + runeLiteProperties.getVersion());
|
||||
final JLabel version = new JLabel("RuneLite Version : " + properties.getProperty(RUNELITE_VERSION));
|
||||
version.setForeground(Color.GREEN);
|
||||
version.setFont(FontManager.getRunescapeSmallFont());
|
||||
version.setForeground(version.getForeground().darker());
|
||||
@@ -128,34 +144,42 @@ public class RuneLiteSplashScreen
|
||||
panel.add(version, versionConstraints);
|
||||
|
||||
// version
|
||||
final JLabel litVersion = new JLabel("Plus Version : " + RuneLite.PLUS_VERSION);
|
||||
final JLabel litVersion = new JLabel("Plus Version : " + properties.getProperty(RUNELITE_PLUS_VERSION));
|
||||
litVersion.setForeground(Color.GREEN);
|
||||
litVersion.setFont(FontManager.getRunescapeSmallFont());
|
||||
litVersion.setForeground(litVersion.getForeground().darker());
|
||||
final GridBagConstraints litVersionConstraints = new GridBagConstraints();
|
||||
litVersionConstraints.gridy = 3;
|
||||
litVersionConstraints.weightx = 4;
|
||||
panel.add(litVersion, litVersionConstraints);
|
||||
|
||||
// build date
|
||||
final JLabel litBuildDate = new JLabel("Build date : " + properties.getProperty(RUNELITE_PLUS_DATE));
|
||||
litBuildDate.setForeground(Color.GREEN);
|
||||
litBuildDate.setFont(FontManager.getRunescapeSmallFont());
|
||||
litBuildDate.setForeground(litBuildDate.getForeground().darker());
|
||||
final GridBagConstraints litBuildDateConstraints = new GridBagConstraints();
|
||||
litBuildDateConstraints.gridy = 4;
|
||||
panel.add(litBuildDate, litBuildDateConstraints);
|
||||
|
||||
|
||||
// progressbar
|
||||
final GridBagConstraints progressConstraints = new GridBagConstraints();
|
||||
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
progressConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
progressConstraints.gridy = 4;
|
||||
progressConstraints.gridy = 5;
|
||||
panel.add(progressBar, progressConstraints);
|
||||
|
||||
// main message
|
||||
messageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
final GridBagConstraints messageConstraints = new GridBagConstraints();
|
||||
messageConstraints.gridy = 5;
|
||||
messageConstraints.gridy = 6;
|
||||
panel.add(messageLabel, messageConstraints);
|
||||
|
||||
// alternate message
|
||||
final GridBagConstraints subMessageConstraints = new GridBagConstraints();
|
||||
subMessageLabel.setForeground(subMessageLabel.getForeground().darker());
|
||||
subMessageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
subMessageConstraints.gridy = 6;
|
||||
subMessageConstraints.gridy = 7;
|
||||
panel.add(subMessageLabel, subMessageConstraints);
|
||||
|
||||
frame.setContentPane(panel);
|
||||
@@ -235,7 +259,7 @@ public class RuneLiteSplashScreen
|
||||
final GridBagConstraints progressConstraints = new GridBagConstraints();
|
||||
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
progressConstraints.anchor = GridBagConstraints.SOUTH;
|
||||
progressConstraints.gridy = 4;
|
||||
progressConstraints.gridy = 5;
|
||||
panel.add(progressBar, progressConstraints);
|
||||
panel.validate();
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Prayer;
|
||||
import net.runelite.api.TileObject;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.coords.WorldArea;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
@@ -348,7 +349,7 @@ public class OverlayUtil
|
||||
{
|
||||
Widget widget = client.getWidget(prayer.getWidgetInfo());
|
||||
|
||||
if (widget == null || widget.isHidden())
|
||||
if (widget == null || client.getVar(VarClientInt.PLAYER_INTERFACE_CONTAINER_OPENED) != 5)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
runelite.title=RuneLite
|
||||
runelite.version=${project.version}
|
||||
runescape.version=${rs.version}
|
||||
runelite.discord.appid=409416265891971072
|
||||
runelite.version=@project.version@
|
||||
runescape.version=@rs.version@
|
||||
runelite.plus.discord.appid=560644885250572289
|
||||
runelite.discord.invite=https://discord.gg/HN5gf3m
|
||||
runelite.github.link=https://github.com/runelite-extended/runelite
|
||||
runelite.wiki.link=https://github.com/runelite-extended/runelite/wiki
|
||||
runelite.patreon.link=https://www.patreon.com/RuneLitePlus
|
||||
runelit.version =2.0.1-1
|
||||
runelite.plus.title=RuneLitePlus
|
||||
runelite.plus.version=@runelite.plus.version@
|
||||
runelite.plus.builddate=@runelite.plus.builddate@
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>scripts</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>Scripts</name>
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-webdav-jackrabbit</artifactId>
|
||||
<version>2.12</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
</build>
|
||||
</project>
|
||||
Reference in New Issue
Block a user