11package dev .booky .cloudcore .i18n ;
22// Created by booky10 in CloudCore (17:27 11.05.2024.)
33
4+ import net .kyori .adventure .text .Component ;
45import net .kyori .adventure .text .TranslationArgument ;
56import net .kyori .adventure .text .minimessage .Context ;
67import net .kyori .adventure .text .minimessage .ParsingException ;
1112import net .kyori .adventure .util .TriState ;
1213import org .jetbrains .annotations .Nullable ;
1314
15+ import java .text .DecimalFormat ;
16+ import java .text .DecimalFormatSymbols ;
17+ import java .text .NumberFormat ;
1418import java .util .List ;
19+ import java .util .Locale ;
1520
1621import static net .kyori .adventure .text .serializer .plain .PlainTextComponentSerializer .plainText ;
1722
@@ -49,7 +54,7 @@ public AdvancedTagFormatter(List<TranslationArgument> args) {
4954 }
5055 String dynamicFormattingName = args .pop ().value ();
5156 DynamicFormatting dynamicFormatting = DynamicFormatting .INDEX .valueOr (
52- dynamicFormattingName , DynamicFormatting .NONE );
57+ dynamicFormattingName , DynamicFormatting .NONE );
5358 return dynamicFormatting .format (args , ctx , arg );
5459 }
5560
@@ -95,11 +100,38 @@ public Tag format(ArgumentQueue args, Context ctx, TranslationArgument arg) {
95100 String value ;
96101 do {
97102 value = args .popOr (
98- () -> "No argument found for " + state ).value ();
103+ () -> "No argument found for " + state ).value ();
99104 } while (argOffset -- > 0 );
100105 return Tag .inserting (ctx .deserialize (value ));
101106 }
102107 },
108+ NUMBER ("num" ) {
109+ private static NumberFormat getDecimalFormat (ArgumentQueue args ) {
110+ // copied from Formatter#number
111+ if (!args .hasNext ()) {
112+ return DecimalFormat .getInstance ();
113+ }
114+
115+ String localeStr = args .pop ().value ();
116+ if (args .hasNext ()) {
117+ String format = args .pop ().value ();
118+ Locale locale = Locale .forLanguageTag (localeStr );
119+ DecimalFormatSymbols symbols = new DecimalFormatSymbols (locale );
120+ return new DecimalFormat (format , symbols );
121+ }
122+
123+ return localeStr .indexOf ('.' ) < 0
124+ ? DecimalFormat .getInstance (Locale .forLanguageTag (localeStr ))
125+ : new DecimalFormat (localeStr , DecimalFormatSymbols .getInstance ());
126+ }
127+
128+ @ Override
129+ public Tag format (ArgumentQueue args , Context ctx , TranslationArgument arg ) {
130+ String formatted = getDecimalFormat (args ).format (asNumber (arg ));
131+ Component component = ctx .deserialize (formatted );
132+ return Tag .inserting (component );
133+ }
134+ },
103135 NONE ("none" ) {
104136 @ Override
105137 public Tag format (ArgumentQueue args , Context ctx , TranslationArgument arg ) {
@@ -108,14 +140,24 @@ public Tag format(ArgumentQueue args, Context ctx, TranslationArgument arg) {
108140 };
109141
110142 private static final Index <String , DynamicFormatting > INDEX =
111- Index .create (DynamicFormatting ::getId , values ());
143+ Index .create (DynamicFormatting ::getId , values ());
112144
113145 private final String id ;
114146
115147 DynamicFormatting (String id ) {
116148 this .id = id ;
117149 }
118150
151+ protected static Number asNumber (TranslationArgument arg ) {
152+ if (arg .value () instanceof Number ) {
153+ return (Number ) arg .value ();
154+ }
155+ String string = arg .value () instanceof Component
156+ ? plainText ().serialize ((Component ) arg .value ())
157+ : String .valueOf (arg .value ());
158+ return Double .parseDouble (string );
159+ }
160+
119161 public abstract Tag format (ArgumentQueue args , Context ctx , TranslationArgument arg );
120162
121163 public String getId () {
0 commit comments