Merge branch 'master' into spawn
This commit is contained in:
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
@@ -6,7 +6,7 @@ jobs:
|
|||||||
pr-lint:
|
pr-lint:
|
||||||
name: PR title
|
name: PR title
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: PR title lint
|
- name: PR title lint
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
@@ -15,49 +15,55 @@ jobs:
|
|||||||
title-regex: '^([\w-/]+): \w+'
|
title-regex: '^([\w-/]+): \w+'
|
||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: windows-latest
|
runs-on: ubuntu-latest
|
||||||
name: Build
|
name: Build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v1
|
||||||
|
- name: Make gradlew executable
|
||||||
|
run: chmod +x ./gradlew
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@master
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- name: Assembling
|
- name: Assembling
|
||||||
run: gradlew assemble --console=plain
|
run: ./gradlew assemble --console=plain
|
||||||
- name: Building
|
- name: Building
|
||||||
run: gradlew build --stacktrace -x test -x checkstyleMain --console=plain
|
run: ./gradlew build --stacktrace -x test -x checkstyleMain --console=plain
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: windows-latest
|
runs-on: ubuntu-latest
|
||||||
name: Test
|
name: Test
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v1
|
||||||
|
- name: Make gradlew executable
|
||||||
|
run: chmod +x ./gradlew
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@master
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- name: Assembling
|
- name: Assembling
|
||||||
run: gradlew assemble --console=plain
|
run: ./gradlew assemble --console=plain
|
||||||
- name: Testing
|
- name: Testing
|
||||||
run: gradlew test --stacktrace --console=plain
|
run: ./gradlew test --stacktrace --console=plain
|
||||||
|
|
||||||
checkstyle:
|
checkstyle:
|
||||||
name: Checkstyle
|
name: Checkstyle
|
||||||
runs-on: windows-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v1
|
||||||
|
- name: Make gradlew executable
|
||||||
|
run: chmod +x ./gradlew
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@master
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- name: Assembling
|
- name: Assembling
|
||||||
run: gradlew assemble --console=plain
|
run: ./gradlew assemble --console=plain
|
||||||
- name: Checking code conventions
|
- name: Checking code conventions
|
||||||
run: gradlew checkstyleMain --console=plain
|
run: ./gradlew checkstyleMain --console=plain
|
||||||
|
|
||||||
approve:
|
approve:
|
||||||
name: Approve
|
name: Approve
|
||||||
@@ -67,6 +73,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Approve pull request
|
- name: Approve pull request
|
||||||
if: github.event_name == 'pull_request' && github.actor == 'OpenOSRS'
|
if: github.event_name == 'pull_request' && github.actor == 'OpenOSRS'
|
||||||
uses: hmarr/auto-approve-action@master
|
uses: hmarr/auto-approve-action@v2.0.0
|
||||||
with:
|
with:
|
||||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
30
.github/workflows/gradle.yml
vendored
30
.github/workflows/gradle.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v1
|
||||||
- name: Make gradlew executable
|
- name: Make gradlew executable
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
- name: Update Gradle Wrapper
|
- name: Update Gradle Wrapper
|
||||||
@@ -28,17 +28,17 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v1
|
||||||
- name: Make gradlew executable
|
- name: Make gradlew executable
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
- name: Update Gradle dependencies
|
- name: Update Gradle dependencies
|
||||||
run: ./gradlew useLatestVersions --console=plain
|
run: ./gradlew useLatestVersions --console=plain
|
||||||
- name: Create Gradle dependencies update Pull Request
|
- name: Create Gradle dependencies update Pull Request
|
||||||
uses: Owain94/create-pull-request@master
|
uses: Owain94/create-pull-request@master
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.OpenOSRS }}
|
GITHUB_TOKEN: ${{ secrets.OpenOSRS }}
|
||||||
PULL_REQUEST_BRANCH: GRADLE-DEPENDENCY-UPDATE
|
PULL_REQUEST_BRANCH: GRADLE-DEPENDENCY-UPDATE
|
||||||
PULL_REQUEST_TITLE: 'project: Update gradle dependencies'
|
PULL_REQUEST_TITLE: 'project: Update gradle dependencies'
|
||||||
PULL_REQUEST_BODY: This is an auto-generated PR with an updated gradle dependencies versions
|
PULL_REQUEST_BODY: This is an auto-generated PR with an updated gradle dependencies versions
|
||||||
COMMIT_MESSAGE: 'project: Update gradle dependencies'
|
COMMIT_MESSAGE: 'project: Update gradle dependencies'
|
||||||
PULL_REQUEST_LABELS: automated pull request, gradle
|
PULL_REQUEST_LABELS: automated pull request, gradle
|
||||||
6
.github/workflows/scraper.yml
vendored
6
.github/workflows/scraper.yml
vendored
@@ -9,9 +9,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v1
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@master
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
- name: Make gradlew executable
|
- name: Make gradlew executable
|
||||||
@@ -36,4 +36,4 @@ jobs:
|
|||||||
PULL_REQUEST_TITLE: 'Client: Update NPC stats'
|
PULL_REQUEST_TITLE: 'Client: Update NPC stats'
|
||||||
PULL_REQUEST_BODY: This is an auto-generated PR with changes from the OSRS wiki
|
PULL_REQUEST_BODY: This is an auto-generated PR with changes from the OSRS wiki
|
||||||
COMMIT_MESSAGE: 'Client: Update NPC stats'
|
COMMIT_MESSAGE: 'Client: Update NPC stats'
|
||||||
PULL_REQUEST_LABELS: automated pull request, NPC stats
|
PULL_REQUEST_LABELS: automated pull request, NPC stats
|
||||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -19,4 +19,4 @@ jobs:
|
|||||||
exempt-issue-label: 'awaiting-approval'
|
exempt-issue-label: 'awaiting-approval'
|
||||||
exempt-pr-label: 'awaiting-approval'
|
exempt-pr-label: 'awaiting-approval'
|
||||||
days-before-stale: 60
|
days-before-stale: 60
|
||||||
days-before-close: 30
|
days-before-close: 30
|
||||||
@@ -54,3 +54,7 @@ OpenOSRS is licensed under the BSD 2-clause license. See the license header in t
|
|||||||
## Contribute and Develop
|
## Contribute and Develop
|
||||||
|
|
||||||
We've set up a separate document for our [contribution guidelines](https://github.com/open-osrs/runelite/blob/master/.github/CONTRIBUTING.md).
|
We've set up a separate document for our [contribution guidelines](https://github.com/open-osrs/runelite/blob/master/.github/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## Supported By
|
||||||
|
|
||||||
|
OpenOSRS uses profiling tools provided by [](https://www.yourkit.com/java/profiler/)
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ public final class AnimationID
|
|||||||
// INFERNO animations
|
// INFERNO animations
|
||||||
public static final int JAL_NIB = 7574;
|
public static final int JAL_NIB = 7574;
|
||||||
public static final int JAL_MEJRAH = 7578;
|
public static final int JAL_MEJRAH = 7578;
|
||||||
|
public static final int JAL_MEJRAH_STAND = 7577;
|
||||||
public static final int JAL_AK_RANGE_ATTACK = 7581;
|
public static final int JAL_AK_RANGE_ATTACK = 7581;
|
||||||
public static final int JAL_AK_MELEE_ATTACK = 7582;
|
public static final int JAL_AK_MELEE_ATTACK = 7582;
|
||||||
public static final int JAL_AK_MAGIC_ATTACK = 7583;
|
public static final int JAL_AK_MAGIC_ATTACK = 7583;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,7 @@ import javax.inject.Singleton;
|
|||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.SpriteID;
|
import net.runelite.api.SpriteID;
|
||||||
import net.runelite.client.game.SpriteManager;
|
import net.runelite.client.game.SpriteManager;
|
||||||
|
import net.runelite.client.plugins.inferno.displaymodes.InfernoPrayerDisplayMode;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||||
@@ -41,16 +42,19 @@ import net.runelite.client.ui.overlay.components.ImageComponent;
|
|||||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class InfernoJadOverlay extends Overlay
|
public class InfernoInfoBoxOverlay extends Overlay
|
||||||
{
|
{
|
||||||
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
private static final Color NOT_ACTIVATED_BACKGROUND_COLOR = new Color(150, 0, 0, 150);
|
||||||
private final Client client;
|
private final Client client;
|
||||||
private final InfernoPlugin plugin;
|
private final InfernoPlugin plugin;
|
||||||
private final SpriteManager spriteManager;
|
private final SpriteManager spriteManager;
|
||||||
private final PanelComponent imagePanelComponent = new PanelComponent();
|
private final PanelComponent imagePanelComponent = new PanelComponent();
|
||||||
|
private BufferedImage prayMeleeSprite;
|
||||||
|
private BufferedImage prayRangedSprite;
|
||||||
|
private BufferedImage prayMagicSprite;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private InfernoJadOverlay(final Client client, final InfernoPlugin plugin, final SpriteManager spriteManager)
|
private InfernoInfoBoxOverlay(final Client client, final InfernoPlugin plugin, final SpriteManager spriteManager)
|
||||||
{
|
{
|
||||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||||
setPriority(OverlayPriority.HIGH);
|
setPriority(OverlayPriority.HIGH);
|
||||||
@@ -62,48 +66,56 @@ public class InfernoJadOverlay extends Overlay
|
|||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
if (!plugin.isShowPrayerHelp() || (plugin.getPrayerOverlayMode() != InfernoPrayerOverlayMode.BOTTOM_RIGHT
|
if (plugin.getPrayerDisplayMode() != InfernoPrayerDisplayMode.BOTTOM_RIGHT
|
||||||
&& plugin.getPrayerOverlayMode() != InfernoPrayerOverlayMode.BOTH))
|
&& plugin.getPrayerDisplayMode() != InfernoPrayerDisplayMode.BOTH)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfernoJad.Attack attack = null;
|
|
||||||
int leastTicks = 999;
|
|
||||||
|
|
||||||
for (InfernoJad jad : plugin.getJads())
|
|
||||||
{
|
|
||||||
if (jad.getNextAttack() == null || jad.getTicksTillNextAttack() < 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jad.getTicksTillNextAttack() < leastTicks)
|
|
||||||
{
|
|
||||||
leastTicks = jad.getTicksTillNextAttack();
|
|
||||||
attack = jad.getNextAttack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attack == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final BufferedImage prayerImage = getPrayerImage(attack);
|
|
||||||
|
|
||||||
imagePanelComponent.getChildren().clear();
|
imagePanelComponent.getChildren().clear();
|
||||||
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
|
||||||
imagePanelComponent.setBackgroundColor(client.isPrayerActive(attack.getPrayer())
|
if (plugin.getClosestAttack() != null)
|
||||||
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
{
|
||||||
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
final BufferedImage prayerImage = getPrayerImage(plugin.getClosestAttack());
|
||||||
|
|
||||||
|
imagePanelComponent.getChildren().add(new ImageComponent(prayerImage));
|
||||||
|
imagePanelComponent.setBackgroundColor(client.isPrayerActive(plugin.getClosestAttack().getPrayer())
|
||||||
|
? ComponentConstants.STANDARD_BACKGROUND_COLOR
|
||||||
|
: NOT_ACTIVATED_BACKGROUND_COLOR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imagePanelComponent.setBackgroundColor(ComponentConstants.STANDARD_BACKGROUND_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
return imagePanelComponent.render(graphics);
|
return imagePanelComponent.render(graphics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BufferedImage getPrayerImage(InfernoJad.Attack attack)
|
private BufferedImage getPrayerImage(InfernoNPC.Attack attack)
|
||||||
{
|
{
|
||||||
final int prayerSpriteID = attack == InfernoJad.Attack.MAGIC ? SpriteID.PRAYER_PROTECT_FROM_MAGIC : SpriteID.PRAYER_PROTECT_FROM_MISSILES;
|
if (prayMeleeSprite == null)
|
||||||
return spriteManager.getSprite(prayerSpriteID, 0);
|
{
|
||||||
|
prayMeleeSprite = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MELEE, 0);
|
||||||
|
}
|
||||||
|
if (prayRangedSprite == null)
|
||||||
|
{
|
||||||
|
prayRangedSprite = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MISSILES, 0);
|
||||||
|
}
|
||||||
|
if (prayMagicSprite == null)
|
||||||
|
{
|
||||||
|
prayMagicSprite = spriteManager.getSprite(SpriteID.PRAYER_PROTECT_FROM_MAGIC, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (attack)
|
||||||
|
{
|
||||||
|
case MELEE:
|
||||||
|
return prayMeleeSprite;
|
||||||
|
case RANGED:
|
||||||
|
return prayRangedSprite;
|
||||||
|
case MAGIC:
|
||||||
|
return prayMagicSprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prayMagicSprite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.client.plugins.inferno;
|
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.AnimationID;
|
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.Prayer;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
public class InfernoJad
|
|
||||||
{
|
|
||||||
private static final int TICKS_AFTER_ANIMATION = 4;
|
|
||||||
|
|
||||||
private NPC npc;
|
|
||||||
private Attack nextAttack;
|
|
||||||
private int ticksTillNextAttack;
|
|
||||||
|
|
||||||
InfernoJad(NPC npc)
|
|
||||||
{
|
|
||||||
this.npc = npc;
|
|
||||||
nextAttack = null;
|
|
||||||
ticksTillNextAttack = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateNextAttack(Attack nextAttack)
|
|
||||||
{
|
|
||||||
this.nextAttack = nextAttack;
|
|
||||||
this.ticksTillNextAttack = TICKS_AFTER_ANIMATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gameTick()
|
|
||||||
{
|
|
||||||
if (ticksTillNextAttack < 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.ticksTillNextAttack--;
|
|
||||||
|
|
||||||
if (ticksTillNextAttack < 0)
|
|
||||||
{
|
|
||||||
nextAttack = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
enum Attack
|
|
||||||
{
|
|
||||||
MAGIC(AnimationID.JALTOK_JAD_MAGE_ATTACK, Prayer.PROTECT_FROM_MAGIC),
|
|
||||||
RANGE(AnimationID.JALTOK_JAD_RANGE_ATTACK, Prayer.PROTECT_FROM_MISSILES);
|
|
||||||
|
|
||||||
private final int animation;
|
|
||||||
private final Prayer prayer;
|
|
||||||
|
|
||||||
Attack(final int animation, final Prayer prayer)
|
|
||||||
{
|
|
||||||
this.animation = animation;
|
|
||||||
this.prayer = prayer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
* list of conditions and the following disclaimer.
|
* list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
* 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
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
@@ -25,162 +25,376 @@
|
|||||||
package net.runelite.client.plugins.inferno;
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import net.runelite.api.AnimationID;
|
||||||
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
import net.runelite.api.NpcID;
|
import net.runelite.api.NpcID;
|
||||||
|
import net.runelite.api.Prayer;
|
||||||
|
import net.runelite.api.coords.WorldArea;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
public class InfernoNPC
|
public class InfernoNPC
|
||||||
{
|
{
|
||||||
public enum Attackstyle
|
|
||||||
{
|
|
||||||
MAGE("Mage", Color.CYAN),
|
|
||||||
RANGE("Range", Color.GREEN),
|
|
||||||
MELEE("Melee", Color.WHITE),
|
|
||||||
RANDOM("Random", Color.ORANGE);
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private Color color;
|
|
||||||
|
|
||||||
Attackstyle(String s, Color c)
|
|
||||||
{
|
|
||||||
this.name = s;
|
|
||||||
this.color = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private NPC npc;
|
private NPC npc;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private String name;
|
private Type type;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
@Setter(AccessLevel.PACKAGE)
|
private Attack nextAttack;
|
||||||
private Attackstyle attackstyle;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private int attackTicks;
|
private int ticksTillNextAttack;
|
||||||
|
private int lastAnimation;
|
||||||
@Getter(AccessLevel.PACKAGE)
|
private boolean lastCanAttack;
|
||||||
private int priority;
|
//0 = not in LOS, 1 = in LOS after move, 2 = in LOS
|
||||||
|
private final Map<WorldPoint, Integer> safeSpotCache;
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
@Setter(AccessLevel.PACKAGE)
|
|
||||||
private int ticksTillAttack = -1;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
@Setter(AccessLevel.PACKAGE)
|
|
||||||
private boolean attacking = false;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private int attackAnimation;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private boolean isMidAttack = false;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
@Setter(AccessLevel.PACKAGE)
|
|
||||||
private int distanceToPlayer = 0;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
int textLocHeight;
|
|
||||||
|
|
||||||
InfernoNPC(NPC npc)
|
InfernoNPC(NPC npc)
|
||||||
{
|
{
|
||||||
this.npc = npc;
|
this.npc = npc;
|
||||||
textLocHeight = npc.getLogicalHeight() + 40;
|
this.type = Type.typeFromId(npc.getId());
|
||||||
switch (npc.getId())
|
this.nextAttack = type.getDefaultAttack();
|
||||||
|
this.ticksTillNextAttack = 0;
|
||||||
|
this.lastAnimation = -1;
|
||||||
|
this.lastCanAttack = false;
|
||||||
|
this.safeSpotCache = new HashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateNextAttack(Attack nextAttack, int ticksTillNextAttack)
|
||||||
|
{
|
||||||
|
this.nextAttack = nextAttack;
|
||||||
|
this.ticksTillNextAttack = ticksTillNextAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateNextAttack(Attack nextAttack)
|
||||||
|
{
|
||||||
|
this.nextAttack = nextAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean canAttack(Client client, WorldPoint target)
|
||||||
|
{
|
||||||
|
if (safeSpotCache.containsKey(target))
|
||||||
{
|
{
|
||||||
case NpcID.JALAKREKKET:
|
return safeSpotCache.get(target) == 2;
|
||||||
attackTicks = 4;
|
}
|
||||||
name = "lil mel";
|
|
||||||
attackAnimation = 7582;
|
|
||||||
attackstyle = Attackstyle.MELEE;
|
|
||||||
priority = 7;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NpcID.JALAKREKXIL:
|
boolean hasLos = new WorldArea(target, 1, 1).hasLineOfSightTo(client, this.getNpc().getWorldArea());
|
||||||
attackTicks = 4;
|
boolean hasRange = this.getType().getDefaultAttack() == Attack.MELEE ? this.getNpc().getWorldArea().isInMeleeDistance(target)
|
||||||
name = "lil range";
|
: this.getNpc().getWorldArea().distanceTo(target) <= this.getType().getRange();
|
||||||
attackAnimation = 7583;
|
|
||||||
attackstyle = Attackstyle.RANGE;
|
|
||||||
priority = 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NpcID.JALAKREKMEJ:
|
if (hasLos && hasRange)
|
||||||
attackTicks = 4;
|
{
|
||||||
name = "lil mage";
|
safeSpotCache.put(target, 2);
|
||||||
attackAnimation = 7581;
|
}
|
||||||
attackstyle = Attackstyle.MAGE;
|
|
||||||
priority = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NpcID.JALMEJRAH:
|
return hasLos && hasRange;
|
||||||
attackTicks = 3;
|
}
|
||||||
name = "bat";
|
|
||||||
attackAnimation = 7578;
|
|
||||||
attackstyle = Attackstyle.RANGE;
|
|
||||||
priority = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NpcID.JALAK:
|
boolean canMoveToAttack(Client client, WorldPoint target, List<WorldPoint> obstacles)
|
||||||
attackTicks = 6;
|
{
|
||||||
name = "blob";
|
if (safeSpotCache.containsKey(target))
|
||||||
attackAnimation = 7583; // also 7581
|
{
|
||||||
attackstyle = Attackstyle.RANDOM;
|
return safeSpotCache.get(target) == 1 || safeSpotCache.get(target) == 2;
|
||||||
priority = 3;
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case NpcID.JALIMKOT:
|
final List<WorldPoint> realObstacles = new ArrayList<>();
|
||||||
attackTicks = 4;
|
for (WorldPoint obstacle : obstacles)
|
||||||
name = "meleer";
|
{
|
||||||
attackAnimation = 7597;
|
if (this.getNpc().getWorldArea().toWorldPointList().contains(obstacle))
|
||||||
attackstyle = Attackstyle.MELEE;
|
{
|
||||||
priority = 2;
|
continue;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case NpcID.JALXIL:
|
realObstacles.add(obstacle);
|
||||||
attackTicks = 4;
|
}
|
||||||
name = "ranger";
|
|
||||||
attackAnimation = 7605;
|
|
||||||
attackstyle = Attackstyle.RANGE;
|
|
||||||
priority = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NpcID.JALZEK:
|
final WorldArea targetArea = new WorldArea(target, 1, 1);
|
||||||
attackTicks = 4;
|
WorldArea currentWorldArea = this.getNpc().getWorldArea();
|
||||||
name = "mager";
|
|
||||||
attackAnimation = 7610;
|
|
||||||
attackstyle = Attackstyle.MAGE;
|
|
||||||
priority = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
int steps = 0;
|
||||||
attackTicks = 0;
|
while (true)
|
||||||
|
{
|
||||||
|
// Prevent infinite loop in case of pathfinding failure
|
||||||
|
steps++;
|
||||||
|
if (steps > 30)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final WorldArea predictedWorldArea = currentWorldArea.calculateNextTravellingPoint(client, targetArea, true, x ->
|
||||||
|
{
|
||||||
|
for (WorldPoint obstacle : realObstacles)
|
||||||
|
{
|
||||||
|
if (new WorldArea(x, 1, 1).intersectsWith(new WorldArea(obstacle, 1, 1)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Will only happen when NPC is underneath player or moving out of scene (but this will never show on overlay)
|
||||||
|
if (predictedWorldArea == null)
|
||||||
|
{
|
||||||
|
safeSpotCache.put(target, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (predictedWorldArea == currentWorldArea)
|
||||||
|
{
|
||||||
|
safeSpotCache.put(target, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasLos = new WorldArea(target, 1, 1).hasLineOfSightTo(client, predictedWorldArea);
|
||||||
|
boolean hasRange = this.getType().getDefaultAttack() == Attack.MELEE ? predictedWorldArea.isInMeleeDistance(target)
|
||||||
|
: predictedWorldArea.distanceTo(target) <= this.getType().getRange();
|
||||||
|
|
||||||
|
if (hasLos && hasRange)
|
||||||
|
{
|
||||||
|
safeSpotCache.put(target, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentWorldArea = predictedWorldArea;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String info()
|
private boolean couldAttackPrevTick(Client client, WorldPoint lastPlayerLocation)
|
||||||
{
|
{
|
||||||
String info = "";
|
return new WorldArea(lastPlayerLocation, 1, 1).hasLineOfSightTo(client, this.getNpc().getWorldArea());
|
||||||
|
|
||||||
if (attacking)
|
|
||||||
{
|
|
||||||
info += ticksTillAttack;
|
|
||||||
}
|
|
||||||
//info += " D: " + distanceToPlayer;
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void attacked()
|
void gameTick(Client client, WorldPoint lastPlayerLocation, boolean finalPhase)
|
||||||
{
|
{
|
||||||
ticksTillAttack = attackTicks;
|
safeSpotCache.clear();
|
||||||
attacking = true;
|
|
||||||
|
if (ticksTillNextAttack > 0)
|
||||||
|
{
|
||||||
|
this.ticksTillNextAttack--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Jad animation detection
|
||||||
|
if (this.getType() == Type.JAD && this.getNpc().getAnimation() != -1 && this.getNpc().getAnimation() != this.lastAnimation)
|
||||||
|
{
|
||||||
|
final InfernoNPC.Attack currentAttack = InfernoNPC.Attack.attackFromId(this.getNpc().getAnimation());
|
||||||
|
|
||||||
|
if (currentAttack != null && currentAttack != Attack.UNKNOWN)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(currentAttack, this.getType().getTicksAfterAnimation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ticksTillNextAttack <= 0)
|
||||||
|
{
|
||||||
|
switch (this.getType())
|
||||||
|
{
|
||||||
|
case ZUK:
|
||||||
|
if (this.getNpc().getAnimation() == AnimationID.TZKAL_ZUK)
|
||||||
|
{
|
||||||
|
if (finalPhase)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), 7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JAD:
|
||||||
|
if (this.getNextAttack() != Attack.UNKNOWN)
|
||||||
|
{
|
||||||
|
// Jad's cycle continuous after his animation + attack but there's no animation to alert it
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BLOB:
|
||||||
|
//RS pathfinding + LOS = hell, so if it can attack you the tick you were on previously, start attack cycle
|
||||||
|
if (!this.lastCanAttack && this.couldAttackPrevTick(client, lastPlayerLocation))
|
||||||
|
{
|
||||||
|
this.updateNextAttack(Attack.UNKNOWN, 3);
|
||||||
|
}
|
||||||
|
//If there's no animation when coming out of the safespot, the blob is detecting prayer
|
||||||
|
else if (!this.lastCanAttack && this.canAttack(client, client.getLocalPlayer().getWorldLocation()))
|
||||||
|
{
|
||||||
|
this.updateNextAttack(Attack.UNKNOWN, 4);
|
||||||
|
}
|
||||||
|
//This will activate another attack cycle
|
||||||
|
else if (this.getNpc().getAnimation() != -1)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), this.getType().getTicksAfterAnimation());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BAT:
|
||||||
|
// Range + LOS check for bat because it suffers from the defense animation bug, also dont activate on "stand" animation
|
||||||
|
if (this.canAttack(client, client.getLocalPlayer().getWorldLocation())
|
||||||
|
&& this.getNpc().getAnimation() != AnimationID.JAL_MEJRAH_STAND && this.getNpc().getAnimation() != -1)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), this.getType().getTicksAfterAnimation());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MELEE:
|
||||||
|
case RANGER:
|
||||||
|
case MAGE:
|
||||||
|
// For the meleer, ranger and mage the attack animation is always prioritized so only check for those
|
||||||
|
// Normal attack animation, doesnt suffer from defense animation bug. Activate usual attack cycle
|
||||||
|
if (this.getNpc().getAnimation() == AnimationID.JAL_IMKOT
|
||||||
|
|| this.getNpc().getAnimation() == AnimationID.JAL_XIL_RANGE_ATTACK || this.getNpc().getAnimation() == AnimationID.JAL_XIL_MELEE_ATTACK
|
||||||
|
|| this.getNpc().getAnimation() == AnimationID.JAL_ZEK_MAGE_ATTACK || this.getNpc().getAnimation() == AnimationID.JAL_ZEK_MELEE_ATTACK)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), this.getType().getTicksAfterAnimation());
|
||||||
|
}
|
||||||
|
// Burrow into ground animation for meleer
|
||||||
|
else if (this.getNpc().getAnimation() == 7600)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), 12);
|
||||||
|
}
|
||||||
|
// Respawn enemy animation for mage
|
||||||
|
else if (this.getNpc().getAnimation() == 7611)
|
||||||
|
{
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (this.getNpc().getAnimation() != -1)
|
||||||
|
{
|
||||||
|
// This will activate another attack cycle
|
||||||
|
this.updateNextAttack(this.getType().getDefaultAttack(), this.getType().getTicksAfterAnimation());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Blob prayer detection
|
||||||
|
if (this.getType() == Type.BLOB && this.getTicksTillNextAttack() == 3
|
||||||
|
&& client.getLocalPlayer().getWorldLocation().distanceTo(this.getNpc().getWorldArea()) <= Type.BLOB.getRange())
|
||||||
|
{
|
||||||
|
InfernoNPC.Attack nextBlobAttack = InfernoNPC.Attack.UNKNOWN;
|
||||||
|
if (client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES))
|
||||||
|
{
|
||||||
|
nextBlobAttack = InfernoNPC.Attack.MAGIC;
|
||||||
|
}
|
||||||
|
else if (client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC))
|
||||||
|
{
|
||||||
|
nextBlobAttack = InfernoNPC.Attack.RANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateNextAttack(nextBlobAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is for jad (jad's animation lasts till after the attack is launched, which fucks up the attack cycle)
|
||||||
|
lastAnimation = this.getNpc().getAnimation();
|
||||||
|
// This is for blob (to check if player just came out of safespot)
|
||||||
|
lastCanAttack = this.canAttack(client, client.getLocalPlayer().getWorldLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
enum Attack
|
||||||
|
{
|
||||||
|
MELEE(Prayer.PROTECT_FROM_MELEE,
|
||||||
|
Color.ORANGE,
|
||||||
|
Color.RED,
|
||||||
|
new int[]{
|
||||||
|
AnimationID.JAL_NIB,
|
||||||
|
AnimationID.JAL_AK_MELEE_ATTACK,
|
||||||
|
AnimationID.JAL_IMKOT,
|
||||||
|
AnimationID.JAL_XIL_MELEE_ATTACK,
|
||||||
|
AnimationID.JAL_ZEK_MELEE_ATTACK, //TODO: Yt-HurKot attack animation
|
||||||
|
}),
|
||||||
|
RANGED(Prayer.PROTECT_FROM_MISSILES,
|
||||||
|
Color.GREEN,
|
||||||
|
new Color(0, 128, 0),
|
||||||
|
new int[]{
|
||||||
|
AnimationID.JAL_MEJRAH,
|
||||||
|
AnimationID.JAL_AK_RANGE_ATTACK,
|
||||||
|
AnimationID.JAL_XIL_RANGE_ATTACK,
|
||||||
|
AnimationID.JALTOK_JAD_RANGE_ATTACK,
|
||||||
|
}),
|
||||||
|
MAGIC(Prayer.PROTECT_FROM_MAGIC,
|
||||||
|
Color.CYAN,
|
||||||
|
Color.BLUE,
|
||||||
|
new int[]{
|
||||||
|
AnimationID.JAL_AK_MAGIC_ATTACK,
|
||||||
|
AnimationID.JAL_ZEK_MAGE_ATTACK,
|
||||||
|
AnimationID.JALTOK_JAD_MAGE_ATTACK
|
||||||
|
}),
|
||||||
|
UNKNOWN(null, Color.WHITE, Color.GRAY, new int[]{});
|
||||||
|
|
||||||
|
private final Prayer prayer;
|
||||||
|
private final Color normalColor;
|
||||||
|
private final Color criticalColor;
|
||||||
|
private final int[] animationIds;
|
||||||
|
|
||||||
|
Attack(Prayer prayer, Color normalColor, Color criticalColor, int[] animationIds)
|
||||||
|
{
|
||||||
|
this.prayer = prayer;
|
||||||
|
this.normalColor = normalColor;
|
||||||
|
this.criticalColor = criticalColor;
|
||||||
|
this.animationIds = animationIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Attack attackFromId(int animationId)
|
||||||
|
{
|
||||||
|
for (Attack attack : Attack.values())
|
||||||
|
{
|
||||||
|
if (ArrayUtils.contains(attack.getAnimationIds(), animationId))
|
||||||
|
{
|
||||||
|
return attack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
NIBBLER(new int[]{NpcID.JALNIB}, Attack.MELEE, 4, 99, 100),
|
||||||
|
BAT(new int[]{NpcID.JALMEJRAH}, Attack.RANGED, 3, 4, 7),
|
||||||
|
BLOB(new int[]{NpcID.JALAK}, Attack.UNKNOWN, 6, 15, 4),
|
||||||
|
MELEE(new int[]{NpcID.JALIMKOT}, Attack.MELEE, 4, 1, 3),
|
||||||
|
RANGER(new int[]{NpcID.JALXIL, NpcID.JALXIL_7702}, Attack.RANGED, 4, 98, 2),
|
||||||
|
MAGE(new int[]{NpcID.JALZEK, NpcID.JALZEK_7703}, Attack.MAGIC, 4, 98, 1),
|
||||||
|
JAD(new int[]{NpcID.JALTOKJAD, NpcID.JALTOKJAD_7704}, Attack.UNKNOWN, 3, 99, 0),
|
||||||
|
HEALER_JAD(new int[]{NpcID.YTHURKOT, NpcID.YTHURKOT_7701, NpcID.YTHURKOT_7705}, Attack.MELEE, 4, 1, 6),
|
||||||
|
ZUK(new int[]{NpcID.TZKALZUK}, Attack.UNKNOWN, 10, 99, 99),
|
||||||
|
HEALER_ZUK(new int[]{NpcID.JALMEJJAK}, Attack.UNKNOWN, -1, 99, 100);
|
||||||
|
|
||||||
|
private final int[] npcIds;
|
||||||
|
private final Attack defaultAttack;
|
||||||
|
private final int ticksAfterAnimation;
|
||||||
|
private final int range;
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
|
Type(int[] npcIds, Attack defaultAttack, int ticksAfterAnimation, int range, int priority)
|
||||||
|
{
|
||||||
|
this.npcIds = npcIds;
|
||||||
|
this.defaultAttack = defaultAttack;
|
||||||
|
this.ticksAfterAnimation = ticksAfterAnimation;
|
||||||
|
this.range = range;
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Type typeFromId(int npcId)
|
||||||
|
{
|
||||||
|
for (Type type : Type.values())
|
||||||
|
{
|
||||||
|
if (ArrayUtils.contains(type.getNpcIds(), npcId))
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.client.plugins.inferno;
|
|
||||||
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
|
||||||
import net.runelite.client.ui.overlay.components.table.TableAlignment;
|
|
||||||
import net.runelite.client.ui.overlay.components.table.TableComponent;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class InfernoNibblerOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private final Client client;
|
|
||||||
private final InfernoPlugin plugin;
|
|
||||||
|
|
||||||
private final PanelComponent panelComponent = new PanelComponent();
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public InfernoNibblerOverlay(final Client client, final InfernoPlugin plugin)
|
|
||||||
{
|
|
||||||
this.client = client;
|
|
||||||
this.plugin = plugin;
|
|
||||||
setPosition(OverlayPosition.TOP_LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
if (!plugin.isDisplayNibblerOverlay() || plugin.getNibblers().size() == 0 || client.getMapRegions()[0] != 9043)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
panelComponent.getChildren().clear();
|
|
||||||
TableComponent tableComponent = new TableComponent();
|
|
||||||
tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT);
|
|
||||||
|
|
||||||
tableComponent.addRow("Nibblers Left: ", Integer.toString(plugin.getNibblers().size()));
|
|
||||||
|
|
||||||
panelComponent.getChildren().add(tableComponent);
|
|
||||||
|
|
||||||
return panelComponent.render(graphics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +1,46 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Jacky <liangj97@gmail.com>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.client.plugins.inferno;
|
package net.runelite.client.plugins.inferno;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.Perspective;
|
import net.runelite.api.Perspective;
|
||||||
import net.runelite.api.Point;
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Prayer;
|
||||||
import net.runelite.api.coords.LocalPoint;
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.plugins.inferno.displaymodes.InfernoPrayerDisplayMode;
|
||||||
|
import net.runelite.client.plugins.inferno.displaymodes.InfernoSafespotDisplayMode;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class InfernoOverlay extends Overlay
|
public class InfernoOverlay extends Overlay
|
||||||
{
|
{
|
||||||
private final Client client;
|
private static final int TICK_PIXEL_SIZE = 60;
|
||||||
|
private static final int BOX_WIDTH = 10;
|
||||||
|
private static final int BOX_HEIGHT = 5;
|
||||||
|
|
||||||
private final InfernoPlugin plugin;
|
private final InfernoPlugin plugin;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public InfernoOverlay(final Client client, final InfernoPlugin plugin)
|
private InfernoOverlay(final Client client, final InfernoPlugin plugin)
|
||||||
{
|
{
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||||
|
setPriority(OverlayPriority.HIGHEST);
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
@@ -58,55 +48,426 @@ public class InfernoOverlay extends Overlay
|
|||||||
@Override
|
@Override
|
||||||
public Dimension render(Graphics2D graphics)
|
public Dimension render(Graphics2D graphics)
|
||||||
{
|
{
|
||||||
if (!client.isInInstancedRegion() || client.getMapRegions()[0] != 9043)
|
final Widget meleePrayerWidget = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MELEE);
|
||||||
|
final Widget rangePrayerWidget = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES);
|
||||||
|
final Widget magicPrayerWidget = client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC);
|
||||||
|
|
||||||
|
if (plugin.isIndicateObstacles())
|
||||||
{
|
{
|
||||||
return null;
|
renderObstacles(graphics);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (InfernoNPC monster : plugin.getMonsters().values())
|
if (plugin.getSafespotDisplayMode() == InfernoSafespotDisplayMode.AREA)
|
||||||
{
|
{
|
||||||
NPC npc = monster.getNpc();
|
renderAreaSafepots(graphics);
|
||||||
//if (npc == null || !config.showPrayer()) return;
|
}
|
||||||
LocalPoint lp = npc.getLocalLocation();
|
else if (plugin.getSafespotDisplayMode() == InfernoSafespotDisplayMode.INDIVIDUAL_TILES)
|
||||||
if (lp != null)
|
{
|
||||||
|
renderIndividualTilesSafespots(graphics);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (InfernoNPC infernoNPC : plugin.getInfernoNpcs())
|
||||||
|
{
|
||||||
|
if (infernoNPC.getNpc().getConvexHull() != null)
|
||||||
{
|
{
|
||||||
Point point = Perspective.localToCanvas(client, lp, client.getPlane(), npc.getLogicalHeight());
|
if (plugin.isIndicateNonSafespotted() && plugin.isNormalSafespots(infernoNPC)
|
||||||
if (point != null)
|
&& infernoNPC.canAttack(client, client.getLocalPlayer().getWorldLocation()))
|
||||||
{
|
{
|
||||||
if (monster.getTicksTillAttack() == 1 || (monster.getName().equals("blob") && monster.getTicksTillAttack() <= 3))
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.RED);
|
||||||
{
|
}
|
||||||
renderTextLocation(graphics, monster, monster.info(), Color.GREEN);
|
if (plugin.isIndicateTemporarySafespotted() && plugin.isNormalSafespots(infernoNPC)
|
||||||
}
|
&& infernoNPC.canMoveToAttack(client, client.getLocalPlayer().getWorldLocation(), plugin.getObstacles()))
|
||||||
else
|
{
|
||||||
{
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.YELLOW);
|
||||||
renderTextLocation(graphics, monster, monster.info(), Color.RED);
|
}
|
||||||
}
|
if (plugin.isIndicateSafespotted() && plugin.isNormalSafespots(infernoNPC))
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.GREEN);
|
||||||
|
}
|
||||||
|
if (plugin.isIndicateNibblers() && infernoNPC.getType() == InfernoNPC.Type.NIBBLER
|
||||||
|
&& (!plugin.isIndicateCentralNibbler() || plugin.getCentralNibbler() != infernoNPC))
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.CYAN);
|
||||||
|
}
|
||||||
|
if (plugin.isIndicateCentralNibbler() && infernoNPC.getType() == InfernoNPC.Type.NIBBLER
|
||||||
|
&& plugin.getCentralNibbler() == infernoNPC)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.BLUE);
|
||||||
|
}
|
||||||
|
if (plugin.isIndicateActiveHealersJad() && infernoNPC.getType() == InfernoNPC.Type.HEALER_JAD
|
||||||
|
&& infernoNPC.getNpc().getInteracting() != client.getLocalPlayer())
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.CYAN);
|
||||||
|
}
|
||||||
|
if (plugin.isIndicateActiveHealersZuk() && infernoNPC.getType() == InfernoNPC.Type.HEALER_ZUK
|
||||||
|
&& infernoNPC.getNpc().getInteracting() != client.getLocalPlayer())
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, infernoNPC.getNpc().getConvexHull(), Color.CYAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (plugin.isIndicateNpcPosition(infernoNPC))
|
||||||
|
{
|
||||||
|
renderNpcLocation(graphics, infernoNPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.isTicksOnNpc(infernoNPC) && infernoNPC.getTicksTillNextAttack() > 0)
|
||||||
|
{
|
||||||
|
renderTicksOnNpc(graphics, infernoNPC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((plugin.getPrayerDisplayMode() == InfernoPrayerDisplayMode.PRAYER_TAB
|
||||||
|
|| plugin.getPrayerDisplayMode() == InfernoPrayerDisplayMode.BOTH)
|
||||||
|
&& (meleePrayerWidget != null && !meleePrayerWidget.isHidden()
|
||||||
|
&& rangePrayerWidget != null && !rangePrayerWidget.isHidden()
|
||||||
|
&& magicPrayerWidget != null && !magicPrayerWidget.isHidden()))
|
||||||
|
{
|
||||||
|
renderPrayerIconOverlay(graphics);
|
||||||
|
|
||||||
|
if (plugin.isDescendingBoxes())
|
||||||
|
{
|
||||||
|
renderDescendingBoxes(graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// renders text location
|
private void renderObstacles(Graphics2D graphics)
|
||||||
private static void renderTextLocation(Graphics2D graphics, InfernoNPC actor, String text, Color color)
|
|
||||||
{
|
{
|
||||||
graphics.setFont(new Font("Arial", Font.BOLD, 15));
|
for (WorldPoint worldPoint : plugin.getObstacles())
|
||||||
Point textLocation = actor.getNpc().getCanvasTextLocation(graphics, text, actor.textLocHeight + 40);
|
|
||||||
if (Strings.isNullOrEmpty(text))
|
|
||||||
{
|
{
|
||||||
return;
|
final LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||||
}
|
|
||||||
|
|
||||||
if (textLocation != null)
|
if (localPoint == null)
|
||||||
{
|
{
|
||||||
int x = textLocation.getX();
|
continue;
|
||||||
int y = textLocation.getY();
|
}
|
||||||
|
|
||||||
graphics.setColor(Color.BLACK);
|
final Polygon tilePoly = Perspective.getCanvasTilePoly(client, localPoint);
|
||||||
graphics.drawString(text, x + 1, y + 1);
|
|
||||||
|
|
||||||
graphics.setColor(color);
|
if (tilePoly == null)
|
||||||
graphics.drawString(text, x, y);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayUtil.renderPolygon(graphics, tilePoly, Color.BLUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderAreaSafepots(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
for (int safeSpotId : plugin.getSafeSpotAreas().keySet())
|
||||||
|
{
|
||||||
|
if (safeSpotId > 6)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color colorEdge1 = null;
|
||||||
|
Color colorEdge2 = null;
|
||||||
|
Color colorFill = null;
|
||||||
|
|
||||||
|
switch (safeSpotId)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
colorEdge1 = Color.WHITE;
|
||||||
|
colorFill = Color.WHITE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
colorEdge1 = Color.RED;
|
||||||
|
colorFill = Color.RED;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
colorEdge1 = Color.GREEN;
|
||||||
|
colorFill = Color.GREEN;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
colorEdge1 = Color.BLUE;
|
||||||
|
colorFill = Color.BLUE;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
colorEdge1 = Color.RED;
|
||||||
|
colorEdge2 = Color.GREEN;
|
||||||
|
colorFill = Color.YELLOW;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
colorEdge1 = Color.RED;
|
||||||
|
colorEdge2 = Color.BLUE;
|
||||||
|
colorFill = new Color(255, 0, 255);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
colorEdge1 = Color.GREEN;
|
||||||
|
colorEdge2 = Color.BLUE;
|
||||||
|
colorFill = new Color(0, 255, 255);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add all edges, calculate average edgeSize and indicate tiles
|
||||||
|
final List<int[][]> allEdges = new ArrayList<>();
|
||||||
|
int edgeSizeSquared = 0;
|
||||||
|
|
||||||
|
for (WorldPoint worldPoint : plugin.getSafeSpotAreas().get(safeSpotId))
|
||||||
|
{
|
||||||
|
final LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||||
|
|
||||||
|
if (localPoint == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Polygon tilePoly = Perspective.getCanvasTilePoly(client, localPoint);
|
||||||
|
|
||||||
|
if (tilePoly == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayUtil.renderAreaTilePolygon(graphics, tilePoly, colorFill);
|
||||||
|
|
||||||
|
final int[][] edge1 = new int[][]{{tilePoly.xpoints[0], tilePoly.ypoints[0]}, {tilePoly.xpoints[1], tilePoly.ypoints[1]}};
|
||||||
|
edgeSizeSquared += Math.pow(tilePoly.xpoints[0] - tilePoly.xpoints[1], 2) + Math.pow(tilePoly.ypoints[0] - tilePoly.ypoints[1], 2);
|
||||||
|
allEdges.add(edge1);
|
||||||
|
final int[][] edge2 = new int[][]{{tilePoly.xpoints[1], tilePoly.ypoints[1]}, {tilePoly.xpoints[2], tilePoly.ypoints[2]}};
|
||||||
|
edgeSizeSquared += Math.pow(tilePoly.xpoints[1] - tilePoly.xpoints[2], 2) + Math.pow(tilePoly.ypoints[1] - tilePoly.ypoints[2], 2);
|
||||||
|
allEdges.add(edge2);
|
||||||
|
final int[][] edge3 = new int[][]{{tilePoly.xpoints[2], tilePoly.ypoints[2]}, {tilePoly.xpoints[3], tilePoly.ypoints[3]}};
|
||||||
|
edgeSizeSquared += Math.pow(tilePoly.xpoints[2] - tilePoly.xpoints[3], 2) + Math.pow(tilePoly.ypoints[2] - tilePoly.ypoints[3], 2);
|
||||||
|
allEdges.add(edge3);
|
||||||
|
final int[][] edge4 = new int[][]{{tilePoly.xpoints[3], tilePoly.ypoints[3]}, {tilePoly.xpoints[0], tilePoly.ypoints[0]}};
|
||||||
|
edgeSizeSquared += Math.pow(tilePoly.xpoints[3] - tilePoly.xpoints[0], 2) + Math.pow(tilePoly.ypoints[3] - tilePoly.ypoints[0], 2);
|
||||||
|
allEdges.add(edge4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allEdges.size() <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
edgeSizeSquared /= allEdges.size();
|
||||||
|
|
||||||
|
//Find and indicate unique edges
|
||||||
|
final int toleranceSquared = (int) Math.ceil(edgeSizeSquared / 6);
|
||||||
|
|
||||||
|
for (int i = 0; i < allEdges.size(); i++)
|
||||||
|
{
|
||||||
|
int[][] baseEdge = allEdges.get(i);
|
||||||
|
|
||||||
|
boolean duplicate = false;
|
||||||
|
|
||||||
|
for (int j = 0; j < allEdges.size(); j++)
|
||||||
|
{
|
||||||
|
if (i == j)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[][] checkEdge = allEdges.get(j);
|
||||||
|
|
||||||
|
if (edgeEqualsEdge(baseEdge, checkEdge, toleranceSquared))
|
||||||
|
{
|
||||||
|
duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!duplicate)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderFullLine(graphics, baseEdge, colorEdge1);
|
||||||
|
|
||||||
|
if (colorEdge2 != null)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderDashedLine(graphics, baseEdge, colorEdge2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderIndividualTilesSafespots(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
for (WorldPoint worldPoint : plugin.getSafeSpotMap().keySet())
|
||||||
|
{
|
||||||
|
final int safeSpotId = plugin.getSafeSpotMap().get(worldPoint);
|
||||||
|
|
||||||
|
if (safeSpotId > 6)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||||
|
|
||||||
|
if (localPoint == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Polygon tilePoly = Perspective.getCanvasTilePoly(client, localPoint);
|
||||||
|
|
||||||
|
if (tilePoly == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
switch (safeSpotId)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
color = Color.WHITE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
color = Color.RED;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = Color.GREEN;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
color = Color.BLUE;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
color = new Color(255, 255, 0);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
color = new Color(255, 0, 255);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
color = new Color(0, 255, 255);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayUtil.renderPolygon(graphics, tilePoly, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderTicksOnNpc(Graphics2D graphics, InfernoNPC infernoNPC)
|
||||||
|
{
|
||||||
|
final Color color = (infernoNPC.getTicksTillNextAttack() == 1
|
||||||
|
|| (infernoNPC.getType() == InfernoNPC.Type.BLOB && infernoNPC.getTicksTillNextAttack() == 4))
|
||||||
|
? infernoNPC.getNextAttack().getCriticalColor() : infernoNPC.getNextAttack().getNormalColor();
|
||||||
|
final Point canvasPoint = infernoNPC.getNpc().getCanvasTextLocation(
|
||||||
|
graphics, String.valueOf(infernoNPC.getTicksTillNextAttack()), 0);
|
||||||
|
OverlayUtil.renderTextLocation(graphics, String.valueOf(infernoNPC.getTicksTillNextAttack()),
|
||||||
|
plugin.getTextSize(), plugin.getFontStyle().getFont(), color, canvasPoint, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderNpcLocation(Graphics2D graphics, InfernoNPC infernoNPC)
|
||||||
|
{
|
||||||
|
final LocalPoint localPoint = LocalPoint.fromWorld(client, infernoNPC.getNpc().getWorldLocation());
|
||||||
|
|
||||||
|
if (localPoint != null)
|
||||||
|
{
|
||||||
|
final Polygon tilePolygon = Perspective.getCanvasTilePoly(client, localPoint);
|
||||||
|
|
||||||
|
if (tilePolygon != null)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, tilePolygon, Color.BLUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderDescendingBoxes(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
for (Integer tick : plugin.getUpcomingAttacks().keySet())
|
||||||
|
{
|
||||||
|
final Map<InfernoNPC.Attack, Integer> attackPriority = plugin.getUpcomingAttacks().get(tick);
|
||||||
|
int bestPriority = 999;
|
||||||
|
InfernoNPC.Attack bestAttack = null;
|
||||||
|
|
||||||
|
for (Map.Entry<InfernoNPC.Attack, Integer> attackEntry : attackPriority.entrySet())
|
||||||
|
{
|
||||||
|
if (attackEntry.getValue() < bestPriority)
|
||||||
|
{
|
||||||
|
bestAttack = attackEntry.getKey();
|
||||||
|
bestPriority = attackEntry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (InfernoNPC.Attack currentAttack : attackPriority.keySet())
|
||||||
|
{
|
||||||
|
//TODO: Config values for these colors
|
||||||
|
final Color color = (tick == 1 && currentAttack == bestAttack) ? Color.RED : Color.ORANGE;
|
||||||
|
final Widget prayerWidget = client.getWidget(currentAttack.getPrayer().getWidgetInfo());
|
||||||
|
|
||||||
|
int baseX = (int) prayerWidget.getBounds().getX();
|
||||||
|
baseX += prayerWidget.getBounds().getWidth() / 2;
|
||||||
|
baseX -= BOX_WIDTH / 2;
|
||||||
|
|
||||||
|
int baseY = (int) prayerWidget.getBounds().getY() - tick * TICK_PIXEL_SIZE - BOX_HEIGHT;
|
||||||
|
baseY += TICK_PIXEL_SIZE - ((plugin.getLastTick() + 600 - System.currentTimeMillis()) / 600.0 * TICK_PIXEL_SIZE);
|
||||||
|
|
||||||
|
final Rectangle boxRectangle = new Rectangle(BOX_WIDTH, BOX_HEIGHT);
|
||||||
|
boxRectangle.translate(baseX, baseY);
|
||||||
|
|
||||||
|
if (currentAttack == bestAttack)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderFilledPolygon(graphics, boxRectangle, color);
|
||||||
|
}
|
||||||
|
else if (plugin.isIndicateNonPriorityDescendingBoxes())
|
||||||
|
{
|
||||||
|
OverlayUtil.renderOutlinePolygon(graphics, boxRectangle, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderPrayerIconOverlay(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
if (plugin.getClosestAttack() != null)
|
||||||
|
{
|
||||||
|
// Prayer indicator in prayer tab
|
||||||
|
InfernoNPC.Attack prayerForAttack = null;
|
||||||
|
if (client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC))
|
||||||
|
{
|
||||||
|
prayerForAttack = InfernoNPC.Attack.MAGIC;
|
||||||
|
}
|
||||||
|
else if (client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES))
|
||||||
|
{
|
||||||
|
prayerForAttack = InfernoNPC.Attack.RANGED;
|
||||||
|
}
|
||||||
|
else if (client.isPrayerActive(Prayer.PROTECT_FROM_MELEE))
|
||||||
|
{
|
||||||
|
prayerForAttack = InfernoNPC.Attack.MELEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.getClosestAttack() != prayerForAttack || plugin.isIndicateWhenPrayingCorrectly())
|
||||||
|
{
|
||||||
|
final Widget prayerWidget = client.getWidget(plugin.getClosestAttack().getPrayer().getWidgetInfo());
|
||||||
|
final Rectangle prayerRectangle = new Rectangle((int) prayerWidget.getBounds().getWidth(),
|
||||||
|
(int) prayerWidget.getBounds().getHeight());
|
||||||
|
prayerRectangle.translate((int) prayerWidget.getBounds().getX(), (int) prayerWidget.getBounds().getY());
|
||||||
|
|
||||||
|
//TODO: Config values for these colors
|
||||||
|
Color prayerColor;
|
||||||
|
if (plugin.getClosestAttack() == prayerForAttack)
|
||||||
|
{
|
||||||
|
prayerColor = Color.GREEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prayerColor = Color.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayUtil.renderOutlinePolygon(graphics, prayerRectangle, prayerColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean edgeEqualsEdge(int[][] edge1, int[][] edge2, int toleranceSquared)
|
||||||
|
{
|
||||||
|
return (pointEqualsPoint(edge1[0], edge2[0], toleranceSquared) && pointEqualsPoint(edge1[1], edge2[1], toleranceSquared))
|
||||||
|
|| (pointEqualsPoint(edge1[0], edge2[1], toleranceSquared) && pointEqualsPoint(edge1[1], edge2[0], toleranceSquared));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pointEqualsPoint(int[] point1, int[] point2, int toleranceSquared)
|
||||||
|
{
|
||||||
|
double distanceSquared = Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2);
|
||||||
|
|
||||||
|
return distanceSquared <= toleranceSquared;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +0,0 @@
|
|||||||
package net.runelite.client.plugins.inferno;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Polygon;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.NPC;
|
|
||||||
import net.runelite.api.Prayer;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
|
||||||
|
|
||||||
public class InfernoPrayerOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private static final int TICK_PIXEL_SIZE = 60;
|
|
||||||
private static final int BLOB_WIDTH = 10;
|
|
||||||
private static final int BLOB_HEIGHT = 5;
|
|
||||||
|
|
||||||
private final InfernoPlugin plugin;
|
|
||||||
private final Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private InfernoPrayerOverlay(final Client client, final InfernoPlugin plugin)
|
|
||||||
{
|
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
|
||||||
setPriority(OverlayPriority.HIGHEST);
|
|
||||||
|
|
||||||
this.client = client;
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
if (client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC).isHidden()
|
|
||||||
|| client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES).isHidden())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
InfernoJad.Attack prayerForAttack = null;
|
|
||||||
|
|
||||||
if (client.isPrayerActive(Prayer.PROTECT_FROM_MAGIC))
|
|
||||||
{
|
|
||||||
prayerForAttack = InfernoJad.Attack.MAGIC;
|
|
||||||
}
|
|
||||||
else if (client.isPrayerActive(Prayer.PROTECT_FROM_MISSILES))
|
|
||||||
{
|
|
||||||
prayerForAttack = InfernoJad.Attack.RANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
InfernoJad.Attack closestAttack = null;
|
|
||||||
int leastTicks = 999;
|
|
||||||
|
|
||||||
for (InfernoJad jad : plugin.getJads())
|
|
||||||
{
|
|
||||||
if (jad.getNextAttack() == null || jad.getTicksTillNextAttack() < 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jad.getTicksTillNextAttack() < leastTicks)
|
|
||||||
{
|
|
||||||
leastTicks = jad.getTicksTillNextAttack();
|
|
||||||
closestAttack = jad.getNextAttack();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.isDescendingBoxes() || !plugin.isShowPrayerHelp()
|
|
||||||
|| (plugin.getPrayerOverlayMode() != InfernoPrayerOverlayMode.PRAYER_TAB
|
|
||||||
&& plugin.getPrayerOverlayMode() != InfernoPrayerOverlayMode.BOTH))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Widget prayerWidget = jad.getNextAttack() == InfernoJad.Attack.MAGIC
|
|
||||||
? client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC) : client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES);
|
|
||||||
int baseX = (int) prayerWidget.getBounds().getX();
|
|
||||||
baseX += prayerWidget.getBounds().getWidth() / 2;
|
|
||||||
baseX -= BLOB_WIDTH / 2;
|
|
||||||
|
|
||||||
int baseY = (int) prayerWidget.getBounds().getY() - jad.getTicksTillNextAttack() * TICK_PIXEL_SIZE - BLOB_HEIGHT;
|
|
||||||
baseY += TICK_PIXEL_SIZE - ((plugin.getLastTick() + 600 - System.currentTimeMillis()) / 600.0 * TICK_PIXEL_SIZE);
|
|
||||||
|
|
||||||
final Polygon blob = new Polygon(new int[]{0, BLOB_WIDTH, BLOB_WIDTH, 0}, new int[]{0, 0, BLOB_HEIGHT, BLOB_HEIGHT}, 4);
|
|
||||||
blob.translate(baseX, baseY);
|
|
||||||
|
|
||||||
OverlayUtil.renderPolygon(graphics, blob, Color.ORANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.isShowPrayerHelp() && closestAttack != null
|
|
||||||
&& (closestAttack != prayerForAttack || plugin.isIndicateWhenPrayingCorrectly())
|
|
||||||
&& (plugin.getPrayerOverlayMode() == InfernoPrayerOverlayMode.PRAYER_TAB
|
|
||||||
|| plugin.getPrayerOverlayMode() == InfernoPrayerOverlayMode.BOTH))
|
|
||||||
{
|
|
||||||
final Widget prayerWidget = closestAttack == InfernoJad.Attack.MAGIC
|
|
||||||
? client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MAGIC) : client.getWidget(WidgetInfo.PRAYER_PROTECT_FROM_MISSILES);
|
|
||||||
final Polygon prayer = new Polygon(
|
|
||||||
new int[]{0, (int) prayerWidget.getBounds().getWidth(), (int) prayerWidget.getBounds().getWidth(), 0},
|
|
||||||
new int[]{0, 0, (int) prayerWidget.getBounds().getHeight(), (int) prayerWidget.getBounds().getHeight()},
|
|
||||||
4);
|
|
||||||
prayer.translate((int) prayerWidget.getBounds().getX(), (int) prayerWidget.getBounds().getY());
|
|
||||||
|
|
||||||
Color prayerColor;
|
|
||||||
if (closestAttack == prayerForAttack)
|
|
||||||
{
|
|
||||||
prayerColor = Color.GREEN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prayerColor = Color.RED;
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayUtil.renderPolygon(graphics, prayer, prayerColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.isIndicateActiveHealers())
|
|
||||||
{
|
|
||||||
for (NPC healer : plugin.getActiveHealers())
|
|
||||||
{
|
|
||||||
if (healer.getConvexHull() == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayUtil.renderPolygon(graphics, healer.getConvexHull(), Color.CYAN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package net.runelite.client.plugins.inferno;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum InfernoPrayerOverlayMode
|
|
||||||
{
|
|
||||||
PRAYER_TAB("Prayer Tab"),
|
|
||||||
BOTTOM_RIGHT("Bottom Right"),
|
|
||||||
BOTH("Both");
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Kyleeld <https://github.com/kyleeld>
|
* Copyright (c) 2019, Kyleeld <https://github.com/kyleeld>
|
||||||
* Copyright (c) 2019, openosrs <https://openosrs.com>
|
* Copyright (c) 2019, RuneLitePlus <https://runelitepl.us>
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -28,18 +28,21 @@ package net.runelite.client.plugins.inferno;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.util.Map;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.runelite.client.plugins.inferno.displaymodes.InfernoNamingDisplayMode;
|
||||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||||
|
|
||||||
class InfernoWaveMappings
|
class InfernoWaveMappings
|
||||||
{
|
{
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private static final ImmutableMap<Integer, int[]> waveMapping;
|
private static final Map<Integer, int[]> waveMapping;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private static final ImmutableMap<Integer, String> npcNameMapping;
|
private static final Map<Integer, String> npcNameMappingComplex;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private static final Map<Integer, String> npcNameMappingSimple;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
@@ -108,30 +111,43 @@ class InfernoWaveMappings
|
|||||||
waveMapBuilder.put(61, new int[]{32, 32, 32, 85, 165, 240, 370, 490});
|
waveMapBuilder.put(61, new int[]{32, 32, 32, 85, 165, 240, 370, 490});
|
||||||
waveMapBuilder.put(62, new int[]{32, 32, 32, 85, 85, 165, 240, 370, 490});
|
waveMapBuilder.put(62, new int[]{32, 32, 32, 85, 85, 165, 240, 370, 490});
|
||||||
waveMapBuilder.put(63, new int[]{32, 32, 32, 165, 165, 240, 370, 490});
|
waveMapBuilder.put(63, new int[]{32, 32, 32, 165, 165, 240, 370, 490});
|
||||||
waveMapBuilder.put(64, new int[]{32, 32, 32, 85, 240, 240, 370, 490});
|
waveMapBuilder.put(64, new int[]{32, 32, 32, 240, 240, 370, 490});
|
||||||
waveMapBuilder.put(65, new int[]{32, 32, 32, 85, 370, 370, 490});
|
waveMapBuilder.put(65, new int[]{32, 32, 32, 370, 370, 490});
|
||||||
waveMapBuilder.put(66, new int[]{32, 32, 32, 85, 490, 490});
|
waveMapBuilder.put(66, new int[]{32, 32, 32, 490, 490});
|
||||||
waveMapBuilder.put(67, new int[]{900});
|
waveMapBuilder.put(67, new int[]{900});
|
||||||
waveMapBuilder.put(68, new int[]{900, 900, 900});
|
waveMapBuilder.put(68, new int[]{900, 900, 900});
|
||||||
waveMapBuilder.put(69, new int[]{1400});
|
waveMapBuilder.put(69, new int[]{1400});
|
||||||
|
|
||||||
waveMapping = waveMapBuilder.build();
|
waveMapping = waveMapBuilder.build();
|
||||||
|
|
||||||
ImmutableMap.Builder<Integer, String> nameMapBuilder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<Integer, String> nameMapBuilderSimple = new ImmutableMap.Builder<>();
|
||||||
|
|
||||||
nameMapBuilder.put(32, "Jal-Nib - Level 32");
|
nameMapBuilderSimple.put(32, "Nibbler");
|
||||||
nameMapBuilder.put(85, "Jal-MejRah - Level 85");
|
nameMapBuilderSimple.put(85, "Bat");
|
||||||
nameMapBuilder.put(165, "Jal-Ak - Level 165");
|
nameMapBuilderSimple.put(165, "Blob");
|
||||||
nameMapBuilder.put(240, "Jal-ImKot - Level 240");
|
nameMapBuilderSimple.put(240, "Meleer");
|
||||||
nameMapBuilder.put(370, "Jal-Xil - Level 370");
|
nameMapBuilderSimple.put(370, "Ranger");
|
||||||
nameMapBuilder.put(490, "Jal-Zek - Level 490");
|
nameMapBuilderSimple.put(490, "Mage");
|
||||||
nameMapBuilder.put(900, "JalTok-Jad - Level 900");
|
nameMapBuilderSimple.put(900, "Jad");
|
||||||
nameMapBuilder.put(1400, "TzKal-Zuk - Level 1400");
|
nameMapBuilderSimple.put(1400, "Zuk");
|
||||||
|
|
||||||
npcNameMapping = nameMapBuilder.build();
|
npcNameMappingSimple = nameMapBuilderSimple.build();
|
||||||
|
|
||||||
|
ImmutableMap.Builder<Integer, String> nameMapBuilderComplex = new ImmutableMap.Builder<>();
|
||||||
|
|
||||||
|
nameMapBuilderComplex.put(32, "Jal-Nib");
|
||||||
|
nameMapBuilderComplex.put(85, "Jal-MejRah");
|
||||||
|
nameMapBuilderComplex.put(165, "Jal-Ak");
|
||||||
|
nameMapBuilderComplex.put(240, "Jal-ImKot");
|
||||||
|
nameMapBuilderComplex.put(370, "Jal-Xil");
|
||||||
|
nameMapBuilderComplex.put(490, "Jal-Zek");
|
||||||
|
nameMapBuilderComplex.put(900, "JalTok-Jad");
|
||||||
|
nameMapBuilderComplex.put(1400, "TzKal-Zuk");
|
||||||
|
|
||||||
|
npcNameMappingComplex = nameMapBuilderComplex.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addWaveComponent(PanelComponent panelComponent, String header, int wave, Color titleColor, Color color)
|
static void addWaveComponent(InfernoPlugin plugin, PanelComponent panelComponent, String header, int wave, Color titleColor, Color color)
|
||||||
{
|
{
|
||||||
int[] monsters = waveMapping.get(wave);
|
int[] monsters = waveMapping.get(wave);
|
||||||
|
|
||||||
@@ -160,7 +176,23 @@ class InfernoWaveMappings
|
|||||||
|
|
||||||
TitleComponent.TitleComponentBuilder builder = TitleComponent.builder();
|
TitleComponent.TitleComponentBuilder builder = TitleComponent.builder();
|
||||||
|
|
||||||
builder.text(count + "x " + npcNameMapping.get(monsterType));
|
String npcNameText = "";
|
||||||
|
|
||||||
|
if (plugin.getNpcNaming() == InfernoNamingDisplayMode.SIMPLE)
|
||||||
|
{
|
||||||
|
npcNameText += npcNameMappingSimple.get(monsterType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
npcNameText += npcNameMappingComplex.get(monsterType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.isNpcLevels())
|
||||||
|
{
|
||||||
|
npcNameText += " (" + monsterType + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.text(count + "x " + npcNameText);
|
||||||
builder.color(color);
|
builder.color(color);
|
||||||
|
|
||||||
panelComponent.getChildren().add(builder.build());
|
panelComponent.getChildren().add(builder.build());
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.awt.Graphics2D;
|
|||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import static net.runelite.client.plugins.inferno.InfernoWaveMappings.addWaveComponent;
|
import static net.runelite.client.plugins.inferno.InfernoWaveMappings.addWaveComponent;
|
||||||
|
import net.runelite.client.plugins.inferno.displaymodes.InfernoWaveDisplayMode;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||||
@@ -47,6 +48,7 @@ public class InfernoWaveOverlay extends Overlay
|
|||||||
displayMode == InfernoWaveDisplayMode.BOTH)
|
displayMode == InfernoWaveDisplayMode.BOTH)
|
||||||
{
|
{
|
||||||
addWaveComponent(
|
addWaveComponent(
|
||||||
|
plugin,
|
||||||
panelComponent,
|
panelComponent,
|
||||||
"Current Wave (Wave " + plugin.getCurrentWaveNumber() + ")",
|
"Current Wave (Wave " + plugin.getCurrentWaveNumber() + ")",
|
||||||
plugin.getCurrentWaveNumber(),
|
plugin.getCurrentWaveNumber(),
|
||||||
@@ -59,6 +61,7 @@ public class InfernoWaveOverlay extends Overlay
|
|||||||
displayMode == InfernoWaveDisplayMode.BOTH)
|
displayMode == InfernoWaveDisplayMode.BOTH)
|
||||||
{
|
{
|
||||||
addWaveComponent(
|
addWaveComponent(
|
||||||
|
plugin,
|
||||||
panelComponent,
|
panelComponent,
|
||||||
"Next Wave (Wave " + plugin.getNextWaveNumber() + ")",
|
"Next Wave (Wave " + plugin.getNextWaveNumber() + ")",
|
||||||
plugin.getNextWaveNumber(),
|
plugin.getNextWaveNumber(),
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package net.runelite.client.plugins.inferno.displaymodes;
|
||||||
|
|
||||||
|
public enum InfernoNamingDisplayMode
|
||||||
|
{
|
||||||
|
SIMPLE,
|
||||||
|
COMPLEX
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.runelite.client.plugins.inferno.displaymodes;
|
||||||
|
|
||||||
|
public enum InfernoPrayerDisplayMode
|
||||||
|
{
|
||||||
|
PRAYER_TAB,
|
||||||
|
BOTTOM_RIGHT,
|
||||||
|
BOTH
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package net.runelite.client.plugins.inferno.displaymodes;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
public enum InfernoSafespotDisplayMode
|
||||||
|
{
|
||||||
|
OFF("Off"),
|
||||||
|
INDIVIDUAL_TILES("Individual tiles"),
|
||||||
|
AREA("Area (lower fps)");
|
||||||
|
|
||||||
|
final private String name;
|
||||||
|
|
||||||
|
InfernoSafespotDisplayMode(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.inferno;
|
package net.runelite.client.plugins.inferno.displaymodes;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package net.runelite.client.plugins.inferno.displaymodes;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
public enum InfernoZukShieldDisplayMode
|
||||||
|
{
|
||||||
|
OFF("Off"),
|
||||||
|
LIVE("Live (follow shield)"),
|
||||||
|
PREDICT("Predict (NOT WORKING YET)");
|
||||||
|
|
||||||
|
final private String name;
|
||||||
|
|
||||||
|
InfernoZukShieldDisplayMode(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,6 +72,49 @@ public class OverlayUtil
|
|||||||
graphics.setStroke(originalStroke);
|
graphics.setStroke(originalStroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void renderOutlinePolygon(Graphics2D graphics, Shape poly, Color color)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
final Stroke originalStroke = graphics.getStroke();
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.draw(poly);
|
||||||
|
graphics.setStroke(originalStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderFilledPolygon(Graphics2D graphics, Shape poly, Color color)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
final Stroke originalStroke = graphics.getStroke();
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.draw(poly);
|
||||||
|
graphics.fill(poly);
|
||||||
|
graphics.setStroke(originalStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderAreaTilePolygon(Graphics2D graphics, Shape poly, Color color)
|
||||||
|
{
|
||||||
|
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 10));
|
||||||
|
graphics.fill(poly);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderFullLine(Graphics2D graphics, int[][] line, Color color)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
final Stroke originalStroke = graphics.getStroke();
|
||||||
|
graphics.setStroke(new BasicStroke(2));
|
||||||
|
graphics.drawLine(line[0][0], line[0][1], line[1][0], line[1][1]);
|
||||||
|
graphics.setStroke(originalStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderDashedLine(Graphics2D graphics, int[][] line, Color color)
|
||||||
|
{
|
||||||
|
graphics.setColor(color);
|
||||||
|
final Stroke originalStroke = graphics.getStroke();
|
||||||
|
graphics.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0));
|
||||||
|
graphics.drawLine(line[0][0], line[0][1], line[1][0], line[1][1]);
|
||||||
|
graphics.setStroke(originalStroke);
|
||||||
|
}
|
||||||
|
|
||||||
public static void renderPolygonThin(Graphics2D graphics, Polygon poly, Color color)
|
public static void renderPolygonThin(Graphics2D graphics, Polygon poly, Color color)
|
||||||
{
|
{
|
||||||
graphics.setColor(color);
|
graphics.setColor(color);
|
||||||
|
|||||||
Reference in New Issue
Block a user