@mauricode/token-derby 2.5.2 → 2.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +104 -86
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -420,8 +420,8 @@ var HEARTBEAT_RETRY_DELAYS_MS = [1e3, 2e3, 4e3, 8e3, 15e3];
|
|
|
420
420
|
// src/version.ts
|
|
421
421
|
import { createRequire } from "module";
|
|
422
422
|
function readVersion() {
|
|
423
|
-
if ("2.5.
|
|
424
|
-
return "2.5.
|
|
423
|
+
if ("2.5.4".length > 0) {
|
|
424
|
+
return "2.5.4";
|
|
425
425
|
}
|
|
426
426
|
try {
|
|
427
427
|
const req = createRequire(import.meta.url);
|
|
@@ -592,7 +592,7 @@ var HATS = [
|
|
|
592
592
|
{ id: "spartan_helmet", name: "Spartan Helmet", rarity: "epic", width: 11, anchor_x: 23, rows: ["...........", "........Q..", ".......QQ..", ".....QQQQ..", "....QQQQQ..", "..QQQQQQ...", ".QQQAA.....", "QQAAAAAAA..", "Q.AAAAAAA..", "..AQQQQQA.."], variants: [{ A: "#B0BEC5", Q: "#B71C1C" }, { A: "#B0BEC5", Q: "#b2b51c" }, { A: "#B0BEC5", Q: "#b5611c" }] },
|
|
593
593
|
{ id: "conquistador_full", name: "Conquistador Helm", rarity: "epic", width: 11, anchor_x: 23, rows: ["...........", "...........", "...........", "...........", ".....A.....", "....AAA....", "...AAAAA...", "..AAAAAAA..", "...AQQQA...", "...AQQQA..."], variants: [{ A: "#B0BEC5", Q: "#FFD700" }, { A: "#B0BEC5", Q: "#0040ff" }, { A: "#B0BEC5", Q: "#36123b" }] },
|
|
594
594
|
// ── LEGENDARY (5) ──────────────────────────────────────────────────────
|
|
595
|
-
{ id: "rainbow_crown", name: "Rainbow Crown", rarity: "legendary", width: 11, anchor_x: 23, rows: ["...........", "...........", ".....A.....", "....
|
|
595
|
+
{ id: "rainbow_crown", name: "Rainbow Crown", rarity: "legendary", width: 11, anchor_x: 23, rows: ["...........", "...........", ".....A.....", "....AAA....", "....AQA....", "....AAA....", "...AAQAA...", "...AAAAA...", "..AAAQAAA..", "..AAAAAAA.."], colors: { A: "#FFD700", Q: "#553f3f" }, animation: { type: "cycle", frames: ["#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#0000FF", "#8B00FF"], fps: 8 } },
|
|
596
596
|
{ id: "inferno_cap", name: "Inferno Cap", rarity: "legendary", width: 11, anchor_x: 23, rows: ["...........", "....AAA....", "...AAAAA...", "....AAA....", ".....Q.....", "A....Q....A", "A...QQQ...A", ".A..QQQ..A.", "..AAAAAAA..", "..AAAAAAA.."], colors: { A: "#FF4500", Q: "#FFD700" }, animation: { type: "cycle", frames: ["#FF0000", "#FF2200", "#FF4500", "#FF6600", "#FF8C00", "#FFA500"], fps: 12 } },
|
|
597
597
|
{ id: "void_hood", name: "Void Hood", rarity: "legendary", width: 11, anchor_x: 23, rows: ["...........", "...........", "...........", "...AAA.....", "..AAAAAA...", ".AAAAAAA...", ".AAAAAAAA..", "AAAAAAAAA..", "AAAAQQQAA..", "AAAAQQQAA.."], colors: { A: "#1A0033", Q: "#d9cfe3" }, animation: { type: "cycle", frames: ["#0D0019", "#1A0033", "#2D004D", "#3D0066", "#2D004D", "#1A0033"], fps: 3 } },
|
|
598
598
|
{ id: "prismatic_jester", name: "Prismatic Jester", rarity: "legendary", width: 11, anchor_x: 23, rows: ["...........", "..Q.Q.Q.Q..", "Q..A.A.A..Q", ".Q.A.A.A.Q.", "..AQAQAQA..", "..AQAQAQA..", "..AAAAAAA..", "..AAAAAAA..", "..AAAAAAA..", "..AAAAAAA.."], colors: { A: "#FF0000", Q: "#0000FF" }, animation: { type: "cycle", frames: ["#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#0000FF", "#8B00FF", "#FF00FF", "#00FFFF"], fps: 15 } },
|
|
@@ -939,7 +939,7 @@ async function stableDeleteCommand(name) {
|
|
|
939
939
|
}
|
|
940
940
|
|
|
941
941
|
// src/commands/stable-edit.ts
|
|
942
|
-
import
|
|
942
|
+
import React7 from "react";
|
|
943
943
|
import { render as render3 } from "ink";
|
|
944
944
|
|
|
945
945
|
// src/ui/HatPicker.tsx
|
|
@@ -1046,23 +1046,81 @@ function PreviewArea({ focused, colors }) {
|
|
|
1046
1046
|
return /* @__PURE__ */ jsx5(HorseSprite, { sprite: MAIN_SPRITE, colors, hat: { hat, variant: focused.collected.variant ?? 0 } });
|
|
1047
1047
|
}
|
|
1048
1048
|
|
|
1049
|
+
// src/ui/HorsePicker.tsx
|
|
1050
|
+
import { useState as useState4 } from "react";
|
|
1051
|
+
import { Box as Box6, Text as Text6, useInput as useInput3 } from "ink";
|
|
1052
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1053
|
+
function HorsePicker({ horses, onPick, onCancel }) {
|
|
1054
|
+
const [idx, setIdx] = useState4(0);
|
|
1055
|
+
useInput3((input, key) => {
|
|
1056
|
+
if (key.escape) {
|
|
1057
|
+
onCancel();
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
if (horses.length === 0) return;
|
|
1061
|
+
if (key.upArrow) {
|
|
1062
|
+
setIdx((idx - 1 + horses.length) % horses.length);
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1065
|
+
if (key.downArrow) {
|
|
1066
|
+
setIdx((idx + 1) % horses.length);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
if (key.return) {
|
|
1070
|
+
onPick(horses[idx]);
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
if (horses.length === 0) {
|
|
1075
|
+
return /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", children: [
|
|
1076
|
+
/* @__PURE__ */ jsx6(Text6, { children: "No horses in your stable." }),
|
|
1077
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Run `token-derby stable create` to make one." })
|
|
1078
|
+
] });
|
|
1079
|
+
}
|
|
1080
|
+
return /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", children: [
|
|
1081
|
+
/* @__PURE__ */ jsx6(Text6, { children: "Pick a horse to race:" }),
|
|
1082
|
+
horses.map((h, i) => /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", children: [
|
|
1083
|
+
/* @__PURE__ */ jsx6(Box6, { flexDirection: "row", children: /* @__PURE__ */ jsxs4(Text6, { children: [
|
|
1084
|
+
i === idx ? "\u25BA" : " ",
|
|
1085
|
+
" ",
|
|
1086
|
+
h.name,
|
|
1087
|
+
" ",
|
|
1088
|
+
/* @__PURE__ */ jsxs4(Text6, { color: "cyan", children: [
|
|
1089
|
+
"[Lvl. ",
|
|
1090
|
+
levelFromXp(h.xp),
|
|
1091
|
+
"]"
|
|
1092
|
+
] })
|
|
1093
|
+
] }) }),
|
|
1094
|
+
/* @__PURE__ */ jsxs4(Box6, { flexDirection: "row", children: [
|
|
1095
|
+
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1096
|
+
/* @__PURE__ */ jsx6(HorseSprite, { sprite: MINI_SPRITE, colors: h.colors })
|
|
1097
|
+
] })
|
|
1098
|
+
] }, h.stable_horse_id)),
|
|
1099
|
+
/* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "\u2191/\u2193 choose \xB7 Enter pick \xB7 Esc cancel" }) })
|
|
1100
|
+
] });
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1049
1103
|
// src/commands/stable-edit.ts
|
|
1050
1104
|
async function stableEditCommand(name) {
|
|
1051
|
-
if (!name) {
|
|
1052
|
-
console.error("Usage: token-derby stable edit <name>");
|
|
1053
|
-
return 2;
|
|
1054
|
-
}
|
|
1055
1105
|
const horses = await fetchStable();
|
|
1056
1106
|
if (!horses) return 1;
|
|
1057
|
-
const existing = horses
|
|
1058
|
-
if (
|
|
1107
|
+
const existing = await pickHorseToEdit(horses, name);
|
|
1108
|
+
if (existing === "not_found") {
|
|
1059
1109
|
console.error(`No horse named "${name}" in your stable.`);
|
|
1060
1110
|
return 1;
|
|
1061
1111
|
}
|
|
1112
|
+
if (existing === "empty") {
|
|
1113
|
+
console.log("No horses in your stable. Run `token-derby stable create` to make one.");
|
|
1114
|
+
return 0;
|
|
1115
|
+
}
|
|
1116
|
+
if (existing === "cancelled") {
|
|
1117
|
+
console.log("Cancelled.");
|
|
1118
|
+
return 1;
|
|
1119
|
+
}
|
|
1062
1120
|
let exitCode = 0;
|
|
1063
1121
|
let liveColors = existing.colors;
|
|
1064
1122
|
const app = render3(
|
|
1065
|
-
|
|
1123
|
+
React7.createElement(HorseCreator, {
|
|
1066
1124
|
initialColors: existing.colors,
|
|
1067
1125
|
initialName: existing.name,
|
|
1068
1126
|
lockName: true,
|
|
@@ -1094,7 +1152,7 @@ async function stableEditCommand(name) {
|
|
|
1094
1152
|
if (exitCode === 0 && existing.hats && existing.hats.length > 0) {
|
|
1095
1153
|
const equipResult = await new Promise((resolve) => {
|
|
1096
1154
|
const app2 = render3(
|
|
1097
|
-
|
|
1155
|
+
React7.createElement(HatPicker, {
|
|
1098
1156
|
hats: existing.hats,
|
|
1099
1157
|
equipped: existing.equipped_hat ?? null,
|
|
1100
1158
|
colors: liveColors,
|
|
@@ -1133,6 +1191,29 @@ async function fetchStable() {
|
|
|
1133
1191
|
throw e;
|
|
1134
1192
|
}
|
|
1135
1193
|
}
|
|
1194
|
+
async function pickHorseToEdit(horses, name) {
|
|
1195
|
+
if (name) {
|
|
1196
|
+
const found = horses.find((h) => h.name === name);
|
|
1197
|
+
return found ?? "not_found";
|
|
1198
|
+
}
|
|
1199
|
+
if (horses.length === 0) return "empty";
|
|
1200
|
+
const picked = await new Promise((resolve) => {
|
|
1201
|
+
const app = render3(
|
|
1202
|
+
React7.createElement(HorsePicker, {
|
|
1203
|
+
horses,
|
|
1204
|
+
onPick: (h) => {
|
|
1205
|
+
app.unmount();
|
|
1206
|
+
resolve(h);
|
|
1207
|
+
},
|
|
1208
|
+
onCancel: () => {
|
|
1209
|
+
app.unmount();
|
|
1210
|
+
resolve(null);
|
|
1211
|
+
}
|
|
1212
|
+
})
|
|
1213
|
+
);
|
|
1214
|
+
});
|
|
1215
|
+
return picked ?? "cancelled";
|
|
1216
|
+
}
|
|
1136
1217
|
|
|
1137
1218
|
// src/commands/create.ts
|
|
1138
1219
|
import * as readline2 from "readline/promises";
|
|
@@ -1222,60 +1303,6 @@ function isIso(s) {
|
|
|
1222
1303
|
import React9 from "react";
|
|
1223
1304
|
import { render as render4 } from "ink";
|
|
1224
1305
|
|
|
1225
|
-
// src/ui/HorsePicker.tsx
|
|
1226
|
-
import { useState as useState4 } from "react";
|
|
1227
|
-
import { Box as Box6, Text as Text6, useInput as useInput3 } from "ink";
|
|
1228
|
-
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1229
|
-
function HorsePicker({ horses, onPick, onCancel }) {
|
|
1230
|
-
const [idx, setIdx] = useState4(0);
|
|
1231
|
-
useInput3((input, key) => {
|
|
1232
|
-
if (key.escape) {
|
|
1233
|
-
onCancel();
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
|
-
if (horses.length === 0) return;
|
|
1237
|
-
if (key.upArrow) {
|
|
1238
|
-
setIdx((idx - 1 + horses.length) % horses.length);
|
|
1239
|
-
return;
|
|
1240
|
-
}
|
|
1241
|
-
if (key.downArrow) {
|
|
1242
|
-
setIdx((idx + 1) % horses.length);
|
|
1243
|
-
return;
|
|
1244
|
-
}
|
|
1245
|
-
if (key.return) {
|
|
1246
|
-
onPick(horses[idx]);
|
|
1247
|
-
return;
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1250
|
-
if (horses.length === 0) {
|
|
1251
|
-
return /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", children: [
|
|
1252
|
-
/* @__PURE__ */ jsx6(Text6, { children: "No horses in your stable." }),
|
|
1253
|
-
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Run `token-derby stable create` to make one." })
|
|
1254
|
-
] });
|
|
1255
|
-
}
|
|
1256
|
-
return /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", children: [
|
|
1257
|
-
/* @__PURE__ */ jsx6(Text6, { children: "Pick a horse to race:" }),
|
|
1258
|
-
horses.map((h, i) => /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", children: [
|
|
1259
|
-
/* @__PURE__ */ jsx6(Box6, { flexDirection: "row", children: /* @__PURE__ */ jsxs4(Text6, { children: [
|
|
1260
|
-
i === idx ? "\u25BA" : " ",
|
|
1261
|
-
" ",
|
|
1262
|
-
h.name,
|
|
1263
|
-
" ",
|
|
1264
|
-
/* @__PURE__ */ jsxs4(Text6, { color: "cyan", children: [
|
|
1265
|
-
"[Lvl. ",
|
|
1266
|
-
levelFromXp(h.xp),
|
|
1267
|
-
"]"
|
|
1268
|
-
] })
|
|
1269
|
-
] }) }),
|
|
1270
|
-
/* @__PURE__ */ jsxs4(Box6, { flexDirection: "row", children: [
|
|
1271
|
-
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1272
|
-
/* @__PURE__ */ jsx6(HorseSprite, { sprite: MINI_SPRITE, colors: h.colors })
|
|
1273
|
-
] })
|
|
1274
|
-
] }, h.stable_horse_id)),
|
|
1275
|
-
/* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "\u2191/\u2193 choose \xB7 Enter pick \xB7 Esc cancel" }) })
|
|
1276
|
-
] });
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
1306
|
// src/stable/active-race.ts
|
|
1280
1307
|
import * as fs2 from "fs/promises";
|
|
1281
1308
|
import * as path3 from "path";
|
|
@@ -2152,12 +2179,6 @@ var BOX_EMPTY = [
|
|
|
2152
2179
|
function GiftBox({ frame, color }) {
|
|
2153
2180
|
return /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", children: frame.map((line, i) => /* @__PURE__ */ jsx10(Text10, { children: line ? ansiFg(color) + line + RESET3 : line }, i)) });
|
|
2154
2181
|
}
|
|
2155
|
-
function printClosedBox() {
|
|
2156
|
-
for (const line of BOX_CLOSED) {
|
|
2157
|
-
const colored = line.trim().length > 0 ? `${ansiFg(BOX_COLOR)}${line}${RESET3}` : line;
|
|
2158
|
-
process.stdout.write(colored + "\n");
|
|
2159
|
-
}
|
|
2160
|
-
}
|
|
2161
2182
|
function spawnParticles(tier, count, cx, cy) {
|
|
2162
2183
|
const palette = TIER_PALETTE[tier];
|
|
2163
2184
|
const out = [];
|
|
@@ -2194,23 +2215,26 @@ function ConfettiBurst({ tier }) {
|
|
|
2194
2215
|
}
|
|
2195
2216
|
return /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", children: grid.map((row, y) => /* @__PURE__ */ jsx10(Text10, { children: row.join("") }, y)) });
|
|
2196
2217
|
}
|
|
2218
|
+
var CLOSED_HOLD_MS = 3e3;
|
|
2197
2219
|
function RollReveal({ outcome, onDone }) {
|
|
2198
2220
|
const isNoHat = outcome.kind === "no_hat";
|
|
2199
2221
|
const isLegendary = outcome.kind !== "no_hat" && outcome.hat.rarity === "legendary";
|
|
2200
|
-
const [phase, setPhase] = useState7("
|
|
2222
|
+
const [phase, setPhase] = useState7("closed");
|
|
2201
2223
|
useEffect4(() => {
|
|
2202
2224
|
const timers = [];
|
|
2203
|
-
timers.push(setTimeout(() => setPhase("
|
|
2225
|
+
timers.push(setTimeout(() => setPhase("open1"), CLOSED_HOLD_MS));
|
|
2226
|
+
timers.push(setTimeout(() => setPhase("open2"), CLOSED_HOLD_MS + 350));
|
|
2204
2227
|
if (isNoHat) {
|
|
2205
|
-
timers.push(setTimeout(() => setPhase("empty"), 700));
|
|
2206
|
-
timers.push(setTimeout(onDone, 1500));
|
|
2228
|
+
timers.push(setTimeout(() => setPhase("empty"), CLOSED_HOLD_MS + 700));
|
|
2229
|
+
timers.push(setTimeout(onDone, CLOSED_HOLD_MS + 1500));
|
|
2207
2230
|
} else {
|
|
2208
|
-
timers.push(setTimeout(() => setPhase("burst"), 700));
|
|
2209
|
-
timers.push(setTimeout(() => setPhase("reveal"), 1650));
|
|
2210
|
-
timers.push(setTimeout(onDone, isLegendary ? 4650 : 2650));
|
|
2231
|
+
timers.push(setTimeout(() => setPhase("burst"), CLOSED_HOLD_MS + 700));
|
|
2232
|
+
timers.push(setTimeout(() => setPhase("reveal"), CLOSED_HOLD_MS + 1650));
|
|
2233
|
+
timers.push(setTimeout(onDone, CLOSED_HOLD_MS + (isLegendary ? 4650 : 2650)));
|
|
2211
2234
|
}
|
|
2212
2235
|
return () => timers.forEach(clearTimeout);
|
|
2213
2236
|
}, [isNoHat, isLegendary, onDone]);
|
|
2237
|
+
if (phase === "closed") return /* @__PURE__ */ jsx10(GiftBox, { frame: BOX_CLOSED, color: BOX_COLOR });
|
|
2214
2238
|
if (phase === "open1") return /* @__PURE__ */ jsx10(GiftBox, { frame: BOX_OPENING_1, color: BOX_COLOR });
|
|
2215
2239
|
if (phase === "open2") return /* @__PURE__ */ jsx10(GiftBox, { frame: BOX_OPENING_2, color: BOX_COLOR });
|
|
2216
2240
|
if (phase === "empty") return /* @__PURE__ */ jsx10(GiftBox, { frame: BOX_EMPTY, color: BOX_COLOR });
|
|
@@ -2299,12 +2323,6 @@ function resetStdinAfterInk() {
|
|
|
2299
2323
|
process.stdin.pause();
|
|
2300
2324
|
}
|
|
2301
2325
|
async function runReveal(outcome) {
|
|
2302
|
-
resetStdinAfterInk();
|
|
2303
|
-
printClosedBox();
|
|
2304
|
-
const readline7 = await import("readline/promises");
|
|
2305
|
-
const rl = readline7.createInterface({ input: process.stdin, output: process.stdout });
|
|
2306
|
-
await rl.question("Press Enter to open the box\u2026 ");
|
|
2307
|
-
rl.close();
|
|
2308
2326
|
await new Promise((resolve) => {
|
|
2309
2327
|
const app = render5(React13.createElement(RollReveal, {
|
|
2310
2328
|
outcome,
|
|
@@ -2603,7 +2621,7 @@ Maintenance:
|
|
|
2603
2621
|
Stable management:
|
|
2604
2622
|
token-derby stable create Make a new horse (interactive)
|
|
2605
2623
|
token-derby stable list Show your saved horses
|
|
2606
|
-
token-derby stable edit
|
|
2624
|
+
token-derby stable edit [name] Edit an existing horse's colors (interactive picker if no name)
|
|
2607
2625
|
token-derby stable delete <name> Remove a horse from your stable
|
|
2608
2626
|
|
|
2609
2627
|
Organisations:
|