ba plugin: add health bars for healers

This commit is contained in:
whartd
2019-04-18 23:50:51 -04:00
committed by Adam
parent cb032ab609
commit 26bf9cb077
7 changed files with 202 additions and 29 deletions

View File

@@ -570,6 +570,13 @@ public class WidgetID
static final int ROLE_SPRITE = 11;
static final int ROLE = 12;
}
static class HLR
{
static final int TEAMMATE1 = 18;
static final int TEAMMATE2 = 22;
static final int TEAMMATE3 = 26;
static final int TEAMMATE4 = 30;
}
static final int CORRECT_STYLE = 3;
static final int CURRENT_WAVE_WIDGET = 4;
static final int CURRENT_WAVE = 5;

View File

@@ -353,6 +353,11 @@ public enum WidgetInfo
BA_HEAL_ROLE_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.ROLE),
BA_HEAL_ROLE_SPRITE(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.ROLE_SPRITE),
BA_HEAL_TEAMMATE1(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE1),
BA_HEAL_TEAMMATE2(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE2),
BA_HEAL_TEAMMATE3(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE3),
BA_HEAL_TEAMMATE4(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.HLR.TEAMMATE4),
BA_COLL_WAVE_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.CURRENT_WAVE),
BA_COLL_CALL_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.TO_CALL),
BA_COLL_LISTEN_TEXT(WidgetID.BA_COLLECTOR_GROUP_ID, WidgetID.BarbarianAssault.CORRECT_STYLE),

View File

@@ -42,6 +42,16 @@ public interface BarbarianAssaultConfig extends Config
return true;
}
@ConfigItem(
keyName = "showHealerBars",
name = "Show health bars for teammates when healer",
description = "Displays team health for healer"
)
default boolean showHealerBars()
{
return true;
}
@ConfigItem(
keyName = "waveTimes",
name = "Show wave and game duration",

View File

@@ -29,6 +29,7 @@ import com.google.inject.Provides;
import java.awt.Font;
import java.awt.Image;
import javax.inject.Inject;
import lombok.Getter;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Varbits;
@@ -67,6 +68,9 @@ public class BarbarianAssaultPlugin extends Plugin
private String currentWave = START_WAVE;
private GameTimer gameTime;
@Getter
private Round currentRound;
@Inject
private Client client;
@@ -80,7 +84,10 @@ public class BarbarianAssaultPlugin extends Plugin
private BarbarianAssaultConfig config;
@Inject
private BarbarianAssaultOverlay overlay;
private TimerOverlay timerOverlay;
@Inject
private HealerOverlay healerOverlay;
@Provides
BarbarianAssaultConfig provideConfig(ConfigManager configManager)
@@ -91,7 +98,8 @@ public class BarbarianAssaultPlugin extends Plugin
@Override
protected void startUp() throws Exception
{
overlayManager.add(overlay);
overlayManager.add(timerOverlay);
overlayManager.add(healerOverlay);
font = FontManager.getRunescapeFont()
.deriveFont(Font.BOLD, 24);
@@ -101,7 +109,8 @@ public class BarbarianAssaultPlugin extends Plugin
@Override
protected void shutDown() throws Exception
{
overlayManager.remove(overlay);
overlayManager.remove(timerOverlay);
overlayManager.remove(healerOverlay);
gameTime = null;
currentWave = START_WAVE;
inGameBit = 0;
@@ -126,22 +135,22 @@ public class BarbarianAssaultPlugin extends Plugin
}
case WidgetID.BA_ATTACKER_GROUP_ID:
{
setOverlayRound(Role.ATTACKER);
setRound(Role.ATTACKER);
break;
}
case WidgetID.BA_DEFENDER_GROUP_ID:
{
setOverlayRound(Role.DEFENDER);
setRound(Role.DEFENDER);
break;
}
case WidgetID.BA_HEALER_GROUP_ID:
{
setOverlayRound(Role.HEALER);
setRound(Role.HEALER);
break;
}
case WidgetID.BA_COLLECTOR_GROUP_ID:
{
setOverlayRound(Role.COLLECTOR);
setRound(Role.COLLECTOR);
break;
}
}
@@ -176,7 +185,7 @@ public class BarbarianAssaultPlugin extends Plugin
{
if (inGameBit == 1)
{
overlay.setCurrentRound(null);
currentRound = null;
// Use an instance check to determine if this is exiting a game or a tutorial
// After exiting tutorials there is a small delay before changing IN_GAME_BA back to
@@ -191,17 +200,15 @@ public class BarbarianAssaultPlugin extends Plugin
inGameBit = inGame;
}
private void setOverlayRound(Role role)
private void setRound(Role role)
{
// Prevent changing roles when a role is already set, as widgets can be
// Prevent changing rounds when a round is already set, as widgets can be
// loaded multiple times in game from eg. opening and closing the horn
// of glory.
if (overlay.getCurrentRound() != null)
if (currentRound == null)
{
return;
currentRound = new Round(role);
}
overlay.setCurrentRound(new Round(role));
}
private void announceTime(String preText, String time)
@@ -228,4 +235,4 @@ public class BarbarianAssaultPlugin extends Plugin
{
return clockImage;
}
}
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (c) 2019, whartd <github.com/whartd>
* 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.barbarianassault;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import javax.inject.Inject;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.Client;
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
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 static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition;
class HealerOverlay extends Overlay
{
@Getter
@AllArgsConstructor
private enum HealerTeam
{
TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, 28, 2, 115),
TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, 26, 2, 115),
TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, 26, 2, 115),
TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, 25, 2, 115);
private WidgetInfo teammate;
private int offsetX;
private int offsetY;
private int width;
}
private static final Color HP_HIGH = new Color(10, 146, 5, 125);
private static final Color HP_MID = new Color(146, 146, 0, 230);
private static final Color HP_LOW = new Color(225, 35, 0, 125);
private final Client client;
private final BarbarianAssaultPlugin plugin;
private final BarbarianAssaultConfig config;
@Inject
private HealerOverlay(Client client, BarbarianAssaultPlugin plugin, BarbarianAssaultConfig config)
{
super(plugin);
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.UNDER_WIDGETS);
this.client = client;
this.plugin = plugin;
this.config = config;
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "B.A. overlay"));
}
@Override
public Dimension render(Graphics2D graphics)
{
Round round = plugin.getCurrentRound();
if (round == null)
{
return null;
}
Role role = round.getRoundRole();
if (role == null)
{
return null;
}
if (config.showHealerBars() && role == Role.HEALER)
{
for (HealerTeam teammate : HealerTeam.values())
{
Widget widget = client.getWidget(teammate.getTeammate());
if (widget == null)
{
continue;
}
String[] teammateHealth = widget.getText().split(" / ");
int curHealth = Integer.parseInt(teammateHealth[0]);
int maxHealth = Integer.parseInt(teammateHealth[1]);
int width = teammate.getWidth();
double hpRatio = (double) curHealth / maxHealth;
int filledWidth = getBarWidth(hpRatio, width);
Color barColor = getBarColor(hpRatio);
int offsetX = teammate.getOffsetX();
int offsetY = teammate.getOffsetY();
int x = widget.getCanvasLocation().getX() - offsetX;
int y = widget.getCanvasLocation().getY() - offsetY;
graphics.setColor(barColor);
graphics.fillRect(x, y, filledWidth, 20);
}
}
return null;
}
private int getBarWidth(double ratio, int size)
{
if (ratio >= 1)
{
return size;
}
return (int) Math.round(ratio * size);
}
private Color getBarColor(double ratio)
{
if (ratio <= 0.33)
{
return HP_LOW;
}
if (ratio <= 0.66)
{
return HP_MID;
}
return HP_HIGH;
}
}

