combat level plugin: Add attack level range option
This commit adds a PVP-world-like combat level range text to the wilderness level in non-PVP worlds, displaying the range of combats you can attack at any given wilderness level. Closes runelite/runelite#3103 Closes runelite/runelite#3318
This commit is contained in:
@@ -40,4 +40,14 @@ public interface CombatLevelConfig extends Config
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "wildernessAttackLevelRange",
|
||||||
|
name = "Show level range in wilderness",
|
||||||
|
description = "Displays a PVP-world-like attack level range in the wilderness"
|
||||||
|
)
|
||||||
|
default boolean wildernessAttackLevelRange()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||||
|
* Copyright (c) 2019, Jordan Atwood <nightfirecat@protonmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -26,14 +27,20 @@ package net.runelite.client.plugins.combatlevel;
|
|||||||
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Experience;
|
import net.runelite.api.Experience;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.WorldType;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.GameTick;
|
import net.runelite.api.events.GameTick;
|
||||||
|
import net.runelite.api.events.ScriptCallbackEvent;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
@@ -42,15 +49,31 @@ import net.runelite.client.ui.overlay.OverlayManager;
|
|||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Combat Level",
|
name = "Combat Level",
|
||||||
description = "Show a more accurate combat level in Combat Options panel"
|
description = "Show a more accurate combat level in Combat Options panel and other combat level functions",
|
||||||
|
tags = {"wilderness", "attack", "range"}
|
||||||
)
|
)
|
||||||
public class CombatLevelPlugin extends Plugin
|
public class CombatLevelPlugin extends Plugin
|
||||||
{
|
{
|
||||||
private final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###");
|
||||||
|
private static final String CONFIG_GROUP = "combatlevel";
|
||||||
|
private static final String ATTACK_RANGE_CONFIG_KEY = "wildernessAttackLevelRange";
|
||||||
|
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+)$");
|
||||||
|
private static final int SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y = 6;
|
||||||
|
private static final int WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y = 3;
|
||||||
|
private static final int MIN_COMBAT_LEVEL = 3;
|
||||||
|
|
||||||
|
private int originalWildernessLevelTextPosition = -1;
|
||||||
|
private int originalSkullContainerPosition = -1;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientThread clientThread;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CombatLevelConfig config;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CombatLevelOverlay overlay;
|
private CombatLevelOverlay overlay;
|
||||||
|
|
||||||
@@ -67,6 +90,11 @@ public class CombatLevelPlugin extends Plugin
|
|||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
overlayManager.add(overlay);
|
overlayManager.add(overlay);
|
||||||
|
|
||||||
|
if (config.wildernessAttackLevelRange())
|
||||||
|
{
|
||||||
|
appendAttackLevelRangeText();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,6 +112,8 @@ public class CombatLevelPlugin extends Plugin
|
|||||||
combatLevelWidget.setText(widgetText.substring(0, widgetText.indexOf(".")));
|
combatLevelWidget.setText(widgetText.substring(0, widgetText.indexOf(".")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shutDownAttackLevelRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -112,4 +142,103 @@ public class CombatLevelPlugin extends Plugin
|
|||||||
|
|
||||||
combatLevelWidget.setText("Combat Lvl: " + DECIMAL_FORMAT.format(combatLevelPrecise));
|
combatLevelWidget.setText("Combat Lvl: " + DECIMAL_FORMAT.format(combatLevelPrecise));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onConfigChanged(ConfigChanged event)
|
||||||
|
{
|
||||||
|
if (!CONFIG_GROUP.equals(event.getGroup()) || !ATTACK_RANGE_CONFIG_KEY.equals(event.getKey()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.wildernessAttackLevelRange())
|
||||||
|
{
|
||||||
|
appendAttackLevelRangeText();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shutDownAttackLevelRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||||
|
{
|
||||||
|
if (config.wildernessAttackLevelRange()
|
||||||
|
&& "wildernessWidgetTextSet".equals(event.getEventName()))
|
||||||
|
{
|
||||||
|
appendAttackLevelRangeText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendAttackLevelRangeText()
|
||||||
|
{
|
||||||
|
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||||
|
if (wildernessLevelWidget == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String wildernessLevelText = wildernessLevelWidget.getText();
|
||||||
|
final Matcher m = WILDERNESS_LEVEL_PATTERN.matcher(wildernessLevelText);
|
||||||
|
if (!m.matches()
|
||||||
|
|| WorldType.isPvpWorld(client.getWorldType()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER);
|
||||||
|
if (originalWildernessLevelTextPosition == -1)
|
||||||
|
{
|
||||||
|
originalWildernessLevelTextPosition = wildernessLevelWidget.getOriginalY();
|
||||||
|
}
|
||||||
|
if (originalSkullContainerPosition == -1)
|
||||||
|
{
|
||||||
|
originalSkullContainerPosition = skullContainer.getRelativeY();
|
||||||
|
}
|
||||||
|
|
||||||
|
final int wildernessLevel = Integer.parseInt(m.group(1));
|
||||||
|
final int combatLevel = client.getLocalPlayer().getCombatLevel();
|
||||||
|
|
||||||
|
wildernessLevelWidget.setText(wildernessLevelText + "<br>" + combatAttackRange(combatLevel, wildernessLevel));
|
||||||
|
wildernessLevelWidget.setOriginalY(WILDERNESS_LEVEL_TEXT_ADJUSTED_ORIGINAL_Y);
|
||||||
|
skullContainer.setOriginalY(SKULL_CONTAINER_ADJUSTED_ORIGINAL_Y);
|
||||||
|
|
||||||
|
clientThread.invoke(wildernessLevelWidget::revalidate);
|
||||||
|
clientThread.invoke(skullContainer::revalidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shutDownAttackLevelRange()
|
||||||
|
{
|
||||||
|
if (WorldType.isPvpWorld(client.getWorldType()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
|
||||||
|
if (wildernessLevelWidget != null)
|
||||||
|
{
|
||||||
|
String wildernessLevelText = wildernessLevelWidget.getText();
|
||||||
|
if (wildernessLevelText.contains("<br>"))
|
||||||
|
{
|
||||||
|
wildernessLevelWidget.setText(wildernessLevelText.substring(0, wildernessLevelText.indexOf("<br>")));
|
||||||
|
}
|
||||||
|
wildernessLevelWidget.setOriginalY(originalWildernessLevelTextPosition);
|
||||||
|
clientThread.invoke(wildernessLevelWidget::revalidate);
|
||||||
|
}
|
||||||
|
originalWildernessLevelTextPosition = -1;
|
||||||
|
|
||||||
|
final Widget skullContainer = client.getWidget(WidgetInfo.PVP_SKULL_CONTAINER);
|
||||||
|
if (skullContainer != null)
|
||||||
|
{
|
||||||
|
skullContainer.setOriginalY(originalSkullContainerPosition);
|
||||||
|
clientThread.invoke(skullContainer::revalidate);
|
||||||
|
}
|
||||||
|
originalSkullContainerPosition = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String combatAttackRange(final int combatLevel, final int wildernessLevel)
|
||||||
|
{
|
||||||
|
return Math.max(MIN_COMBAT_LEVEL, combatLevel - wildernessLevel) + "-" + Math.min(Experience.MAX_COMBAT_LEVEL, combatLevel + wildernessLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,4 +114,6 @@ LABEL85:
|
|||||||
LABEL88:
|
LABEL88:
|
||||||
iload 1
|
iload 1
|
||||||
invoke 387
|
invoke 387
|
||||||
|
sconst "wildernessWidgetTextSet" ; set callback name
|
||||||
|
runelite_callback ; invoke callback
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user