Added attack style warnings and option to remove warned attack styles

This commit is contained in:
honeyhoney
2017-11-20 21:07:02 +00:00
committed by Adam
parent ea810a344e
commit 98380f7803
5 changed files with 299 additions and 21 deletions

View File

@@ -29,7 +29,7 @@ import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem; import net.runelite.client.config.ConfigItem;
@ConfigGroup( @ConfigGroup(
keyName = "attackindicator", keyName = "attackIndicator",
name = "Attack Indicators", name = "Attack Indicators",
description = "Configuration for the attack indicator plugin" description = "Configuration for the attack indicator plugin"
) )
@@ -37,12 +37,78 @@ public interface AttackIndicatorConfig extends Config
{ {
@ConfigItem( @ConfigItem(
keyName = "enabled", keyName = "enabled",
name = "Enabled", name = "Show attack style",
description = "Configures whether or not the attack indicator overlay is displayed" description = "Configures whether or not the attack indicator overlay is displayed",
position = 1
) )
default boolean enabled() default boolean enabled()
{ {
return true; return true;
} }
@ConfigItem(
keyName = "warnForDefensive",
name = "Warn for defensive",
description = "Configures whether or not users are warned for selecting a defensive combat option",
position = 2
)
default boolean warnForDefensive()
{
return false;
}
@ConfigItem(
keyName = "warnForAttack",
name = "Warn for attack",
description = "Configures whether or not users are warned for selecting an attack combat option",
position = 3
)
default boolean warnForAttack()
{
return false;
}
@ConfigItem(
keyName = "warnForStrength",
name = "Warn for strength",
description = "Configures whether or not users are warned for selecting a strength combat option",
position = 4
)
default boolean warnForStrength()
{
return false;
}
@ConfigItem(
keyName = "warnForRanged",
name = "Warn for ranged",
description = "Configures whether or not users are warned for selecting a ranged combat option",
position = 5
)
default boolean warnForRanged()
{
return false;
}
@ConfigItem(
keyName = "warnForMagic",
name = "Warn for magic",
description = "Configures whether or not users are warned for selecting a magic combat option",
position = 6
)
default boolean warnForMagic()
{
return false;
}
@ConfigItem(
keyName = "removeWarnedStyles",
name = "Remove warned styles",
description = "Configures whether or not warned styles are removed from the combat options tab",
position = 7
)
default boolean removeWarnedStyles()
{
return false;
}
} }

View File

@@ -105,7 +105,14 @@ public class AttackIndicatorOverlay extends Overlay
// Render text with shadow // Render text with shadow
graphics.setColor(Color.BLACK); graphics.setColor(Color.BLACK);
graphics.drawString(attackStyleString, anchor.x - background.width + 3, anchor.y); graphics.drawString(attackStyleString, anchor.x - background.width + 3, anchor.y);
graphics.setColor(Color.WHITE); if (plugin.isWarnedSkillSelected())
{
graphics.setColor(Color.RED);
}
else
{
graphics.setColor(Color.WHITE);
}
graphics.drawString(attackStyleString, anchor.x - background.width + 2, anchor.y - 1); graphics.drawString(attackStyleString, anchor.x - background.width + 2, anchor.y - 1);
return null; return null;

View File

