Merge pull request #211 from honeyhoney/feature_attack_indicators

Feature attack indicator plugin
This commit is contained in:
Adam
2017-11-13 18:58:25 -05:00
committed by GitHub
8 changed files with 463 additions and 1 deletions

View File

@@ -91,6 +91,21 @@ public enum Varbits
POISON(102, 0, 5),
VENOM(102, 6, 9),
/**
* Attack Style
*/
ATTACK_STYLE(43, 0, 7),
/**
* Equipped weapon type
*/
EQUIPPED_WEAPON_TYPE(357, 843, 0, 5),
/**
* Defensive casting mode
*/
DEFENSIVE_CASTING_MODE(2668, 439, 8, 8),
/**
* Options
*/

View File

@@ -46,6 +46,7 @@ class WidgetID
static final int DIALOG_NPC_GROUP_ID = 231;
static final int SLAYER_REWARDS_GROUP_ID = 426;
static final int PRIVATE_CHAT = 163;
static final int CHATBOX_GROUP_ID = 162;
static class SlayerRewards
{
@@ -137,6 +138,12 @@ class WidgetID
static final int RESIZABLE_VIEWPORT_BOTTOM_LINE = 12;
}
static class Chatbox
{
static final int CHATBOX_MESSAGES = 29;
static final int CHATBOX_BUTTONS = 1;
}
static class Prayer
{
static final int THICK_SKIN = 4;

View File

@@ -90,7 +90,11 @@ public enum WidgetInfo
PRIVATE_CHAT_MESSAGE(WidgetID.PRIVATE_CHAT, 0),
SLAYER_REWARDS_TOPBAR(WidgetID.SLAYER_REWARDS_GROUP_ID, WidgetID.SlayerRewards.TOP_BAR);
SLAYER_REWARDS_TOPBAR(WidgetID.SLAYER_REWARDS_GROUP_ID, WidgetID.SlayerRewards.TOP_BAR),
CHATBOX(WidgetID.CHATBOX_GROUP_ID, 0),
CHATBOX_MESSAGES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_MESSAGES),
CHATBOX_BUTTONS(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_BUTTONS);
private final int groupId;

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
* 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.attackindicator;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup(
keyName = "attackindicator",
name = "Attack Indicators",
description = "Configuration for the attack indicator plugin"
)
public interface AttackIndicatorConfig extends Config
{
@ConfigItem(
keyName = "enabled",
name = "Enabled",
description = "Configures whether or not the attack indicator overlay is displayed"
)
default boolean enabled()
{
return true;
}
}

