From 541ad1e26de261e567886dc31aa5c77e3a53ea5d Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Mon, 31 Dec 2018 10:34:45 -0800 Subject: [PATCH 1/2] combatlevel: Clean up plugin code This commit moves constants from the test to the overlay, and replaces instances of magic numbers with them. It additionally fixes the odd check in `correctPrayer()` and fixes some minor whitespace issues. --- .../combatlevel/CombatLevelOverlay.java | 41 +++++++++++-------- .../combatlevel/CombatLevelPluginTest.java | 17 +++++--- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java index 7fda7c0f8a..7e1ded7990 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java @@ -43,6 +43,11 @@ import java.awt.Rectangle; class CombatLevelOverlay extends Overlay { private static final Color COMBAT_LEVEL_COLOUR = new Color(0xff981f); + static final double ATT_STR_MULT = 0.325; + static final double DEF_HP_MULT = 0.25; + static final double PRAY_MULT = 0.125; + static final double RANGE_MAGIC_LEVEL_MULT = 1.5; + static final double RANGE_MAGIC_MULT = 0.325; private final Client client; private final CombatLevelConfig config; @@ -94,17 +99,17 @@ class CombatLevelOverlay extends Overlay int prayerLevel = client.getRealSkillLevel(Skill.PRAYER); // calculate initial required numbers - double base = 0.25 * (defenceLevel + hitpointsLevel + Math.floor(prayerLevel / 2)); - double melee = 0.325 * (attackLevel + strengthLevel); - double range = 0.325 * Math.floor(rangedLevel * 1.5); - double mage = 0.325 * Math.floor(magicLevel * 1.5); + double base = DEF_HP_MULT * (defenceLevel + hitpointsLevel + Math.floor(prayerLevel / 2)); + double melee = ATT_STR_MULT * (attackLevel + strengthLevel); + double range = RANGE_MAGIC_MULT * Math.floor(rangedLevel * RANGE_MAGIC_LEVEL_MULT); + double mage = RANGE_MAGIC_MULT * Math.floor(magicLevel * RANGE_MAGIC_LEVEL_MULT); double max = Math.max(melee, Math.max(range, mage)); // find the needed levels until level up int next = client.getLocalPlayer().getCombatLevel() + 1; - int meleeNeed = calcLevels(base + melee, next, 0.325); - int hpdefNeed = calcLevels(base + max, next, 0.25); - int prayNeed = calcLevels(base + max, next, 0.125); + int meleeNeed = calcLevels(base + melee, next, ATT_STR_MULT); + int hpdefNeed = calcLevels(base + max, next, DEF_HP_MULT); + int prayNeed = calcLevels(base + max, next, PRAY_MULT); int rangeNeed = calcLevelsRM(rangedLevel, next, base); int magicNeed = calcLevelsRM(magicLevel, next, base); @@ -115,30 +120,30 @@ class CombatLevelOverlay extends Overlay StringBuilder sb = new StringBuilder(); sb.append(ColorUtil.wrapWithColorTag("Next combat level:
", COMBAT_LEVEL_COLOUR)); - if ((attackLevel + strengthLevel + meleeNeed) <= 198) + if ((attackLevel + strengthLevel + meleeNeed) <= Experience.MAX_REAL_LEVEL * 2) { sb.append(meleeNeed).append(" Attack/Strength
"); } - if ((hitpointsLevel + defenceLevel + hpdefNeed) <= 198) + if ((hitpointsLevel + defenceLevel + hpdefNeed) <= Experience.MAX_REAL_LEVEL * 2) { sb.append(hpdefNeed).append(" Defence/Hitpoints
"); } - if ((rangedLevel + rangeNeed) <= 99) + if ((rangedLevel + rangeNeed) <= Experience.MAX_REAL_LEVEL) { sb.append(rangeNeed).append(" Ranged
"); } - if ((magicLevel + magicNeed) <= 99) + if ((magicLevel + magicNeed) <= Experience.MAX_REAL_LEVEL) { sb.append(magicNeed).append(" Magic
"); } - if ((prayerLevel + prayNeed) <= 99) + if ((prayerLevel + prayNeed) <= Experience.MAX_REAL_LEVEL) { sb.append(prayNeed).append(" Prayer"); } return sb.toString(); } - /*** + /** * Calculate skill levels required for increasing combat level, meant * for all combat skills besides ranged and magic. * @param start initial value @@ -152,7 +157,7 @@ class CombatLevelOverlay extends Overlay return (int) Math.ceil((end - start) / multiple); } - /*** + /** * Calculate skill levels required for increasing combat level, meant * ONLY for Ranged and Magic skills. * @param start either the current ranged or magic level @@ -163,11 +168,11 @@ class CombatLevelOverlay extends Overlay @VisibleForTesting static int calcLevelsRM(double start, int end, double dhp) { - start = Math.floor(start * 1.5) * 0.325; - return (int) Math.ceil((end - dhp - start) / 0.4875); + start = Math.floor(start * RANGE_MAGIC_LEVEL_MULT) * RANGE_MAGIC_MULT; + return (int) Math.ceil((end - dhp - start) / (RANGE_MAGIC_MULT * RANGE_MAGIC_LEVEL_MULT)); } - /*** + /** * Corrects how many levels you need to level up combat through prayer. * @param level current prayer level * @param need needed prayer level calculated by calcLevels(...) @@ -176,7 +181,7 @@ class CombatLevelOverlay extends Overlay @VisibleForTesting static int correctPrayer(int level, int need) { - if ((level + need) % 2 == 1) + if ((level + need) % 2 != 0) { need++; } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java index b1c4604834..c7000a67ac 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java @@ -33,6 +33,11 @@ import net.runelite.api.Skill; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.calcLevels; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.calcLevelsRM; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.correctPrayer; +import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.ATT_STR_MULT; +import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.DEF_HP_MULT; +import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.PRAY_MULT; +import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.RANGE_MAGIC_LEVEL_MULT; +import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.RANGE_MAGIC_MULT; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; @@ -73,10 +78,10 @@ public class CombatLevelPluginTest int rangedLevel = client.getRealSkillLevel(Skill.RANGED); int prayerLevel = client.getRealSkillLevel(Skill.PRAYER); - double base = 0.25 * (defenceLevel + hitpointsLevel + Math.floor(prayerLevel / 2)); - double melee = 0.325 * (attackLevel + strengthLevel); - double range = 0.325 * Math.floor(rangedLevel * 1.5); - double mage = 0.325 * Math.floor(magicLevel * 1.5); + double base = DEF_HP_MULT * (defenceLevel + hitpointsLevel + Math.floor(prayerLevel / 2)); + double melee = ATT_STR_MULT * (attackLevel + strengthLevel); + double range = RANGE_MAGIC_MULT * Math.floor(rangedLevel * RANGE_MAGIC_LEVEL_MULT); + double mage = RANGE_MAGIC_MULT * Math.floor(magicLevel * RANGE_MAGIC_LEVEL_MULT); double max = Math.max(melee, Math.max(range, mage)); HashMap result = new HashMap<>(); @@ -102,11 +107,11 @@ public class CombatLevelPluginTest // test attack/strength assertEquals(2, calcLevels(baseValues.get("base") + baseValues.get("melee"), - player.getCombatLevel() + 1, ATT_STR_MULT)); + player.getCombatLevel() + 1, ATT_STR_MULT)); // test defence/hitpoints assertEquals(3, calcLevels(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, DEF_HP_MULT)); + player.getCombatLevel() + 1, DEF_HP_MULT)); // test prayer int prayNeed = calcLevels(baseValues.get("base") + baseValues.get("max"), From 5edeeb66339fcfbf89d47650de4065d9a90c9219 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Mon, 31 Dec 2018 10:39:48 -0800 Subject: [PATCH 2/2] combatlevel: Fix prayer level needed to next combat This adds a test which exposes an edge case where the needed prayer levels to next combat level had been calculated to be 3 instead of 1, and fixes that calculation. Fixes runelite/runelite#7103 --- .../combatlevel/CombatLevelOverlay.java | 55 +++++++++++-------- .../combatlevel/CombatLevelPluginTest.java | 51 ++++++++++------- 2 files changed, 62 insertions(+), 44 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java index 7e1ded7990..bc107e31b2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/combatlevel/CombatLevelOverlay.java @@ -43,9 +43,9 @@ import java.awt.Rectangle; class CombatLevelOverlay extends Overlay { private static final Color COMBAT_LEVEL_COLOUR = new Color(0xff981f); + private static final double PRAY_MULT = 0.125; static final double ATT_STR_MULT = 0.325; static final double DEF_HP_MULT = 0.25; - static final double PRAY_MULT = 0.125; static final double RANGE_MAGIC_LEVEL_MULT = 1.5; static final double RANGE_MAGIC_MULT = 0.325; @@ -109,13 +109,10 @@ class CombatLevelOverlay extends Overlay int next = client.getLocalPlayer().getCombatLevel() + 1; int meleeNeed = calcLevels(base + melee, next, ATT_STR_MULT); int hpdefNeed = calcLevels(base + max, next, DEF_HP_MULT); - int prayNeed = calcLevels(base + max, next, PRAY_MULT); + int prayNeed = calcLevelsPray(base + max, next, prayerLevel); int rangeNeed = calcLevelsRM(rangedLevel, next, base); int magicNeed = calcLevelsRM(magicLevel, next, base); - // prayer is a special case, increasing combat every even level. need to correct its value - prayNeed = correctPrayer(prayerLevel, prayNeed); - // create tooltip string StringBuilder sb = new StringBuilder(); sb.append(ColorUtil.wrapWithColorTag("Next combat level:
", COMBAT_LEVEL_COLOUR)); @@ -145,7 +142,7 @@ class CombatLevelOverlay extends Overlay /** * Calculate skill levels required for increasing combat level, meant - * for all combat skills besides ranged and magic. + * for all combat skills besides prayer, ranged, and magic. * @param start initial value * @param end ending value (combat level + 1) * @param multiple how much adding one skill level will change combat @@ -154,7 +151,35 @@ class CombatLevelOverlay extends Overlay @VisibleForTesting static int calcLevels(double start, int end, double multiple) { - return (int) Math.ceil((end - start) / multiple); + return (int) Math.ceil(calcMultipliedLevels(start, end, multiple)); + } + + /** + * Calculate skill levels for increasing combat level, meant ONLY for the Prayer skill. + *

+ * Note: Prayer is a special case, only leveling up upon even level numbers. This is accounted + * for in this function. + *

+ * @param start current combat level + * @param end ending value (combat level + 1) + * @param prayerLevel the player's current prayer level + * @return Prayer levels required to level up combat + */ + @VisibleForTesting + static int calcLevelsPray(double start, int end, int prayerLevel) + { + final int neededLevels = (int) Math.floor(calcMultipliedLevels(start, end, PRAY_MULT)); + + if ((prayerLevel + neededLevels) % 2 != 0) + { + return neededLevels + 1; + } + return neededLevels; + } + + private static double calcMultipliedLevels(double start, int end, double multiple) + { + return (end - start) / multiple; } /** @@ -171,20 +196,4 @@ class CombatLevelOverlay extends Overlay start = Math.floor(start * RANGE_MAGIC_LEVEL_MULT) * RANGE_MAGIC_MULT; return (int) Math.ceil((end - dhp - start) / (RANGE_MAGIC_MULT * RANGE_MAGIC_LEVEL_MULT)); } - - /** - * Corrects how many levels you need to level up combat through prayer. - * @param level current prayer level - * @param need needed prayer level calculated by calcLevels(...) - * @return a corrected number to increase combat through prayer only - */ - @VisibleForTesting - static int correctPrayer(int level, int need) - { - if ((level + need) % 2 != 0) - { - need++; - } - return need; - } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java index c7000a67ac..16400b651d 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/combatlevel/CombatLevelPluginTest.java @@ -31,11 +31,10 @@ import net.runelite.api.Client; import net.runelite.api.Player; import net.runelite.api.Skill; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.calcLevels; +import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.calcLevelsPray; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.calcLevelsRM; -import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.correctPrayer; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.ATT_STR_MULT; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.DEF_HP_MULT; -import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.PRAY_MULT; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.RANGE_MAGIC_LEVEL_MULT; import static net.runelite.client.plugins.combatlevel.CombatLevelOverlay.RANGE_MAGIC_MULT; import static org.junit.Assert.assertEquals; @@ -50,10 +49,6 @@ import java.util.HashMap; @RunWith(MockitoJUnitRunner.class) public class CombatLevelPluginTest { - private static final double ATT_STR_MULT = 0.325; - private static final double DEF_HP_MULT = 0.25; - private static final double PRAY_MULT = 0.125; - @Mock @Bind private Client client; @@ -114,9 +109,8 @@ public class CombatLevelPluginTest player.getCombatLevel() + 1, DEF_HP_MULT)); // test prayer - int prayNeed = calcLevels(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, PRAY_MULT); - assertEquals(5, correctPrayer(client.getRealSkillLevel(Skill.PRAYER), prayNeed)); + assertEquals(5, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); // test ranged assertEquals(2, calcLevelsRM(client.getRealSkillLevel(Skill.RANGED), @@ -150,9 +144,8 @@ public class CombatLevelPluginTest player.getCombatLevel() + 1, DEF_HP_MULT)); // test prayer - int prayNeed = calcLevels(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, PRAY_MULT); - assertEquals(2, correctPrayer(client.getRealSkillLevel(Skill.PRAYER), prayNeed)); + assertEquals(2, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); // test ranged assertEquals(4, calcLevelsRM(client.getRealSkillLevel(Skill.RANGED), @@ -187,9 +180,8 @@ public class CombatLevelPluginTest player.getCombatLevel() + 1, DEF_HP_MULT)); // test prayer - int prayNeed = calcLevels(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, PRAY_MULT); - assertEquals(4, correctPrayer(client.getRealSkillLevel(Skill.PRAYER), prayNeed)); + assertEquals(4, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); // test ranged assertEquals(17, calcLevelsRM(client.getRealSkillLevel(Skill.RANGED), @@ -224,9 +216,8 @@ public class CombatLevelPluginTest player.getCombatLevel() + 1, DEF_HP_MULT)); // test prayer - int prayNeed = calcLevels(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, PRAY_MULT); - assertEquals(3, correctPrayer(client.getRealSkillLevel(Skill.PRAYER), prayNeed)); + assertEquals(3, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); // test ranged assertEquals(14, calcLevelsRM(client.getRealSkillLevel(Skill.RANGED), @@ -262,8 +253,26 @@ public class CombatLevelPluginTest player.getCombatLevel() + 1, DEF_HP_MULT)); // test prayer - int prayNeed = calcLevels(baseValues.get("base") + baseValues.get("max"), - player.getCombatLevel() + 1, PRAY_MULT); - assertEquals(4, correctPrayer(client.getRealSkillLevel(Skill.PRAYER), prayNeed)); + assertEquals(4, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); + } + + @Test + public void testPrayerLevelsNeeded() + { + when(player.getCombatLevel()).thenReturn(124); + when(client.getRealSkillLevel(Skill.ATTACK)).thenReturn(99); + when(client.getRealSkillLevel(Skill.STRENGTH)).thenReturn(99); + when(client.getRealSkillLevel(Skill.DEFENCE)).thenReturn(99); + when(client.getRealSkillLevel(Skill.PRAYER)).thenReturn(89); + when(client.getRealSkillLevel(Skill.RANGED)).thenReturn(99); + when(client.getRealSkillLevel(Skill.MAGIC)).thenReturn(99); + when(client.getRealSkillLevel(Skill.HITPOINTS)).thenReturn(99); + + HashMap baseValues = getBaseValues(); + + // test prayer + assertEquals(1, calcLevelsPray(baseValues.get("base") + baseValues.get("max"), + player.getCombatLevel() + 1, client.getRealSkillLevel(Skill.PRAYER))); } }