Skip to content

Commit 0120700

Browse files
authored
Add FormatNumbers Extension (TurboWarp#2036)
This is a simple extension that lets you format large numbers into AD Standard, Fixed Decimal, Comma Separated, or Scientific Notation. It adds but one block, yet a very useful one imo, especially for incremental games! ![msedge_2ZeCztrapG](https://github.com/user-attachments/assets/fabb6c21-2b0a-4770-a7a4-e8bb2a0206ea) ![msedge_b8scWM1ITL](https://github.com/user-attachments/assets/166c6bda-5292-46d4-9904-f96d58b64d67) ![msedge_easzgrLqwB](https://github.com/user-attachments/assets/65f06a27-0fa2-4d50-8a8a-047a0fe4c556) ![msedge_bvo6IzMFhC](https://github.com/user-attachments/assets/230d486b-b682-4aed-9b4a-9231efc72a15) ![msedge_d6Rc1Kz7ia](https://github.com/user-attachments/assets/e2f33009-27ad-46a5-abc0-f2e80c260a8c) ![msedge_i5PasinNgF](https://github.com/user-attachments/assets/ae149005-f8bf-4aab-885e-cdde1fec8ef4) ![msedge_SZVAPgfXeq](https://github.com/user-attachments/assets/3df20b51-cd4f-4419-badc-5f8f09680456) This is the banner, drawn by Dillon (dillonr on Discord)! ![FormatNumbers](https://github.com/user-attachments/assets/fa0f963d-f5e6-46d5-bce8-8685e02cd6c2)
1 parent 26aff55 commit 0120700

4 files changed

Lines changed: 237 additions & 0 deletions

File tree

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// Name: Format Numbers
2+
// ID: dogeiscutformatnumbers
3+
// Description: Format large numbers into AD standard, fixed decimal, comma separated, or scientific notation.
4+
// By: DogeisCut <https://scratch.mit.edu/users/dogeiscut/>
5+
// License: MIT
6+
7+
// Version V.2.0.2
8+
9+
// TODO:
10+
// - Editor Icon
11+
// - BigInt Support
12+
// - Time notation, decimal count defines how many milliseconds show.
13+
14+
(function (Scratch) {
15+
"use strict";
16+
17+
const Cast = Scratch.Cast;
18+
19+
const Formats = {
20+
AD_STANDARD: "AD standard",
21+
FIXED_DECIMAL: "fixed decimal",
22+
COMMA_SEPERATED: "comma separated",
23+
SCIENTIFIC_NOTATION: "scientific notation",
24+
};
25+
26+
class FormatNumbers {
27+
constructor() {
28+
this.notation = "AD standard";
29+
this.decimalPlaces = 2;
30+
}
31+
32+
convertToADStandard(number, decimalPlaces = 2) {
33+
if (typeof number !== "number" || isNaN(number)) {
34+
return "Invalid Input";
35+
}
36+
37+
if (!isFinite(number)) {
38+
return number.toString();
39+
}
40+
41+
if (number === 0) {
42+
return "0";
43+
}
44+
45+
const kMBd = [
46+
"",
47+
"K",
48+
"M",
49+
"B",
50+
"T",
51+
"Qa",
52+
"Qt",
53+
"Sx",
54+
"Sp",
55+
"Oc",
56+
"No",
57+
"Dc",
58+
];
59+
const unitPrefixes = ["U", "D", "T", "Qa", "Qt", "Sx", "Sp", "O", "N"];
60+
const tensPrefixes = [
61+
"Dc",
62+
"Vg",
63+
"Tg",
64+
"Qd",
65+
"Qi",
66+
"Se",
67+
"St",
68+
"Og",
69+
"Nn",
70+
];
71+
const hundredsPrefixes = [
72+
"Ce",
73+
"Dn",
74+
"Tc",
75+
"Qe",
76+
"Qu",
77+
"Sc",
78+
"Si",
79+
"Oe",
80+
"Ne",
81+
];
82+
const tier2Illions = ["MI", "MC", "NA", "PC", "FM", "AT", "ZP"];
83+
const tier2Cutoff = 3003 * tier2Illions.length;
84+
if (Math.log10(Math.abs(number)) > tier2Cutoff) {
85+
return `Il(${number})`;
86+
}
87+
88+
if (Math.abs(number) < 1000) {
89+
return number.toFixed(decimalPlaces).replace(/\.?0+$/, "");
90+
}
91+
92+
const tier = Math.max(0, Math.floor(Math.log10(Math.abs(number)) / 3));
93+
94+
if (tier <= 11) {
95+
const scaledNumber = number / Math.pow(10, tier * 3);
96+
return (
97+
scaledNumber.toFixed(decimalPlaces).replace(/\.?0+$/, "") + kMBd[tier]
98+
);
99+
}
100+
101+
const illionNumber = Math.floor(Math.log10(Math.abs(number)) / 3);
102+
let illionString = "";
103+
104+
if (illionNumber <= 999) {
105+
const hundreds = Math.floor(illionNumber / 100);
106+
const tens = Math.floor((illionNumber % 100) / 10);
107+
const units = illionNumber % 10;
108+
109+
illionString =
110+
(hundreds > 0 ? hundredsPrefixes[hundreds - 1] : "") +
111+
(tens > 0 ? tensPrefixes[tens - 1] : "") +
112+
(units > 0 ? unitPrefixes[units - 1] : "");
113+
} else {
114+
const tier2Index = Math.floor(illionNumber / 1000);
115+
const tier2Remainder = illionNumber % 1000;
116+
117+
if (tier2Index <= tier2Illions.length) {
118+
illionString = tier2Illions[tier2Index - 1];
119+
} else {
120+
return `Il(${number})`;
121+
}
122+
123+
if (tier2Remainder > 0) {
124+
const hundreds = Math.floor(tier2Remainder / 100);
125+
const tens = Math.floor((tier2Remainder % 100) / 10);
126+
const units = tier2Remainder % 10;
127+
128+
const remainderString =
129+
(hundreds > 0 ? hundredsPrefixes[hundreds - 1] : "") +
130+
(tens > 0 ? tensPrefixes[tens - 1] : "") +
131+
(units > 0 ? unitPrefixes[units - 1] : "");
132+
illionString = remainderString + "-" + illionString;
133+
}
134+
}
135+
136+
const scaledNumber =
137+
number / Math.pow(10, Math.floor(Math.log10(Math.abs(number)) / 3) * 3);
138+
return (
139+
scaledNumber.toFixed(decimalPlaces).replace(/\.?0+$/, "") +
140+
" " +
141+
illionString
142+
);
143+
}
144+
145+
convertToCommaSeparated(number, decimalPlaces = 2) {
146+
return number
147+
.toFixed(decimalPlaces)
148+
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
149+
}
150+
151+
convertToScientificNotation(number, decimalPlaces = 2) {
152+
return number.toExponential(decimalPlaces);
153+
}
154+
155+
formatNumber(args) {
156+
const decimals = Math.max(0, Math.min(100, Cast.toNumber(args.DECIMALS)));
157+
switch (args.NOTATION) {
158+
case Formats.AD_STANDARD:
159+
return this.convertToADStandard(Cast.toNumber(args.NUM), decimals);
160+
case Formats.COMMA_SEPERATED:
161+
return this.convertToCommaSeparated(
162+
Cast.toNumber(args.NUM),
163+
decimals
164+
);
165+
case Formats.SCIENTIFIC_NOTATION:
166+
return this.convertToScientificNotation(
167+
Cast.toNumber(args.NUM),
168+
decimals
169+
);
170+
default:
171+
return Cast.toNumber(args.NUM).toFixed(decimals);
172+
}
173+
}
174+
175+
getInfo() {
176+
return {
177+
id: "dogeiscutformatnumbers",
178+
name: Scratch.translate("Format Numbers"),
179+
color1: "#419873",
180+
color2: "#4CA981",
181+
blocks: [
182+
{
183+
opcode: "formatNumber",
184+
text: Scratch.translate(
185+
"format number [NUM] to notation [NOTATION] with [DECIMALS] decimal places"
186+
),
187+
blockType: Scratch.BlockType.REPORTER,
188+
arguments: {
189+
NUM: {
190+
type: Scratch.ArgumentType.NUMBER,
191+
defaultValue: 1000,
192+
},
193+
NOTATION: {
194+
type: Scratch.ArgumentType.STRING,
195+
menu: "notationOptions",
196+
defaultValue: "AD standard",
197+
},
198+
DECIMALS: {
199+
type: Scratch.ArgumentType.NUMBER,
200+
defaultValue: 2,
201+
},
202+
},
203+
},
204+
],
205+
menus: {
206+
notationOptions: {
207+
acceptReporters: false,
208+
items: [
209+
{
210+
text: Scratch.translate("AD standard"),
211+
value: Formats.AD_STANDARD,
212+
},
213+
{
214+
text: Scratch.translate("fixed decimal"),
215+
value: Formats.FIXED_DECIMAL,
216+
},
217+
{
218+
text: Scratch.translate("comma separated"),
219+
value: Formats.COMMA_SEPERATED,
220+
},
221+
{
222+
text: Scratch.translate("scientific notation"),
223+
value: Formats.SCIENTIFIC_NOTATION,
224+
},
225+
],
226+
},
227+
},
228+
};
229+
}
230+
}
231+
232+
Scratch.extensions.register(new FormatNumbers());
233+
})(Scratch);

‎extensions/extensions.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"true-fantom/math",
5757
"true-fantom/regexp",
5858
"true-fantom/couplers",
59+
"DogeisCut/FormatNumbers",
5960
"Lily/AllMenus",
6061
"Lily/HackedBlocks",
6162
"Lily/Cast",

‎images/DogeisCut/FormatNumbers.png‎

75.7 KB
Loading

‎images/README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,6 @@ All images in this folder are licensed under the [GNU General Public License ver
321321

322322
## CubesterYT/KeySimulation.svg
323323
- Created by [@SharkPool-SP](https://github.com/SharkPool-SP/)
324+
325+
## DogeisCut/FormatNumbers.png
326+
- Created by [@Dillon](https://github.com/DillonRGaming)

0 commit comments

Comments
 (0)