Skip to content

Commit

Permalink
spec counter: add defence drain percentage
Browse files Browse the repository at this point in the history
This adds an infobox showing what percentage an opponent's defence has
been drained, and broadcasts 0 hit specs.

A config option was added to draw the spec misses, which are drawn with
a blue hitsplat background to visually distinguish them from normal
hits.

Support for the special cases for Tekton with bgs/dwh/em was added.

Co-authored-by: 1Defence <>
Co-authored-by: JaayJee <[email protected]>
  • Loading branch information
Adam- and jaayjee committed Jun 15, 2024
1 parent bb85d87 commit 318a8db
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 123 deletions.
3 changes: 2 additions & 1 deletion runelite-api/src/main/java/net/runelite/api/SpriteID.java
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,8 @@ public final class SpriteID
public static final int EMOTE_SMOOTH_DANCE_LOCKED = 1355;
public static final int EMOTE_CRAZY_DANCE_LOCKED = 1356;
public static final int EMOTE_PREMIER_SHIELD_LOCKED = 1357;
/* Unmapped: 1358~1359 */
public static final int HITSPLAT_BLUE_MISS = 1358;
/* Unmapped: 1359 */
public static final int HITSPLAT_GREEN_POISON = 1360;
/* Unmapped: 1361~1363 */
public static final int BOUNTY_HUNTER_SKIP_TARGET = 1364;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2024, 1Defence
* Copyright (c) 2024, Adam <[email protected]>
* 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.specialcounter;

import java.awt.Color;
import java.awt.image.BufferedImage;
import net.runelite.client.ui.overlay.infobox.InfoBox;

class PercentageInfobox extends InfoBox
{
private float percent = 1f;

PercentageInfobox(BufferedImage image, SpecialCounterPlugin plugin)
{
super(image, plugin);
}

void mul(float p)
{
percent *= p;
}

@Override
public String getTooltip()
{
return "Opponent defence has been reduced by " + getText() + ".";
}

@Override
public Color getTextColor()
{
return Color.WHITE;
}

@Override
public String getText()
{
return (int) (percent * 100) + "%";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,59 +27,29 @@
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import javax.annotation.Nullable;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import net.runelite.client.ui.FontManager;

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Value
class PlayerInfoDrop
{
private final int startCycle;
private final int endCycle;
private final int playerIdx;
private final String text;
private final int startHeightOffset;
private final int endHeightOffset;
private final Font font;
private final Color color;
private final BufferedImage image;

public static Builder builder(int startCycle, int endCycle, int playerIdx, String text)
{
return new Builder(startCycle, endCycle, playerIdx, text);
}

@RequiredArgsConstructor
@Accessors(fluent = true)
@Setter
static class Builder
{
private final int startCycle;
private final int endCycle;
private final int playerIdx;
private final String text;
private int startHeightOffset = 0;
private int endHeightOffset = 200;
private Font font = FontManager.getRunescapeBoldFont();
private Color color = Color.WHITE;
private BufferedImage image;

public PlayerInfoDrop build()
{
if (startCycle > endCycle)
{
throw new IllegalArgumentException("endCycle must be after startCycle");
}
if (playerIdx < 0 || playerIdx > 2047)
{
throw new IllegalArgumentException("playerIdx must be between 0-2047");
}
return new PlayerInfoDrop(startCycle, endCycle, playerIdx, text, startHeightOffset, endHeightOffset, font, color, image);
}
}
int startCycle;
int endCycle;
int playerIdx;
String text;
@Nullable
BufferedImage textBackground;
int startHeightOffset;
@Builder.Default
int endHeightOffset = 200;
@Builder.Default
Font font = FontManager.getRunescapeBoldFont();
@Builder.Default
Color color = Color.WHITE;
@NonNull
BufferedImage image;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Iterator;
Expand Down Expand Up @@ -68,7 +69,7 @@ public Dimension render(Graphics2D graphics)
}

final int cycle = client.getGameCycle();
for (Iterator<PlayerInfoDrop> iterator = infoDrops.iterator(); iterator.hasNext();)
for (Iterator<PlayerInfoDrop> iterator = infoDrops.iterator(); iterator.hasNext(); )
{
PlayerInfoDrop infoDrop = iterator.next();

Expand Down Expand Up @@ -100,27 +101,43 @@ public Dimension render(Graphics2D graphics)
String text = infoDrop.getText();

graphics.setFont(infoDrop.getFont());
Point textLocation = player.getCanvasTextLocation(graphics, text, player.getLogicalHeight() + infoDrop.getStartHeightOffset() + currentHeight);
if (textLocation == null)
Point playerLocation = player.getCanvasTextLocation(graphics, text, player.getLogicalHeight() + infoDrop.getStartHeightOffset() + currentHeight);
if (playerLocation == null)
{
continue;
}

FontMetrics fontMetrics = graphics.getFontMetrics();
int alpha = 255 - (255 * percent / 100);
BufferedImage image = infoDrop.getImage();
if (image != null)

BufferedImage sprite = infoDrop.getImage();
int textHeight = fontMetrics.getHeight() - fontMetrics.getMaxDescent();
int textWidth = fontMetrics.stringWidth(text);
int textMargin = sprite.getWidth() / 2;

Point imageLocation = new Point(
playerLocation.getX() - textMargin - 1,
playerLocation.getY() - textHeight / 2 - sprite.getHeight() / 2
);
Point textLocation = new Point(playerLocation.getX() + textMargin, playerLocation.getY());

BufferedImage backgroundSprite = infoDrop.getTextBackground();
if (backgroundSprite != null)
{
int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent();
int textMargin = image.getWidth() / 2;
int x = textLocation.getX() - textMargin - 1;
int y = textLocation.getY() - textHeight / 2 - image.getHeight() / 2;
Point imageLocation = new Point(x, y);
int x = textLocation.getX();
int y = textLocation.getY();

textLocation = new Point(textLocation.getX() + textMargin, textLocation.getY());
y -= textHeight / 2;
y -= backgroundSprite.getHeight() / 2;

OverlayUtil.renderImageLocation(graphics, imageLocation, ImageUtil.alphaOffset(image, alpha - 255));
x += (textWidth + 1) / 2;
x -= backgroundSprite.getWidth() / 2;

OverlayUtil.renderImageLocation(graphics, new Point(x, y), ImageUtil.alphaOffset(backgroundSprite, alpha - 255));
}

OverlayUtil.renderImageLocation(graphics, imageLocation, ImageUtil.alphaOffset(sprite, alpha - 255));

drawText(graphics, textLocation, text, infoDrop.getColor(), alpha);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ class SpecialCounter extends Counter
this.config = config;
}

void addHits(double hit)
void addHits(int hit)
{
int count = getCount();
setCount(count + (int) hit);
setCount(count + hit);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ default boolean specDrops()
return true;
}

@ConfigItem(
position = 1,
keyName = "specDropMisses",
name = "Spec Drops Misses",
description = "Draws an overlay over the player when a special attack misses"
)
default boolean specDropMisses()
{
return false;
}

@ConfigItem(
position = 2,
keyName = "specDropColor",
Expand Down
Loading

0 comments on commit 318a8db

Please sign in to comment.