View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
* 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.attackindicator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
public class AttackIndicatorOverlay extends Overlay
{
private static final int ANCHOR_X = -4;
private static final int ANCHOR_Y = -1;
private static final int BORDER_SIZE = 2;
private static final Color BACKGROUND_COLOR = new Color(56, 48, 35, 100);
private static final Color OUTSIDE_STROKE_COLOR = new Color(56, 48, 35, 255);
private static final Color INSIDE_STROKE_COLOR = new Color(90, 82, 69, 255);
@Inject
@Nullable
Client client;
private final AttackIndicatorConfig config;
private final AttackIndicatorPlugin plugin;
@Inject
public AttackIndicatorOverlay(AttackIndicatorPlugin plugin, AttackIndicatorConfig config)
{
super(OverlayPosition.DYNAMIC);
this.plugin = plugin;
this.config = config;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (!config.enabled() || client.getGameState() != GameState.LOGGED_IN)
{
return null;
}
Rectangle chatbox = getChatboxBounds();
if (chatbox == null)
{
return null;
}
// Setup string
graphics.setFont(FontManager.getRunescapeFont());
FontMetrics fm = graphics.getFontMetrics();
String attackStyleString = plugin.getAttackStyle().getName();
// Create anchor point
Point anchor = new Point(chatbox.x + chatbox.width + ANCHOR_X, chatbox.y + ANCHOR_Y);
// Calculate size of background
Rectangle background = fm.getStringBounds(attackStyleString, graphics).getBounds();
background.setBounds(background.x, background.y, background.width + BORDER_SIZE, background.height + BORDER_SIZE);
// Render background
graphics.setColor(BACKGROUND_COLOR);
graphics.fillRect(anchor.x - background.width, anchor.y - background.height, background.width, background.height);
// Render outside stroke
graphics.setColor(OUTSIDE_STROKE_COLOR);
graphics.drawRect(anchor.x - background.width, anchor.y - background.height, background.width + BORDER_SIZE / 2, background.height + BORDER_SIZE / 2);
// Render inside stroke
graphics.setColor(INSIDE_STROKE_COLOR);
graphics.drawRect(anchor.x - background.width + BORDER_SIZE / 2, anchor.y - background.height + BORDER_SIZE / 2, background.width - BORDER_SIZE / 2, background.height - BORDER_SIZE / 2);
// Render text with shadow
graphics.setColor(Color.BLACK);
graphics.drawString(attackStyleString, anchor.x - background.width + 3, anchor.y);
graphics.setColor(Color.WHITE);
graphics.drawString(attackStyleString, anchor.x - background.width + 2, anchor.y - 1);
return null;
}
private Rectangle getChatboxBounds()
{
Widget chatbox = client.getWidget(WidgetInfo.CHATBOX);
return chatbox != null ? chatbox.getBounds() : null;
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
* 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.attackindicator;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Binder;
import com.google.inject.Provides;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Varbits;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.VarbitChanged;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import static net.runelite.client.plugins.attackindicator.AttackStyle.CASTING;
import static net.runelite.client.plugins.attackindicator.AttackStyle.DEFENSIVE_CASTING;
@PluginDescriptor(
name = "Attack indicator plugin"
)
public class AttackIndicatorPlugin extends Plugin
{
@Inject
@Nullable
Client client;
private int attackStyleVarbit = -1;
private int equippedWeaponTypeVarbit = -1;
private int castingModeVarbit = -1;
private AttackStyle attackStyle;
@Inject
AttackIndicatorOverlay overlay;
@Override
public void configure(Binder binder)
{
binder.bind(AttackIndicatorOverlay.class);
}
@Provides
AttackIndicatorConfig provideConfig(ConfigManager configManager)
{
return configManager.getConfig(AttackIndicatorConfig.class);
}
@Override
public AttackIndicatorOverlay getOverlay()
{
return overlay;
}
public AttackStyle getAttackStyle()
{
return attackStyle;
}
@Subscribe
public void onAttackStyleChange(VarbitChanged event)
{
if (attackStyleVarbit == -1 || attackStyleVarbit != client.getSetting(Varbits.ATTACK_STYLE))
{
attackStyleVarbit = client.getSetting(Varbits.ATTACK_STYLE);
updateAttackStyle(client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit,
client.getSetting(Varbits.DEFENSIVE_CASTING_MODE));
}
}
@Subscribe
public void onEquippedWeaponTypeChange(VarbitChanged event)
{
if (equippedWeaponTypeVarbit == -1 || equippedWeaponTypeVarbit != client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE))
{
equippedWeaponTypeVarbit = client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE);
updateAttackStyle(equippedWeaponTypeVarbit, client.getSetting(Varbits.ATTACK_STYLE),
client.getSetting(Varbits.DEFENSIVE_CASTING_MODE));
}
}
@Subscribe
public void onCastingModeChange(VarbitChanged event)
{
if (castingModeVarbit == -1 || castingModeVarbit != client.getSetting(Varbits.DEFENSIVE_CASTING_MODE))
{
castingModeVarbit = client.getSetting(Varbits.DEFENSIVE_CASTING_MODE);
updateAttackStyle(client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE), client.getSetting(Varbits.ATTACK_STYLE),
castingModeVarbit);
}
}
private void updateAttackStyle(int equippedWeaponType, int attackStyleIndex, int castingMode)
{
AttackStyle[] attackStyles = WeaponType.getWeaponType(equippedWeaponType).getAttackStyles();
if (attackStyleIndex < attackStyles.length)
{
attackStyle = attackStyles[attackStyleIndex];
if (attackStyle == null)
{
return;
}
if ((attackStyle == CASTING) && (castingMode == 1))
{
attackStyle = DEFENSIVE_CASTING;
}
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
* 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.attackindicator;
public enum AttackStyle
{
ACCURATE("Accurate"),
AGGRESSIVE("Aggressive"),
DEFENSIVE("Defensive"),
CONTROLLED("Controlled"),
RANGING("Ranging"),
LONGRANGE("Longrange"),
CASTING("Casting"),
DEFENSIVE_CASTING("Defensive Casting"),
OTHER("Other");
private final String name;
AttackStyle(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2017, honeyhoney <https://github.com/honeyhoney>
* 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.attackindicator;
import java.util.HashMap;
import java.util.Map;
import static net.runelite.client.plugins.attackindicator.AttackStyle.*;
public enum WeaponType
{
TYPE_0(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
TYPE_1(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
TYPE_2(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
TYPE_3(RANGING, RANGING, null, LONGRANGE),
TYPE_4(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
TYPE_5(RANGING, RANGING, null, LONGRANGE),
TYPE_6(AGGRESSIVE, RANGING, DEFENSIVE_CASTING, null),
TYPE_7(RANGING, RANGING, null, DEFENSIVE_CASTING),
TYPE_8(OTHER, AGGRESSIVE, null, null),
TYPE_9(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
TYPE_10(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
TYPE_11(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
TYPE_12(CONTROLLED, AGGRESSIVE, null, DEFENSIVE),
TYPE_13(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
TYPE_14(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
TYPE_15(CONTROLLED, CONTROLLED, CONTROLLED, DEFENSIVE),
TYPE_16(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
TYPE_17(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
TYPE_18(ACCURATE, AGGRESSIVE, null, DEFENSIVE, CASTING),
TYPE_19(RANGING, RANGING, null, LONGRANGE),
TYPE_20(ACCURATE, CONTROLLED, null, LONGRANGE),
TYPE_21(ACCURATE, AGGRESSIVE, null, DEFENSIVE),
TYPE_22(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),
TYPE_23(CASTING, CASTING, null, DEFENSIVE_CASTING),
TYPE_24(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
TYPE_25(CONTROLLED, AGGRESSIVE, null, DEFENSIVE),
TYPE_26(AGGRESSIVE, AGGRESSIVE, null, AGGRESSIVE),
TYPE_27(ACCURATE, null, null, OTHER);
private static final Map<Integer, WeaponType> weaponTypes = new HashMap<>();
private final AttackStyle[] attackStyles;
static
{
for (WeaponType weaponType : values())
{
weaponTypes.put(weaponType.ordinal(), weaponType);
}
}
WeaponType(AttackStyle... attackStyles)
{
this.attackStyles = attackStyles;
}
public AttackStyle[] getAttackStyles()
{
return attackStyles;
}
public static WeaponType getWeaponType(int id)
{
return weaponTypes.get(id);
}
}