aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md10
-rw-r--r--src/main/java/de/cowtipper/cowlection/command/MooCommand.java16
-rw-r--r--src/main/java/de/cowtipper/cowlection/data/HyPlayerData.java1
-rw-r--r--src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java23
-rw-r--r--src/main/java/de/cowtipper/cowlection/data/XpTables.java24
-rw-r--r--src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java2
-rw-r--r--src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java11
-rw-r--r--src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java5
-rw-r--r--src/main/java/de/cowtipper/cowlection/search/GuiSearch.java3
-rw-r--r--src/main/java/de/cowtipper/cowlection/util/Utils.java41
-rw-r--r--src/main/resources/assets/cowlection/lang/en_US.lang4
11 files changed, 97 insertions, 43 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fa5390..b458704 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- SkyBlock Dwarven Mines update:
- Added new minions to `/m analyzeIslands` (Mithril + t12)
+- `/moo stalkskyblock` additions:
+ - Added 'last profile save'
+ - Added Enchanting, Farming and Mining 51-60
+ - Added missing Runecrafting 25
+
+### Changed
+- Refined the comma representation of large numbers abbreviated with k, m, b
+
+### Fixed
+- Fixed issue with 'no dung class selected'
## [1.8.9-0.12.0] - 03.01.2021
### Added
diff --git a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java
index 3a12f46..f3b2962 100644
--- a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java
+++ b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java
@@ -481,11 +481,15 @@ public class MooCommand extends CommandBase {
HySkyBlockStats.Profile.Dungeons dungeons = member.getDungeons();
boolean hasPlayedDungeons = dungeons != null && dungeons.hasPlayed();
if (hasPlayedDungeons) {
- DataHelper.DungeonClass selectedClass = dungeons.getSelectedClass();
-
MooChatComponent dungeonHover = new MooChatComponent("Dungeoneering").gold().bold();
- int selectedClassLevel = dungeons.getSelectedClassLevel();
- dungeonsComponent = new MooChatComponent.KeyValueChatComponent("Dungeoneering", selectedClass.getName() + " " + (MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(selectedClassLevel) : selectedClassLevel))
+
+ DataHelper.DungeonClass selectedClass = dungeons.getSelectedClass();
+ String selectedDungClass = "" + EnumChatFormatting.GRAY + EnumChatFormatting.ITALIC + "no class selected";
+ if (selectedClass != null) {
+ int selectedClassLevel = dungeons.getSelectedClassLevel();
+ selectedDungClass = selectedClass.getName() + " " + (MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(selectedClassLevel) : selectedClassLevel);
+ }
+ dungeonsComponent = new MooChatComponent.KeyValueChatComponent("Dungeoneering", selectedDungClass)
.setHover(dungeonHover);
@@ -616,6 +620,10 @@ public class MooCommand extends CommandBase {
sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Fairy Souls", (member.getFairySoulsCollected() >= 0) ? String.valueOf(member.getFairySoulsCollected()) : "API access disabled"));
// profile age:
sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Profile age", fancyFirstJoined.first()).setHover(new MooChatComponent.KeyValueTooltipComponent("Join date", (fancyFirstJoined.second() == null ? "today" : fancyFirstJoined.second()))));
+ // last save:
+ Pair<String, String> fancyLastSave = member.getFancyLastSave();
+ sbStats.appendFreshSibling(new MooChatComponent.KeyValueChatComponent("Last save", fancyLastSave.first() + " ago").setHover(new MooChatComponent.KeyValueTooltipComponent("Last save", (fancyLastSave.second() == null ? "today" : fancyLastSave.second()))
+ .appendFreshSibling(new MooChatComponent("= last time " + stalkedPlayer.getName() + " has played SkyBlock.").white())));
main.getChatHelper().sendMessage(sbStats);
} else {
diff --git a/src/main/java/de/cowtipper/cowlection/data/HyPlayerData.java b/src/main/java/de/cowtipper/cowlection/data/HyPlayerData.java
index 5a7c168..feca6ba 100644
--- a/src/main/java/de/cowtipper/cowlection/data/HyPlayerData.java
+++ b/src/main/java/de/cowtipper/cowlection/data/HyPlayerData.java
@@ -16,6 +16,7 @@ public class HyPlayerData {
private long lastLogin;
private long lastLogout;
private String mostRecentGameType;
+ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private Map<String, Integer> achievements;
/**
diff --git a/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java b/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java
index b65e48c..fb9fcff 100644
--- a/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java
+++ b/src/main/java/de/cowtipper/cowlection/data/HySkyBlockStats.java
@@ -126,6 +126,7 @@ public class HySkyBlockStats {
private double experience_skill_taming = -1;
private Map<String, SlayerBossDetails> slayer_bosses;
private List<Pet> pets;
+ private JacobData jacob2;
private Dungeons dungeons;
/**
@@ -138,6 +139,10 @@ public class HySkyBlockStats {
return Utils.getDurationAsWords(first_join);
}
+ public Pair<String, String> getFancyLastSave() {
+ return Utils.getDurationAsWords(last_save);
+ }
+
public double getCoinPurse() {
return coin_purse;
}
@@ -149,10 +154,10 @@ public class HySkyBlockStats {
public Map<XpTables.Skill, Integer> getSkills() {
Map<XpTables.Skill, Integer> skills = new TreeMap<>();
if (experience_skill_farming >= 0) {
- skills.put(XpTables.Skill.FARMING, XpTables.Skill.FARMING.getLevel(experience_skill_farming));
+ skills.put(XpTables.Skill.FARMING, XpTables.Skill.FARMING.getLevel(experience_skill_farming, getMaxFarmingLevel()));
}
if (experience_skill_mining >= 0) {
- skills.put(XpTables.Skill.MINING, XpTables.Skill.MINING.getLevel(experience_skill_mining));
+ skills.put(XpTables.Skill.MINING, XpTables.Skill.MINING.getLevel(experience_skill_mining, 60));
}
if (experience_skill_combat >= 0) {
skills.put(XpTables.Skill.COMBAT, XpTables.Skill.COMBAT.getLevel(experience_skill_combat));
@@ -164,7 +169,7 @@ public class HySkyBlockStats {
skills.put(XpTables.Skill.FISHING, XpTables.Skill.FISHING.getLevel(experience_skill_fishing));
}
if (experience_skill_enchanting >= 0) {
- skills.put(XpTables.Skill.ENCHANTING, XpTables.Skill.ENCHANTING.getLevel(experience_skill_enchanting));
+ skills.put(XpTables.Skill.ENCHANTING, XpTables.Skill.ENCHANTING.getLevel(experience_skill_enchanting, 60));
}
if (experience_skill_alchemy >= 0) {
skills.put(XpTables.Skill.ALCHEMY, XpTables.Skill.ALCHEMY.getLevel(experience_skill_alchemy));
@@ -209,6 +214,14 @@ public class HySkyBlockStats {
return null;
}
+ public int getMaxFarmingLevel() {
+ int farmingLevelCap = 50;
+ if (jacob2 != null && jacob2.perks != null) {
+ farmingLevelCap += jacob2.perks.getOrDefault("farming_level_cap", 0);
+ }
+ return farmingLevelCap;
+ }
+
public List<String> getArmor() {
NBTTagCompound nbt = inv_armor.getDecodedData();
List<String> armorList = new ArrayList<>();
@@ -270,6 +283,10 @@ public class HySkyBlockStats {
}
}
+ private static class JacobData {
+ private Map<String, Integer> perks;
+ }
+
public static class Dungeons {
private Map<String, Type> dungeon_types;
private Map<DataHelper.DungeonClass, ClassDetails> player_classes;
diff --git a/src/main/java/de/cowtipper/cowlection/data/XpTables.java b/src/main/java/de/cowtipper/cowlection/data/XpTables.java
index 158fb66..efa576a 100644
--- a/src/main/java/de/cowtipper/cowlection/data/XpTables.java
+++ b/src/main/java/de/cowtipper/cowlection/data/XpTables.java
@@ -62,6 +62,16 @@ public class XpTables {
XP_TO_LEVEL.put(47472425, 48);
XP_TO_LEVEL.put(51172425, 49);
XP_TO_LEVEL.put(55172425, 50);
+ XP_TO_LEVEL.put(59472425, 51);
+ XP_TO_LEVEL.put(64072425, 52);
+ XP_TO_LEVEL.put(68972425, 53);
+ XP_TO_LEVEL.put(74172425, 54);
+ XP_TO_LEVEL.put(79672425, 55);
+ XP_TO_LEVEL.put(85472425, 56);
+ XP_TO_LEVEL.put(91572425, 57);
+ XP_TO_LEVEL.put(97972425, 58);
+ XP_TO_LEVEL.put(104672425, 59);
+ XP_TO_LEVEL.put(111672425, 60);
XP_TO_LEVEL_ALTERNATIVE.put(0, 0);
XP_TO_LEVEL_ALTERNATIVE.put(50, 1);
@@ -88,7 +98,7 @@ public class XpTables {
XP_TO_LEVEL_ALTERNATIVE.put(47850, 22);
XP_TO_LEVEL_ALTERNATIVE.put(60100, 23);
XP_TO_LEVEL_ALTERNATIVE.put(75400, 24);
-
+ XP_TO_LEVEL_ALTERNATIVE.put(94450, 25);
}
Skill() {
@@ -101,9 +111,17 @@ public class XpTables {
public int getLevel(double exp) {
if (alternativeXpFormula) {
- return XP_TO_LEVEL_ALTERNATIVE.floorEntry((int) exp).getValue();
+ return getLevel(exp, 25);
} else {
- return XP_TO_LEVEL.floorEntry((int) exp).getValue();
+ return getLevel(exp, 50);
+ }
+ }
+
+ public int getLevel(double exp, int maxLevel) {
+ if (alternativeXpFormula) {
+ return Math.min(XP_TO_LEVEL_ALTERNATIVE.floorEntry((int) exp).getValue(), maxLevel);
+ } else {
+ return Math.min(XP_TO_LEVEL.floorEntry((int) exp).getValue(), maxLevel);
}
}
diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java
index 5f25fa7..63927c6 100644
--- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java
+++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java
@@ -158,7 +158,7 @@ public class DungeonsListener {
hasCustomGearScore = true;
}
if (!hasCustomGearScore) {
- customGearScore.append("―");
+ customGearScore.append(EnumChatFormatting.LIGHT_PURPLE).append("100%").append(EnumChatFormatting.DARK_GRAY).append(" (never has randomized stats)");
}
if (showItemQualityAndFloor) {
if (MooConfig.isDungItemQualityAtTop()) {
diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java
index a0162d3..9df27c5 100644
--- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java
+++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsPartyListener.java
@@ -244,13 +244,16 @@ public class DungeonsPartyListener {
continue;
}
DataHelper.DungeonClass selectedClass = dungeons.getSelectedClass();
- int selectedClassLevel = dungeons.getSelectedClassLevel();
- String classAndDungeonTypeInfo = selectedClass.getName() + " " + (MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(selectedClassLevel) : selectedClassLevel)
- + dungeons.getDungeonTypesLevels();
+ String noClassSelected = EnumChatFormatting.ITALIC + "no class selected";
+ String classAndDungeonTypeInfo = noClassSelected;
+ if (selectedClass != null) {
+ int selectedClassLevel = dungeons.getSelectedClassLevel();
+ classAndDungeonTypeInfo = selectedClass.getName() + " " + (MooConfig.useRomanNumerals() ? Utils.convertArabicToRoman(selectedClassLevel) : selectedClassLevel);
+ }
+ classAndDungeonTypeInfo += dungeons.getDungeonTypesLevels();
playerEntry.append(classAndDungeonTypeInfo);
// insert class + dungeon type data into str:
- String noClassSelected = EnumChatFormatting.ITALIC + "no class selected";
int start = playerTooltip.indexOf(noClassSelected);
playerTooltip.replace(start, start + noClassSelected.length(), classAndDungeonTypeInfo);
diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java
index 632ffa1..12f5e48 100644
--- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java
+++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/SkyBlockListener.java
@@ -309,12 +309,13 @@ public class SkyBlockListener {
if ((tooltipAuctionHousePriceEachDisplay == MooConfig.Setting.ALWAYS || tooltipAuctionHousePriceEachDisplay == MooConfig.Setting.SPECIAL && MooConfig.isTooltipToggleKeyBindingPressed())
&& (e.entityPlayer.openContainer instanceof ContainerChest || Minecraft.getMinecraft().currentScreen instanceof MooConfigGui)) {
int stackSize = e.itemStack.stackSize;
- if ((stackSize == 1 && !isSubmitBidItem(e.itemStack)) || e.toolTip.size() < 4) {
+ boolean isSubmitBidItem = isSubmitBidItem(e.itemStack);
+ if ((stackSize == 1 && !isSubmitBidItem) || e.toolTip.size() < 4) {
// only 1 item or irrelevant tooltip - nothing to do here, abort!
return;
}
- if (isSubmitBidItem(e.itemStack)) {
+ if (isSubmitBidItem) {
// special case: "place bid on an item" interface ("Auction View")
ItemStack auctionedItem = e.entityPlayer.openContainer.getInventory().get(13);
if (auctionedItem == null || auctionedItem.stackSize == 1) {
diff --git a/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java b/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java
index f10e024..ae17d32 100644
--- a/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java
+++ b/src/main/java/de/cowtipper/cowlection/search/GuiSearch.java
@@ -26,7 +26,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
import java.awt.*;
import java.io.File;
@@ -416,7 +415,7 @@ public class GuiSearch extends GuiScreen {
drawString(fontRendererObj, "Log file: ", 2, 2, 0xff888888);
GlStateManager.pushMatrix();
float scaleFactor = 0.75f;
- GL11.glScalef(scaleFactor, scaleFactor, scaleFactor);
+ GlStateManager.scale(scaleFactor, scaleFactor, 0);
fontRendererObj.drawSplitString(EnumChatFormatting.GRAY + Utils.toRealPath(hoveredEntry.getFilePath()), 5, (int) ((4 + fontRendererObj.FONT_HEIGHT) * (1 / scaleFactor)), (int) ((GuiSearch.this.fieldSearchQuery.xPosition - 8) * (1 / scaleFactor)), 0xff888888);
GlStateManager.popMatrix();
drawString(fontRendererObj, "Result: " + EnumChatFormatting.WHITE + (hoveredSearchResultId + 1) + EnumChatFormatting.RESET + "/" + EnumChatFormatting.WHITE + this.rawResults.size(), 8, 48, 0xff888888);
diff --git a/src/main/java/de/cowtipper/cowlection/util/Utils.java b/src/main/java/de/cowtipper/cowlection/util/Utils.java
index 20794b1..d5c846d 100644
--- a/src/main/java/de/cowtipper/cowlection/util/Utils.java
+++ b/src/main/java/de/cowtipper/cowlection/util/Utils.java
@@ -12,9 +12,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.text.DecimalFormat;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -22,7 +20,14 @@ import java.util.stream.Collectors;
public final class Utils {
public static final Pattern VALID_UUID_PATTERN = Pattern.compile("^(\\w{8})-(\\w{4})-(\\w{4})-(\\w{4})-(\\w{12})$");
private static final Pattern VALID_USERNAME = Pattern.compile("^[\\w]{1,16}$");
- private static final char[] LARGE_NUMBERS = new char[]{'k', 'm', 'b', 't'};
+ private static final NavigableMap<Double, Character> NUMBER_SUFFIXES = new TreeMap<>();
+
+ static {
+ NUMBER_SUFFIXES.put(1_000d, 'k');
+ NUMBER_SUFFIXES.put(1_000_000d, 'm');
+ NUMBER_SUFFIXES.put(1_000_000_000d, 'b');
+ NUMBER_SUFFIXES.put(1_000_000_000_000d, 't');
+ }
private Utils() {
}
@@ -105,27 +110,19 @@ public final class Utils {
}
/**
- * Formats a large number with abbreviations for each factor of a thousand (k, m, ...)
- *
- * @param number the number to format
- * @return a String representing the number n formatted in a cool looking way.
- * @see <a href="https://stackoverflow.com/a/4753866">Source</a>
+ * Formats a large number with abbreviations for each factor of a thousand (k, m, b, t)
*/
public static String formatNumberWithAbbreviations(double number) {
- return formatNumberWithAbbreviations(number, 0);
- }
+ if (number == Double.MIN_VALUE) return formatNumberWithAbbreviations(Double.MIN_VALUE + 1);
+ if (number < 0) return "-" + formatNumberWithAbbreviations(-number);
+ if (number < 1000) return "" + (long) number;
+
+ Map.Entry<Double, Character> e = NUMBER_SUFFIXES.floorEntry(number);
+ Double divideBy = e.getKey();
+ Character suffix = e.getValue();
- private static String formatNumberWithAbbreviations(double number, int iteration) {
- @SuppressWarnings("IntegerDivisionInFloatingPointContext") double d = ((long) number / 100) / 10.0;
- boolean isRound = (d * 10) % 10 == 0; // true if the decimal part is equal to 0 (then it's trimmed anyway)
- // this determines the class, i.e. 'k', 'm' etc
- // this decides whether to trim the decimals
- // (int) d * 10 / 10 drops the decimal
- return d < 1000 ? // this determines the class, i.e. 'k', 'm' etc
- (d > 99.9 || isRound || d > 9.99 ? // this decides whether to trim the decimals
- (int) d * 10 / 10 : d + "" // (int) d * 10 / 10 drops the decimal
- ) + "" + LARGE_NUMBERS[iteration]
- : formatNumberWithAbbreviations(d, iteration + 1);
+ DecimalFormat df = new DecimalFormat("#,##0.#");
+ return df.format(number / divideBy) + suffix;
}
/**
diff --git a/src/main/resources/assets/cowlection/lang/en_US.lang b/src/main/resources/assets/cowlection/lang/en_US.lang
index 93fef62..ede0dda 100644
--- a/src/main/resources/assets/cowlection/lang/en_US.lang
+++ b/src/main/resources/assets/cowlection/lang/en_US.lang
@@ -63,9 +63,9 @@ cowlection.config.lookupPriceKeyBinding.tooltip=Hover over an item in any invent
cowlection.config.lookupItemDirectly=Open website directly?
cowlection.config.lookupItemDirectly.tooltip=Should the corresponding website be opened immediately (§a✔§r) or sent as a chat message (§c✘§r)?
cowlection.config.showItemQualityAndFloor=Show item quality + obtained floor
-cowlection.config.showItemQualityAndFloor.tooltip=Should the item quality (in %%) and the obtained floor be added to the dungeon items' tooltips?\n§e'top' replaces the default 'gear score' entry §rwhich normally includes reforges and essence upgrades.
+cowlection.config.showItemQualityAndFloor.tooltip=Should the item quality (in %%) and the obtained floor be added to the dungeon items' tooltips?
cowlection.config.dungItemQualityPos=Item quality + obtained floor position
-cowlection.config.dungItemQualityPos.tooltip=Position of item quality and otained floor in dungeon item tooltips
+cowlection.config.dungItemQualityPos.tooltip=Position of item quality and obtained floor in dungeon item tooltips\n§e'top' replaces the default 'gear score' entry §rwhich normally includes reforges and essence upgrades.
cowlection.config.dungItemToolTipToggleKeyBinding=Key binding: Show dungeon item base stats
cowlection.config.dungItemToolTipToggleKeyBinding.tooltip=Hold down this key to toggle dungeon item tooltip.\nDisplays the base stats of an item without reforges and without essence upgrades.\n\n§7§odisable key binding: §e§oset key binding to §lESC
cowlection.config.dungSendPerformanceOnDeath=Send player deaths overview after each death?