View File

@@ -56,4 +56,4 @@ enum Role
{
return name();
}
}
}

View File

@@ -28,10 +28,7 @@ import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.inject.Inject;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
import net.runelite.api.widgets.Widget;
import net.runelite.client.ui.overlay.Overlay;
@@ -40,19 +37,14 @@ import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPosition;
class BarbarianAssaultOverlay extends Overlay
class TimerOverlay extends Overlay
{
private final Client client;
private final BarbarianAssaultPlugin plugin;
private final BarbarianAssaultConfig config;
@Getter
@Setter
private Round currentRound;
@Inject
private BarbarianAssaultOverlay(Client client, BarbarianAssaultPlugin plugin, BarbarianAssaultConfig config)
private TimerOverlay(Client client, BarbarianAssaultPlugin plugin, BarbarianAssaultConfig config)
{
super(plugin);
setPosition(OverlayPosition.DYNAMIC);
@@ -66,12 +58,13 @@ class BarbarianAssaultOverlay extends Overlay
@Override
public Dimension render(Graphics2D graphics)
{
if (client.getGameState() != GameState.LOGGED_IN || currentRound == null)
Round round = plugin.getCurrentRound();
if (round == null)
{
return null;
}
Role role = currentRound.getRoundRole();
Role role = round.getRoundRole();
if (role == null)
{
return null;
@@ -82,7 +75,7 @@ class BarbarianAssaultOverlay extends Overlay
if (config.showTimer() && roleText != null && roleSprite != null)
{
roleText.setText(String.format("00:%02d", currentRound.getTimeToChange()));
roleText.setText(String.format("00:%02d", round.getTimeToChange()));
Rectangle spriteBounds = roleSprite.getBounds();
roleSprite.setHidden(true);
graphics.drawImage(plugin.getClockImage(), spriteBounds.x, spriteBounds.y, null);