@@ -24,33 +24,52 @@
*/ */
package net.runelite.client.plugins.attackindicator; package net.runelite.client.plugins.attackindicator;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import com.google.inject.Binder; import com.google.inject.Binder;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.Skill;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.VarbitChanged; import net.runelite.client.events.VarbitChanged;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import static net.runelite.client.plugins.attackindicator.AttackStyle.CASTING; import static net.runelite.client.plugins.attackindicator.AttackStyle.*;
import static net.runelite.client.plugins.attackindicator.AttackStyle.DEFENSIVE_CASTING; import net.runelite.client.task.Schedule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@PluginDescriptor( @PluginDescriptor(
name = "Attack indicator plugin" name = "Attack indicator plugin"
) )
public class AttackIndicatorPlugin extends Plugin public class AttackIndicatorPlugin extends Plugin
{ {
@Inject private static final Logger logger = LoggerFactory.getLogger(AttackIndicatorPlugin.class);
@Nullable
Client client;
private int attackStyleVarbit = -1; private int attackStyleVarbit = -1;
private int equippedWeaponTypeVarbit = -1; private int equippedWeaponTypeVarbit = -1;
private int castingModeVarbit = -1; private int castingModeVarbit = -1;
private AttackStyle attackStyle; private AttackStyle attackStyle;
private final Set<Skill> warnedSkills = new HashSet<>();
private boolean warnedSkillSelected = false;
private final Table<WeaponType, WidgetInfo, Boolean> widgetsToHide = HashBasedTable.create();
@Inject
@Nullable
Client client;
@Inject
AttackIndicatorConfig config;
@Inject @Inject
AttackIndicatorOverlay overlay; AttackIndicatorOverlay overlay;
@@ -78,6 +97,43 @@ public class AttackIndicatorPlugin extends Plugin
return attackStyle; return attackStyle;
} }
public boolean isWarnedSkillSelected()
{
return warnedSkillSelected;
}
@Override
protected void startUp() throws Exception
{
updateWarnedSkills(config.warnForAttack(), Skill.ATTACK);
updateWarnedSkills(config.warnForStrength(), Skill.STRENGTH);
updateWarnedSkills(config.warnForDefensive(), Skill.DEFENCE);
updateWarnedSkills(config.warnForRanged(), Skill.RANGED);
updateWarnedSkills(config.warnForMagic(), Skill.MAGIC);
}
@Schedule(
period = 600,
unit = ChronoUnit.MILLIS
)
public void hideWidgets()
{
if (widgetsToHide == null)
{
return;
}
WeaponType equippedWeaponType = WeaponType.getWeaponType(equippedWeaponTypeVarbit);
if (widgetsToHide.containsRow(equippedWeaponType))
{
for (WidgetInfo widgetKey : widgetsToHide.row(equippedWeaponType).keySet())
{
hideWidget(client.getWidget(widgetKey), widgetsToHide.get(equippedWeaponType, widgetKey));
}
}
}
@Subscribe @Subscribe
public void onAttackStyleChange(VarbitChanged event) public void onAttackStyleChange(VarbitChanged event)
{ {
@@ -86,6 +142,7 @@ public class AttackIndicatorPlugin extends Plugin
attackStyleVarbit = client.getSetting(Varbits.ATTACK_STYLE); attackStyleVarbit = client.getSetting(Varbits.ATTACK_STYLE);
updateAttackStyle(client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit, updateAttackStyle(client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE), attackStyleVarbit,
client.getSetting(Varbits.DEFENSIVE_CASTING_MODE)); client.getSetting(Varbits.DEFENSIVE_CASTING_MODE));
updateWarning(false);
} }
} }
@@ -97,6 +154,7 @@ public class AttackIndicatorPlugin extends Plugin
equippedWeaponTypeVarbit = client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE); equippedWeaponTypeVarbit = client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE);
updateAttackStyle(equippedWeaponTypeVarbit, client.getSetting(Varbits.ATTACK_STYLE), updateAttackStyle(equippedWeaponTypeVarbit, client.getSetting(Varbits.ATTACK_STYLE),
client.getSetting(Varbits.DEFENSIVE_CASTING_MODE)); client.getSetting(Varbits.DEFENSIVE_CASTING_MODE));
updateWarning(true);
} }
} }
@@ -108,6 +166,41 @@ public class AttackIndicatorPlugin extends Plugin
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), updateAttackStyle(client.getSetting(Varbits.EQUIPPED_WEAPON_TYPE), client.getSetting(Varbits.ATTACK_STYLE),
castingModeVarbit); castingModeVarbit);
updateWarning(false);
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("attackIndicator"))
{
boolean enabled = event.getNewValue().equals("true");
switch (event.getKey())
{
case "enabled":
break;
case "warnForDefensive":
updateWarnedSkills(enabled, Skill.DEFENCE);
break;
case "warnForAttack":
updateWarnedSkills(enabled, Skill.ATTACK);
break;
case "warnForStrength":
updateWarnedSkills(enabled, Skill.STRENGTH);
break;
case "warnForRanged":
updateWarnedSkills(enabled, Skill.RANGED);
break;
case "warnForMagic":
updateWarnedSkills(enabled, Skill.MAGIC);
break;
case "removeWarnedStyles":
hideWarnedStyles(enabled);
break;
default:
logger.warn("Unreachable default case for config keys");
}
} }
} }
@@ -119,13 +212,116 @@ public class AttackIndicatorPlugin extends Plugin
attackStyle = attackStyles[attackStyleIndex]; attackStyle = attackStyles[attackStyleIndex];
if (attackStyle == null) if (attackStyle == null)
{ {
return; attackStyle = OTHER;
} }
if ((attackStyle == CASTING) && (castingMode == 1)) else if ((attackStyle == CASTING) && (castingMode == 1))
{ {
attackStyle = DEFENSIVE_CASTING; attackStyle = DEFENSIVE_CASTING;
} }
} }
} }
private void updateWarnedSkills(boolean enabled, Skill skill)
{
if (enabled)
{
warnedSkills.remove(skill);
warnedSkills.add(skill);
}
else
{
warnedSkills.remove(skill);
}
updateWarning(false);
}
private void updateWarning(boolean weaponSwitch)
{
warnedSkillSelected = false;
if (attackStyle != null)
{
for (Skill skill : attackStyle.getSkills())
{
if (warnedSkills.contains(skill))
{
if (weaponSwitch)
{
// TODO : chat message to warn players that their weapon switch also caused an unwanted attack style change
}
warnedSkillSelected = true;
break;
}
}
}
hideWarnedStyles(config.removeWarnedStyles());
}
private void hideWarnedStyles(boolean enabled)
{
WeaponType equippedWeaponType = WeaponType.getWeaponType(equippedWeaponTypeVarbit);
if (equippedWeaponType == null)
{
return;
}
AttackStyle[] attackStyles = equippedWeaponType.getAttackStyles();
// Iterate over attack styles
for (int i = 0; i < attackStyles.length; i++)
{
if (attackStyles[i] == null)
{
continue;
}
boolean warnedSkill = false;
for (Skill skill : attackStyles[i].getSkills())
{
if (warnedSkills.contains(skill))
{
warnedSkill = true;
break;
}
}
// Magic staves defensive casting mode
if (equippedWeaponType == WeaponType.TYPE_18)
{
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_BOX, enabled && (warnedSkills.contains(Skill.DEFENCE) || warnedSkill));
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_ICON, enabled && (warnedSkills.contains(Skill.DEFENCE) || warnedSkill));
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_SHIELD, enabled && (warnedSkills.contains(Skill.DEFENCE) || warnedSkill));
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_DEFENSIVE_SPELL_TEXT, enabled && (warnedSkills.contains(Skill.DEFENCE) || warnedSkill));
}
// Remove appropriate combat option
switch (i)
{
case 0:
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_ONE, enabled && warnedSkill);
break;
case 1:
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_TWO, enabled && warnedSkill);
break;
case 2:
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_THREE, enabled && warnedSkill);
break;
case 3:
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_STYLE_FOUR, enabled && warnedSkill);
break;
case 4:
widgetsToHide.put(equippedWeaponType, WidgetInfo.COMBAT_SPELLS, enabled && warnedSkill);
break;
default:
logger.warn("Unreachable default case for equipped weapon type attack styles");
}
}
}
private void hideWidget(Widget widget, boolean hidden)
{
if (widget != null)
{
widget.setHidden(hidden);
}
}
} }

