Add regen meter plugin

This commit is contained in:
Max Weber
2018-03-10 02:22:20 -07:00
parent c3920e5814
commit c7deb854db
5 changed files with 315 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2018 Abex
* 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.regenmeter;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup(
keyName = "regenmeter",
name = "Regeneration Meter",
description = "Configuration for the data orb regeneration meters"
)
public interface RegenMeterConfig extends Config
{
@ConfigItem(
keyName = "showHitpoints",
name = "Show hitpoints regen",
description = "Show a ring around the hitpoints orb")
default boolean showHitpoints()
{
return true;
}
@ConfigItem(
keyName = "showSpecial",
name = "Show Spec. Attack regen",
description = "Show a ring around the Special Attack orb")
default boolean showSpecial()
{
return true;
}
@ConfigItem(
keyName = "showWhenNoChange",
name = "Show hitpoints regen at full hitpoints",
description = "Always show the hitpoints regen orb, even if there will be no stat change")
default boolean showWhenNoChange()
{
return false;
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2018 Abex
* 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.regenmeter;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Arc2D;
import javax.inject.Inject;
import net.runelite.api.Client;
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;
public class RegenMeterOverlay extends Overlay
{
private static final Color HITPOINTS_COLOR = brighter(0x9B0703);
private static final Color SPECIAL_COLOR = brighter(0x1E95B0);
private final Client client;
private RegenMeterPlugin plugin;
private RegenMeterConfig config;
private static Color brighter(int color)
{
float[] hsv = new float[3];
Color.RGBtoHSB(color >>> 16, (color >> 8) & 0xFF, color & 0xFF, hsv);
return Color.getHSBColor(hsv[0], 1.f, 1.f);
}
@Inject
public RegenMeterOverlay(Client client, RegenMeterPlugin plugin, RegenMeterConfig config)
{
setPosition(OverlayPosition.DYNAMIC);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client;
this.plugin = plugin;
this.config = config;
}
@Override
public Dimension render(Graphics2D g, Point point)
{
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
if (config.showHitpoints())
{
renderRegen(g, WidgetInfo.MINIMAP_HEALTH_ORB, plugin.getHitpointsPercentage(), HITPOINTS_COLOR);
}
if (config.showSpecial())
{
renderRegen(g, WidgetInfo.MINIMAP_SPEC_ORB, plugin.getSpecialPercentage(), SPECIAL_COLOR);
}
return null;
}
private void renderRegen(Graphics2D g, WidgetInfo widgetInfo, double percent, Color color)
{
Widget widget = client.getWidget(widgetInfo);
if (widget == null)
{
return;
}
Rectangle bounds = widget.getBounds();
Arc2D.Double arc = new Arc2D.Double(bounds.x + 26d, bounds.y + 3.d, 27d, 27d, 90.d, -360.d * percent, Arc2D.OPEN);
final Stroke STROKE = new BasicStroke(2f);
g.setStroke(STROKE);
g.setColor(color);
g.draw(arc);
}
}

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2018 Abex
* Copyright (c) 2018, Zimaya <https://github.com/Zimaya>
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.regenmeter;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides;
import javax.inject.Inject;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.Prayer;
import net.runelite.api.Setting;
import net.runelite.api.Skill;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.Overlay;
@PluginDescriptor(name = "Regeneration Meter")
public class RegenMeterPlugin extends Plugin
{
private static final int SPEC_REGEN_TICKS = 51;
private static final int NORMAL_HP_REGEN_TICKS = 100;
@Inject
private RegenMeterOverlay overlay;
@Inject
private Client client;
@Inject
RegenMeterConfig config;
private int ticksSinceHPRegen;
private boolean wasRapidHeal;
@Getter
private double hitpointsPercentage;
private int ticksSinceSpecRegen;
@Getter
private double specialPercentage;
@Override
public Overlay getOverlay()
{
return overlay;
}
@Provides
RegenMeterConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(RegenMeterConfig.class);
}
@Subscribe
private void onGameStateChanged(GameStateChanged ev)
{
if (ev.getGameState() == GameState.HOPPING || ev.getGameState() == GameState.LOGIN_SCREEN)
{
ticksSinceHPRegen = -2; // For some reason this makes this accurate
ticksSinceSpecRegen = 0;
}
}
@Subscribe
private void onVarbitChanged(VarbitChanged ev)
{
boolean isRapidHeal = client.isPrayerActive(Prayer.RAPID_HEAL);
if (wasRapidHeal != isRapidHeal)
{
ticksSinceHPRegen = 0;
}
wasRapidHeal = isRapidHeal;
}
@Subscribe
private void onTick(GameTick event)
{
if (client.getSetting(Setting.SPECIAL_ATTACK_PERCENT) == 1000)
{
// The recharge doesn't tick when at 100%
ticksSinceSpecRegen = 0;
}
else
{
ticksSinceSpecRegen = (ticksSinceSpecRegen + 1) % SPEC_REGEN_TICKS;
}
specialPercentage = ticksSinceSpecRegen / (double) SPEC_REGEN_TICKS;
int ticksPerHPRegen = NORMAL_HP_REGEN_TICKS;
if (client.isPrayerActive(Prayer.RAPID_HEAL))
{
ticksPerHPRegen /= 2;
}
ticksSinceHPRegen = (ticksSinceHPRegen + 1) % ticksPerHPRegen;
hitpointsPercentage = ticksSinceHPRegen / (double) ticksPerHPRegen;
int currentHP = client.getBoostedSkillLevel(Skill.HITPOINTS);
int maxHP = client.getRealSkillLevel(Skill.HITPOINTS);
if (currentHP == maxHP && !config.showWhenNoChange())
{
hitpointsPercentage = 0;
}
else if (currentHP > maxHP)
{
// Show it going down
hitpointsPercentage = 1 - hitpointsPercentage;
}
}
}