Implemented hoverComponents with dynamic color, proper formatting and proper unit for damage and distance-based statistics!

This commit is contained in:
Artemis-the-gr8 2022-07-03 02:29:05 +02:00
parent f723a657e7
commit cde80fa9d2
5 changed files with 115 additions and 85 deletions

View File

@ -92,19 +92,33 @@ public class ConfigHandler {
return config.getInt("number-of-days-since-last-joined", 0); return config.getInt("number-of-days-since-last-joined", 0);
} }
public Unit getDistanceUnit() { public Unit getStatUnit(Unit.Type unitType, boolean isHoverText) {
switch (unitType) {
case DISTANCE -> {
return isHoverText ? getDistanceUnitHoverText() : getDistanceUnit();
}
case DAMAGE -> {
return isHoverText ? getDamageUnitHoverText() : getDamageUnit();
}
default -> {
return Unit.NUMBER;
}
}
}
private Unit getDistanceUnit() {
return getUnitFromString(config.getString("distance-unit", "blocks"), Unit.BLOCK); return getUnitFromString(config.getString("distance-unit", "blocks"), Unit.BLOCK);
} }
public Unit getDistanceUnitHoverText() { private Unit getDistanceUnitHoverText() {
return getUnitFromString(config.getString("distance-unit-hover-text", "km"), Unit.KM); return getUnitFromString(config.getString("distance-unit-hover-text", "km"), Unit.KM);
} }
public Unit getDamageUnit() { private Unit getDamageUnit() {
return getUnitFromString(config.getString("damage-unit", "hearts"), Unit.HEART); return getUnitFromString(config.getString("damage-unit", "hearts"), Unit.HEART);
} }
public Unit getDamageUnitHoverText() { private Unit getDamageUnitHoverText() {
return getUnitFromString(config.getString("damage-unit-hover-text", "hp"), Unit.HP); return getUnitFromString(config.getString("damage-unit-hover-text", "hp"), Unit.HP);
} }

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.enums; package com.gmail.artemis.the.gr8.playerstats.enums;
import org.bukkit.Statistic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public enum Unit { public enum Unit {
@ -17,10 +18,26 @@ public enum Unit {
DAY (Type.TIME), DAY (Type.TIME),
WEEK (Type.TIME); WEEK (Type.TIME);
private final Type type;
Unit(Type type) { Unit() {
this(Type.UNTYPED);
} }
Unit(Type type) {
this.type = type;
}
public Type type() {
return type;
}
public static @NotNull Type getType(Statistic statistic) {
return getType(statistic.toString());
}
/** Returns the Unit.Type of this Statistic, which can be Untyped, Distance, Damage, or Time.
@param statName the name of the Statistic enum constant in String*/
public static @NotNull Type getType(String statName) { public static @NotNull Type getType(String statName) {
String name = statName.toLowerCase(); String name = statName.toLowerCase();
if (name.contains("one_cm")) { if (name.contains("one_cm")) {
@ -34,7 +51,9 @@ public enum Unit {
} }
} }
public @NotNull String getName() { /** Returns a pretty name belonging to this enum constant. If the Unit is
NUMBER, it will return an empty String. */
public @NotNull String getName() throws NullPointerException {
switch (this) { switch (this) {
case CM -> { case CM -> {
return "cm"; return "cm";
@ -72,18 +91,21 @@ public enum Unit {
case WEEK -> { case WEEK -> {
return "weeks"; return "weeks";
} }
case NUMBER -> {
return "";
}
default -> default ->
throw new NullPointerException("Trying to get the name of an enum constant that does not exist!"); throw new NullPointerException("Trying to get the name of an enum constant that does not exist!");
} }
} }
public static enum Type{ public enum Type{
DAMAGE, //7 statistics DAMAGE, //7 statistics
DISTANCE, //15 statistics DISTANCE, //15 statistics
TIME, //5 statistics TIME, //5 statistics
UNTYPED; UNTYPED;
private Type() { Type() {
} }
} }
} }

View File

@ -203,20 +203,25 @@ public class ComponentFactory {
//TODO Make this dark gray (or at least darker than statNumber, and at least for time statistics) //TODO Make this dark gray (or at least darker than statNumber, and at least for time statistics)
public TextComponent statUnitComponent(Unit statUnit, Target selection, boolean isTranslatable) { public TextComponent statUnitComponent(Unit statUnit, Target selection, boolean isTranslatable) {
TextComponent.Builder statUnitBuilder = getComponentBuilder(null, if (statUnit.type() != Unit.Type.UNTYPED) {
getColorFromString(config.getSubStatNameFormatting(selection, false)), TextComponent.Builder statUnitBuilder = getComponentBuilder(null,
getStyleFromString(config.getSubStatNameFormatting(selection, true))) getColorFromString(config.getSubStatNameFormatting(selection, false)),
.append(text("[")); getStyleFromString(config.getSubStatNameFormatting(selection, true)))
if (isTranslatable) { .append(text("["));
String unitKey = languageKeyHandler.getUnitKey(statUnit); if (isTranslatable) {
if (unitKey == null) { String unitKey = languageKeyHandler.getUnitKey(statUnit);
unitKey = statUnit.getName(); if (unitKey == null) {
unitKey = statUnit.getName();
}
statUnitBuilder.append(translatable().key(unitKey));
} else {
statUnitBuilder.append(text(statUnit.getName()));
} }
statUnitBuilder.append(translatable().key(unitKey)); return statUnitBuilder.append(text("]")).build();
} else { }
statUnitBuilder.append(text(statUnit.getName())); else {
return Component.empty();
} }
return statUnitBuilder.append(text("]")).build();
} }
public TextComponent titleComponent(String content, Target selection) { public TextComponent titleComponent(String content, Target selection) {

View File

@ -29,7 +29,7 @@ public class MessageWriter {
public MessageWriter(ConfigHandler c) { public MessageWriter(ConfigHandler c) {
config = c; config = c;
formatter = new NumberFormatter(config); formatter = new NumberFormatter();
getComponentFactory(); getComponentFactory();
} }
@ -108,11 +108,14 @@ public class MessageWriter {
.append(componentFactory.playerNameBuilder(request.getPlayerName(), Target.PLAYER) .append(componentFactory.playerNameBuilder(request.getPlayerName(), Target.PLAYER)
.append(text(":")) .append(text(":"))
.append(space())) .append(space()))
.append(componentFactory.statNumberComponent(stat, request.getStatistic().toString(), Target.PLAYER)) .append(getStatNumberComponent(request.getStatistic(), stat, Target.PLAYER))
.append(space()) .append(space())
.append(getStatNameComponent(request)) .append(getStatNameComponent(request))
.append(space()) .append(space())
.append(componentFactory.statUnitComponent(request.getStatistic().toString(), Target.PLAYER)) .append(componentFactory.statUnitComponent(
config.getStatUnit(Unit.getType(request.getStatistic()), false),
Target.PLAYER,
config.useTranslatableComponents()))
.build(); .build();
} }
@ -124,11 +127,13 @@ public class MessageWriter {
.append(componentFactory.titleNumberComponent(topStats.size())).append(space()) .append(componentFactory.titleNumberComponent(topStats.size())).append(space())
.append(getStatNameComponent(request)) .append(getStatNameComponent(request))
.append(space()) .append(space())
.append(componentFactory.statUnitComponent(request.getStatistic().toString(), Target.TOP)); .append(componentFactory.statUnitComponent(
config.getStatUnit(Unit.getType(request.getStatistic()), false),
Target.TOP,
config.useTranslatableComponents()));
boolean useDots = config.useDots(); boolean useDots = config.useDots();
boolean boldNames = config.playerNameIsBold(); boolean boldNames = config.playerNameIsBold();
boolean useHover = config.useHoverText();
Set<String> playerNames = topStats.keySet(); Set<String> playerNames = topStats.keySet();
MinecraftFont font = new MinecraftFont(); MinecraftFont font = new MinecraftFont();
@ -155,20 +160,15 @@ public class MessageWriter {
} }
if (dots >= 1) { if (dots >= 1) {
topList.append(dotsBuilder topList.append(dotsBuilder
.append(text((".".repeat(dots)))) .append(text((".".repeat(dots)))));
.build());
} }
} else { } else {
topList.append(playerNameBuilder topList.append(playerNameBuilder
.append(text(":")) .append(text(":")));
.build());
}
topList.append(space());
if (useHover) {
topList.append(
//componentFactory.statNumberHoverComponent(
// formatter.formatMainNumber(request.getStatistic().toString(), topStats.get(playerName)), Target.TOP));
} }
topList.append(space())
.append(getStatNumberComponent(request.getStatistic(), topStats.get(playerName), Target.TOP));
} }
return topList.build(); return topList.build();
} }
@ -179,17 +179,20 @@ public class MessageWriter {
.append(space()) .append(space())
.append(componentFactory.serverNameComponent(config.getServerName())) .append(componentFactory.serverNameComponent(config.getServerName()))
.append(space()) .append(space())
.append(componentFactory.statNumberComponent(stat, request.getStatistic().toString(), Target.SERVER)) .append(getStatNumberComponent(request.getStatistic(), stat, Target.SERVER))
.append(space()) .append(space())
.append(getStatNameComponent(request)) .append(getStatNameComponent(request))
.append(space()) .append(space())
.append(componentFactory.statUnitComponent(request.getStatistic().toString(), Target.SERVER)) .append(componentFactory.statUnitComponent(
config.getStatUnit(Unit.getType(request.getStatistic()), false),
Target.SERVER,
config.useTranslatableComponents()))
.build(); .build();
} }
/** Depending on the config settings, return either a TranslatableComponent representing /** Depending on the config settings, return either a TranslatableComponent representing
the statName (and potential subStatName), or a TextComponent with capitalized English names.*/ the statName (and potential subStatName), or a TextComponent with capitalized English names.*/
private Component getStatNameComponent(StatRequest request) { private TextComponent getStatNameComponent(StatRequest request) {
if (config.useTranslatableComponents()) { if (config.useTranslatableComponents()) {
return componentFactory.statNameTransComponent(request); return componentFactory.statNameTransComponent(request);
} else { } else {
@ -200,12 +203,18 @@ public class MessageWriter {
} }
} }
private Component getStatNumberComponent(String statName, long statNumber) { private TextComponent getStatNumberComponent(Statistic statistic, long statNumber, Target selection) {
Unit.getType(statName); Unit.Type type = Unit.getType(statistic);
if (config.useHoverText()) { Unit baseUnit = config.getStatUnit(type, false);
return componentFactory.statNumberHoverComponent(formatter.formatMainNumber(statName, statNumber), String prettyNumber = formatter.format(statNumber, baseUnit);
formatter.formatHoverNumber(statName, statNumber), if (config.useHoverText() && type != Unit.Type.UNTYPED) {
//something like config.getUnit that calls a bunch of smaller specific getUnit methods) Unit hoverUnit = config.getStatUnit(type, true);
return componentFactory.statNumberHoverComponent(
prettyNumber,
formatter.format(statNumber, hoverUnit),
hoverUnit, selection, config.useTranslatableComponents());
} else {
return componentFactory.statNumberComponent(prettyNumber, selection).build();
} }
} }

View File

@ -1,62 +1,43 @@
package com.gmail.artemis.the.gr8.playerstats.msg; package com.gmail.artemis.the.gr8.playerstats.msg;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.Unit; import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
import java.text.DecimalFormat; import java.text.DecimalFormat;
public class NumberFormatter { public class NumberFormatter {
private static ConfigHandler config;
private final DecimalFormat format; private final DecimalFormat format;
public NumberFormatter(ConfigHandler c) { public NumberFormatter() {
config = c;
format = new DecimalFormat(); format = new DecimalFormat();
format.setGroupingUsed(true); format.setGroupingUsed(true);
format.setGroupingSize(3); format.setGroupingSize(3);
} }
/** Turns the input number into a more readable format depending on its type /** Turns the input number into a more readable format depending on its type
(number-or-times, time-, damage- or distance-based) according to the (number-of-times, time-, damage- or distance-based) according to the
corresponding config settings, and adds commas in groups of 3.*/ corresponding config settings, and adds commas in groups of 3.*/
public String formatMainNumber(String statName, long number) { public String format(long number, Unit statUnit) {
return format(statName, number, false); switch (statUnit.type()) {
} case DISTANCE -> {
return formatDistance(number, statUnit);
/** Turns the input number into a more readable format depending on its type }
(number-or-times, time-, damage- or distance-based) according to the case DAMAGE -> {
corresponding config settings, and adds commas in groups of 3.*/ return formatDamage(number, statUnit);
public String formatHoverNumber(String statName, long number) { }
return format(statName, number, true); case TIME -> {
} return formatTime(number, statUnit);
}
/** Formats the input based on the desired config settings from *-unit or *-unit-hover-text. default -> {
@param statName the Statistic enum name in String format return format.format(number);
@param number the statistic number }
@param isHoverText boolean that indicates whether this number will be displayed in a HoverComponent or not*/
private String format(String statName, long number, boolean isHoverText) {
if (EnumHandler.isDistanceStatistic(statName)) {
return formatDistance(number, isHoverText);
}
else if (EnumHandler.isDamageStatistic(statName)) {
return formatDamage(number, isHoverText);
}
else if (EnumHandler.isTimeStatistic(statName)) {
return formatTime(number, isHoverText);
}
else {
return format.format(number);
} }
} }
/** The unit of damage-based statistics is half a heart by default. /** The unit of damage-based statistics is half a heart by default.
This method turns the number into hearts. */ This method turns the number into hearts. */
private String formatDamage(long number, boolean isHoverText) { //7 statistics private String formatDamage(long number, Unit statUnit) { //7 statistics
Unit unit = isHoverText ? config.getDamageUnitHoverText() : config.getDamageUnit(); if (statUnit == Unit.HEART) {
if (unit == Unit.HEART) {
return format.format(Math.round(number / 2.0)); return format.format(Math.round(number / 2.0));
} else { } else {
return format.format(number); return format.format(number);
@ -65,9 +46,8 @@ public class NumberFormatter {
/** The unit of distance-based statistics is cm by default. This method turns it into blocks by default, /** The unit of distance-based statistics is cm by default. This method turns it into blocks by default,
and turns it into km or leaves it as cm otherwise, depending on the config settings. */ and turns it into km or leaves it as cm otherwise, depending on the config settings. */
private String formatDistance(long number, boolean isHoverText) { //15 statistics private String formatDistance(long number, Unit statUnit) { //15 statistics
Unit unit = isHoverText ? config.getDistanceUnitHoverText() : config.getDistanceUnit(); switch (statUnit) {
switch (unit) {
case CM -> { case CM -> {
return format.format(number); return format.format(number);
} }
@ -84,7 +64,7 @@ public class NumberFormatter {
} }
/** The unit of time-based statistics is ticks by default.*/ /** The unit of time-based statistics is ticks by default.*/
private String formatTime(long number, boolean isHoverText) { //5 statistics private String formatTime(long number, Unit statUnit) { //5 statistics
if (number == 0) { if (number == 0) {
return "-"; return "-";
} }