View File

@@ -24,27 +24,36 @@
*/ */
package net.runelite.client.plugins.attackindicator; package net.runelite.client.plugins.attackindicator;
import net.runelite.api.Skill;
public enum AttackStyle public enum AttackStyle
{ {
ACCURATE("Accurate"), ACCURATE("Accurate", Skill.ATTACK),
AGGRESSIVE("Aggressive"), AGGRESSIVE("Aggressive", Skill.STRENGTH),
DEFENSIVE("Defensive"), DEFENSIVE("Defensive", Skill.DEFENCE),
CONTROLLED("Controlled"), CONTROLLED("Controlled", Skill.ATTACK, Skill.STRENGTH, Skill.DEFENCE),
RANGING("Ranging"), RANGING("Ranging", Skill.RANGED),
LONGRANGE("Longrange"), LONGRANGE("Longrange", Skill.RANGED, Skill.DEFENCE),
CASTING("Casting"), CASTING("Casting", Skill.MAGIC),
DEFENSIVE_CASTING("Defensive Casting"), DEFENSIVE_CASTING("Defensive Casting", Skill.MAGIC, Skill.DEFENCE),
OTHER("Other"); OTHER("Other");
private final String name; private final String name;
private final Skill[] skills;
AttackStyle(String name) AttackStyle(String name, Skill... skills)
{ {
this.name = name; this.name = name;
this.skills = skills;
} }
public String getName() public String getName()
{ {
return name; return name;
} }
public Skill[] getSkills()
{
return skills;
}
} }

View File

@@ -37,7 +37,7 @@ public enum WeaponType
TYPE_4(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE), TYPE_4(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
TYPE_5(RANGING, RANGING, null, LONGRANGE), TYPE_5(RANGING, RANGING, null, LONGRANGE),
TYPE_6(AGGRESSIVE, RANGING, DEFENSIVE_CASTING, null), TYPE_6(AGGRESSIVE, RANGING, DEFENSIVE_CASTING, null),
TYPE_7(RANGING, RANGING, null, DEFENSIVE_CASTING), TYPE_7(RANGING, RANGING, null, LONGRANGE),
TYPE_8(OTHER, AGGRESSIVE, null, null), TYPE_8(OTHER, AGGRESSIVE, null, null),
TYPE_9(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE), TYPE_9(ACCURATE, AGGRESSIVE, CONTROLLED, DEFENSIVE),
TYPE_10(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE), TYPE_10(ACCURATE, AGGRESSIVE, AGGRESSIVE, DEFENSIVE),