@siegesailor/terminal-sigma 1.1.0 → 1.2.0
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/README.md +59 -24
- package/build/app.js +150 -71
- package/build/app.js.map +1 -1
- package/build/command-line-interface.js +1 -1
- package/build/components/character.js +7 -7
- package/build/components/character.js.map +1 -1
- package/build/components/choice.js +32 -0
- package/build/components/choice.js.map +1 -0
- package/build/components/entry-form.js +9 -7
- package/build/components/entry-form.js.map +1 -1
- package/build/components/footer.js +10 -8
- package/build/components/footer.js.map +1 -1
- package/build/components/logs-view.js +35 -29
- package/build/components/logs-view.js.map +1 -1
- package/build/components/menu-grid.js +3 -2
- package/build/components/menu-grid.js.map +1 -1
- package/build/components/today-panel.js +20 -13
- package/build/components/today-panel.js.map +1 -1
- package/build/content.js +150 -40
- package/build/content.js.map +1 -1
- package/build/health.js +90 -0
- package/build/health.js.map +1 -0
- package/build/i18n.js +379 -30
- package/build/i18n.js.map +1 -1
- package/build/pixel-art.js +262 -305
- package/build/pixel-art.js.map +1 -1
- package/build/progress.js +14 -2
- package/build/progress.js.map +1 -1
- package/build/quotes.js +132 -27
- package/build/quotes.js.map +1 -1
- package/build/theme.js +119 -19
- package/build/theme.js.map +1 -1
- package/package.json +1 -1
package/build/pixel-art.js
CHANGED
|
@@ -1,279 +1,213 @@
|
|
|
1
|
-
// The character is a
|
|
2
|
-
// pixels with "▀", foreground for the top and background for the bottom.
|
|
3
|
-
export const spriteWidth =
|
|
4
|
-
export const spriteHeight =
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
y
|
|
8
|
-
rows
|
|
9
|
-
"....kkkkkkkk....",
|
|
10
|
-
"...khhhhhhhhk...",
|
|
11
|
-
"..khhhhhhhhhhk..",
|
|
12
|
-
"..khsssssssshk..",
|
|
13
|
-
"..kssessssessk..",
|
|
14
|
-
"..ksrssmmssrsk..",
|
|
15
|
-
"...kssssssssk...",
|
|
16
|
-
"....kkksskkk....",
|
|
17
|
-
],
|
|
18
|
-
};
|
|
19
|
-
const body = {
|
|
20
|
-
y: 10,
|
|
21
|
-
rows: [
|
|
22
|
-
"...kaaaaaaaak...",
|
|
23
|
-
"...kAaaaaaaAk...",
|
|
24
|
-
"...kAaaaaaaAk...",
|
|
25
|
-
"...knnnnnnnnk...",
|
|
26
|
-
"...kppppppppk...",
|
|
27
|
-
],
|
|
28
|
-
};
|
|
29
|
-
const straps = { y: 10, rows: rows(3, "......P..P......") };
|
|
30
|
-
const leftArm = {
|
|
31
|
-
y: 10,
|
|
32
|
-
rows: ["..kA............", "..kA............", "..ks............"],
|
|
33
|
-
};
|
|
34
|
-
const rightArm = {
|
|
35
|
-
y: 10,
|
|
36
|
-
rows: ["............Ak..", "............Ak..", "............sk.."],
|
|
37
|
-
};
|
|
38
|
-
const swingingArms = {
|
|
39
|
-
y: 10,
|
|
40
|
-
rows: ["..kA........Ak..", ".ks..........sk."],
|
|
41
|
-
};
|
|
42
|
-
const raisedArms = {
|
|
43
|
-
y: 3,
|
|
44
|
-
rows: [
|
|
45
|
-
".s............s.",
|
|
46
|
-
...rows(4, ".A............A."),
|
|
47
|
-
...rows(3, "..A..........A.."),
|
|
48
|
-
],
|
|
49
|
-
};
|
|
50
|
-
const standingLegs = {
|
|
51
|
-
y: 15,
|
|
52
|
-
rows: [
|
|
53
|
-
"....kpp..ppk....",
|
|
54
|
-
"....kpp..ppk....",
|
|
55
|
-
"....kbb..bbk....",
|
|
56
|
-
"...kbbb..bbbk...",
|
|
57
|
-
],
|
|
58
|
-
};
|
|
59
|
-
const stridingLegs = {
|
|
60
|
-
y: 15,
|
|
61
|
-
rows: ["....kpp..ppk....", "...kpp....ppk...", "..kbb......bbk.."],
|
|
62
|
-
};
|
|
63
|
-
const passingLegs = {
|
|
64
|
-
y: 15,
|
|
65
|
-
rows: [
|
|
66
|
-
".....kppppk.....",
|
|
67
|
-
"......kppk......",
|
|
68
|
-
"......kbbk......",
|
|
69
|
-
".....kbbbbk.....",
|
|
70
|
-
],
|
|
71
|
-
};
|
|
72
|
-
const sweat = { y: 3, rows: ["..............d."] };
|
|
73
|
-
const motionLines = {
|
|
74
|
-
y: 15,
|
|
75
|
-
rows: ["vv..............", "................", "v..............."],
|
|
76
|
-
};
|
|
77
|
-
const laptop = {
|
|
78
|
-
y: 12,
|
|
79
|
-
rows: [
|
|
80
|
-
"..kggggggggggk..",
|
|
81
|
-
"..kggggLLggggk..",
|
|
82
|
-
"..kggggLLggggk..",
|
|
83
|
-
"..kggggggggggk..",
|
|
84
|
-
".kkkkkkkkkkkkkk.",
|
|
85
|
-
],
|
|
86
|
-
};
|
|
87
|
-
const typingArms = (hands) => ({
|
|
88
|
-
y: 10,
|
|
89
|
-
rows: ["..kA........Ak..", hands],
|
|
1
|
+
// The character is a 20x28 pixel canvas, facing right. Each terminal cell draws
|
|
2
|
+
// 2 stacked pixels with "▀", foreground for the top and background for the bottom.
|
|
3
|
+
export const spriteWidth = 20;
|
|
4
|
+
export const spriteHeight = 28;
|
|
5
|
+
const layer = (x, y, ...rows) => ({
|
|
6
|
+
x,
|
|
7
|
+
y,
|
|
8
|
+
rows,
|
|
90
9
|
});
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const appleInHand = {
|
|
107
|
-
y: 11,
|
|
108
|
-
rows: ["...............q", "..............ff", "..............ff"],
|
|
109
|
-
};
|
|
110
|
-
const chewing = { y: 7, rows: [".......oo......."] };
|
|
111
|
-
const dumbbellsUp = {
|
|
112
|
-
y: 1,
|
|
113
|
-
rows: [
|
|
114
|
-
"GG............GG",
|
|
115
|
-
"GG............GG",
|
|
116
|
-
".s............s.",
|
|
117
|
-
...rows(6, ".A............A."),
|
|
118
|
-
"..A..........A..",
|
|
119
|
-
],
|
|
120
|
-
};
|
|
121
|
-
const dumbbellsDown = {
|
|
122
|
-
y: 7,
|
|
123
|
-
rows: [
|
|
124
|
-
"GG............GG",
|
|
125
|
-
"GG............GG",
|
|
126
|
-
".s............s.",
|
|
127
|
-
".AA..........AA.",
|
|
128
|
-
],
|
|
129
|
-
};
|
|
130
|
-
const sparkles = (top, y, bottom) => [
|
|
131
|
-
{ y: 0, rows: [top] },
|
|
132
|
-
{ y, rows: [bottom] },
|
|
10
|
+
const upper = (x, y, ...rows) => ({
|
|
11
|
+
x,
|
|
12
|
+
y,
|
|
13
|
+
rows,
|
|
14
|
+
upper: true,
|
|
15
|
+
});
|
|
16
|
+
const hood = upper(0, 2, "......kkkk", "....kkHHHHkk", "..kkHHHHHHHhk", "kkHHHHHHHHhffk", "..kHHHHHHhffEfk", "...kHHHHHhfffk", "....khhHHhffk", "....kkkkkkkk");
|
|
17
|
+
const neckScarf = upper(4, 10, "kSSSSSSSk", ".ksSSSsk");
|
|
18
|
+
const torso = upper(4, 12, ".kCCCCCCk", ".kcCCCCCCk", ".kcCCCCCCk", ".kcCCCCCk", ".knnnnNnk", "kcCCkCCCCk", "kcCk.kCCCk", ".kk...kkk");
|
|
19
|
+
const pauldron = upper(8, 11, "kaak", ".aaak", ".AAk");
|
|
20
|
+
const tails = [
|
|
21
|
+
upper(0, 10, "sSSS", "SS..", "s..."),
|
|
22
|
+
upper(0, 9, "s...", ".SSS", "..sS"),
|
|
23
|
+
upper(0, 10, "..SS", ".SSs", "Ss.."),
|
|
24
|
+
upper(0, 10, "SSSS", "ssss"),
|
|
133
25
|
];
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
26
|
+
const [tailA, tailB, tailC, tailStream] = tails;
|
|
27
|
+
const hangingArm = upper(10, 14, "cck", "cck", "cck", "mm");
|
|
28
|
+
const standingLegs = layer(5, 19, ".kpk.kpk", ".kPk.kppk", ".kPk.kppk", ".kPk.kppk", ".kPk.kppk", ".kbk.kbbk", "kbbk.kbbbk", "kkkk.kkkkk");
|
|
29
|
+
const stride = (back, front) => layer(1, 19, `.....k${back}${back}${front}${front}k`, `....k${back}k..k${front}${front}k`, `...k${back}k....k${front}${front}k`, `..k${back}k......k${front}k`, ".kbk.......kpk", "kbk........kbbk", "kk.........kkkk");
|
|
30
|
+
const passing = (raised, planted) => layer(4, 19, `..k${raised}${planted}${planted}k`, `.kbk${planted}${planted}k`, `kbbkk${planted}k`, `.kk.k${planted}${planted}k`, `....k${planted}k`, "....kbbk", "....kbbbk", "....kkkkk");
|
|
31
|
+
const runLegs = [
|
|
32
|
+
stride("P", "p"),
|
|
33
|
+
passing("P", "p"),
|
|
34
|
+
stride("p", "P"),
|
|
35
|
+
passing("p", "P"),
|
|
36
|
+
];
|
|
37
|
+
const armForward = upper(10, 13, "cc..", ".cck", "..mm");
|
|
38
|
+
const armBack = upper(7, 13, "..cc", ".cc.", "mm..");
|
|
39
|
+
const speedLines = [
|
|
40
|
+
layer(0, 14, "vv", "", "", "", "v", "", "", "vv"),
|
|
41
|
+
layer(0, 15, "v", "", "", "vv", "", "", "", "v"),
|
|
42
|
+
];
|
|
43
|
+
const table = layer(12, 18, "xxxxxxxx", "......x.", "......x.", "......x.", "......x.", "......x.", "......x.", ".....xxx");
|
|
44
|
+
const laptop = layer(13, 12, "....lL", "....lL", "....lL", "....lL", "....lL", "LLLLLL");
|
|
45
|
+
const typing = [
|
|
46
|
+
upper(10, 13, "cc..", ".cc.", "..cm", "...m"),
|
|
47
|
+
upper(10, 13, "cc..", ".cc.", "..cm", "..m."),
|
|
48
|
+
];
|
|
49
|
+
const codeBits = [
|
|
50
|
+
layer(14, 9, "y", "", "..y", "", ".y"),
|
|
51
|
+
layer(14, 7, ".y", "", "y", "", "..y"),
|
|
52
|
+
layer(15, 5, "y", "", ".y", "", "y"),
|
|
53
|
+
layer(14, 3, "..y", "", "y", "", ".y"),
|
|
54
|
+
];
|
|
55
|
+
const cupLow = upper(10, 13, "cc..", ".ccm", "..QQ", "..Qo");
|
|
56
|
+
const cupRaised = upper(10, 6, "...QQ", "...Qo", "..cm.", ".cc..", ".cc..", ".cc..");
|
|
57
|
+
const steam = [
|
|
58
|
+
layer(12, 12, ".v", "v.", ".v"),
|
|
59
|
+
layer(12, 11, "v.", ".v", "v."),
|
|
60
|
+
layer(14, 3, "v", ".v"),
|
|
146
61
|
];
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
],
|
|
167
|
-
[
|
|
168
|
-
|
|
169
|
-
y: 0,
|
|
170
|
-
rows: [
|
|
171
|
-
".Y............Y.",
|
|
172
|
-
".YY..........YY.",
|
|
173
|
-
"..YYMMMMMMMMYY..",
|
|
174
|
-
"...kMMMMMMMMk...",
|
|
175
|
-
"..kMMMMMMMMMMk..",
|
|
176
|
-
],
|
|
177
|
-
},
|
|
178
|
-
],
|
|
62
|
+
const appleAtMouth = upper(10, 5, "...G.", "...FF", "...FF", "..cm.", ".cc..", ".cc..", ".cc..");
|
|
63
|
+
const appleInHand = upper(10, 13, "cc...", ".cmF.", "..FFG");
|
|
64
|
+
const bitten = upper(10, 13, "cc...", ".cmF.", "..F.G");
|
|
65
|
+
const dumbbellUp = upper(13, 0, "DDD", "DdD", "DDD", ".m.", ".c.", ".c.", ".c.", ".c.", ".c.", ".c.", ".c.", ".c.", "cc.");
|
|
66
|
+
const dumbbellRacked = upper(13, 8, "DDD", "DdD", "DDD", ".m.", ".c.", "cc.");
|
|
67
|
+
const sweat = [layer(16, 6, "u"), layer(16, 8, "u")];
|
|
68
|
+
const reachUp = upper(13, 1, ".m", ".c", ".c", ".c", ".c", ".c", ".c", ".c", ".c", ".c", ".c", "cc");
|
|
69
|
+
const reachForward = upper(10, 13, "ccccc", "....cmm");
|
|
70
|
+
const swordRaised = upper(13, 0, ".t.", ".t.", ".t.", ".t.", "ggg", ".m.", ".c.", ".c.", ".c.", ".c.", ".c.", ".c.", "cc.");
|
|
71
|
+
const sparkles = [
|
|
72
|
+
layer(0, 1, ".y..........y", "", "", "", "", "", "y.................y"),
|
|
73
|
+
layer(0, 3, "y.................y", "", "", "", "", "..y...........y"),
|
|
74
|
+
];
|
|
75
|
+
const breathing = (legs, front) => [
|
|
76
|
+
{ legs, behind: [tailA], front },
|
|
77
|
+
{ legs, behind: [tailB], front },
|
|
78
|
+
{ legs, behind: [tailC], front, breathe: true },
|
|
79
|
+
{ legs, behind: [tailB], front, breathe: true },
|
|
80
|
+
{ legs, behind: [tailA], front },
|
|
81
|
+
{ legs, behind: [tailB], front, blink: true },
|
|
82
|
+
{ legs, behind: [tailC], front, breathe: true },
|
|
83
|
+
{ legs, behind: [tailB], front, breathe: true },
|
|
179
84
|
];
|
|
180
|
-
const arms = [leftArm, rightArm];
|
|
181
85
|
const animations = {
|
|
182
86
|
idle: {
|
|
183
|
-
interval:
|
|
184
|
-
frames: [
|
|
185
|
-
...Array.from({ length: 11 }, () => ({
|
|
186
|
-
layers: [...arms, standingLegs],
|
|
187
|
-
})),
|
|
188
|
-
{ layers: [...arms, standingLegs], blink: true },
|
|
189
|
-
],
|
|
87
|
+
interval: 220,
|
|
88
|
+
frames: breathing(standingLegs, [hangingArm]),
|
|
190
89
|
},
|
|
191
90
|
focus: {
|
|
192
|
-
interval:
|
|
91
|
+
interval: 160,
|
|
92
|
+
frames: codeBits.map((bits, index) => ({
|
|
93
|
+
legs: standingLegs,
|
|
94
|
+
behind: [index % 2 === 0 ? tailA : tailB, table],
|
|
95
|
+
front: [laptop, typing[index % 2] ?? hangingArm, bits],
|
|
96
|
+
breathe: index >= 2,
|
|
97
|
+
})),
|
|
98
|
+
},
|
|
99
|
+
break: {
|
|
100
|
+
interval: 380,
|
|
193
101
|
frames: [
|
|
102
|
+
{ legs: standingLegs, behind: [tailA], front: [cupLow, steam[0]] },
|
|
194
103
|
{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
steam(1, "............O..."),
|
|
200
|
-
],
|
|
104
|
+
legs: standingLegs,
|
|
105
|
+
behind: [tailB],
|
|
106
|
+
front: [cupLow, steam[1]],
|
|
107
|
+
breathe: true,
|
|
201
108
|
},
|
|
202
109
|
{
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
steam(0, "..............O."),
|
|
208
|
-
],
|
|
110
|
+
legs: standingLegs,
|
|
111
|
+
behind: [tailC],
|
|
112
|
+
front: [cupLow, steam[0]],
|
|
113
|
+
breathe: true,
|
|
209
114
|
},
|
|
210
|
-
],
|
|
211
|
-
},
|
|
212
|
-
break: {
|
|
213
|
-
interval: 600,
|
|
214
|
-
frames: [
|
|
215
115
|
{
|
|
216
|
-
|
|
116
|
+
legs: standingLegs,
|
|
117
|
+
behind: [tailB],
|
|
118
|
+
front: [cupRaised, steam[2]],
|
|
119
|
+
blink: true,
|
|
217
120
|
},
|
|
218
121
|
{
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
cup,
|
|
223
|
-
steam(9, "..............v."),
|
|
224
|
-
steam(8, ".............v.."),
|
|
225
|
-
],
|
|
122
|
+
legs: standingLegs,
|
|
123
|
+
behind: [tailA],
|
|
124
|
+
front: [cupRaised, steam[2]],
|
|
226
125
|
blink: true,
|
|
227
126
|
},
|
|
127
|
+
{ legs: standingLegs, behind: [tailB], front: [cupLow, steam[1]] },
|
|
228
128
|
],
|
|
229
129
|
},
|
|
230
130
|
eat: {
|
|
231
|
-
interval:
|
|
131
|
+
interval: 300,
|
|
232
132
|
frames: [
|
|
233
|
-
{
|
|
234
|
-
{
|
|
133
|
+
{ legs: standingLegs, behind: [tailA], front: [appleInHand] },
|
|
134
|
+
{ legs: standingLegs, behind: [tailB], front: [appleAtMouth] },
|
|
135
|
+
{
|
|
136
|
+
legs: standingLegs,
|
|
137
|
+
behind: [tailC],
|
|
138
|
+
front: [appleAtMouth],
|
|
139
|
+
breathe: true,
|
|
140
|
+
},
|
|
141
|
+
{ legs: standingLegs, behind: [tailB], front: [bitten], breathe: true },
|
|
235
142
|
],
|
|
236
143
|
},
|
|
237
144
|
run: {
|
|
238
|
-
interval:
|
|
239
|
-
frames:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
145
|
+
interval: 110,
|
|
146
|
+
frames: runLegs.map((legs, index) => ({
|
|
147
|
+
legs,
|
|
148
|
+
behind: [tailStream, speedLines[index % 2] ?? tailStream],
|
|
149
|
+
front: [index % 2 === 0 ? armForward : armBack],
|
|
150
|
+
dy: index % 2 === 0 ? 0 : -1,
|
|
151
|
+
})),
|
|
243
152
|
},
|
|
244
153
|
lift: {
|
|
245
|
-
interval:
|
|
154
|
+
interval: 420,
|
|
246
155
|
frames: [
|
|
247
|
-
{
|
|
248
|
-
{
|
|
156
|
+
{ legs: standingLegs, behind: [tailA], front: [dumbbellRacked] },
|
|
157
|
+
{
|
|
158
|
+
legs: standingLegs,
|
|
159
|
+
behind: [tailB],
|
|
160
|
+
front: [dumbbellUp, sweat[0]],
|
|
161
|
+
dy: -1,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
legs: standingLegs,
|
|
165
|
+
behind: [tailC],
|
|
166
|
+
front: [dumbbellUp, sweat[1]],
|
|
167
|
+
dy: -1,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
legs: standingLegs,
|
|
171
|
+
behind: [tailB],
|
|
172
|
+
front: [dumbbellRacked],
|
|
173
|
+
breathe: true,
|
|
174
|
+
},
|
|
249
175
|
],
|
|
250
176
|
},
|
|
251
177
|
stretch: {
|
|
252
|
-
interval:
|
|
178
|
+
interval: 520,
|
|
253
179
|
frames: [
|
|
254
|
-
{
|
|
255
|
-
{
|
|
180
|
+
{ legs: standingLegs, behind: [tailA], front: [reachUp], dy: -1 },
|
|
181
|
+
{ legs: standingLegs, behind: [tailB], front: [reachUp], dy: -1 },
|
|
182
|
+
{
|
|
183
|
+
legs: standingLegs,
|
|
184
|
+
behind: [tailC],
|
|
185
|
+
front: [reachForward],
|
|
186
|
+
breathe: true,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
legs: standingLegs,
|
|
190
|
+
behind: [tailB],
|
|
191
|
+
front: [reachForward],
|
|
192
|
+
breathe: true,
|
|
193
|
+
},
|
|
256
194
|
],
|
|
257
195
|
},
|
|
258
196
|
levelUp: {
|
|
259
|
-
interval:
|
|
260
|
-
frames: [
|
|
197
|
+
interval: 160,
|
|
198
|
+
frames: sparkles.flatMap((burst, index) => [
|
|
261
199
|
{
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
],
|
|
200
|
+
legs: standingLegs,
|
|
201
|
+
behind: [tailStream],
|
|
202
|
+
front: [swordRaised, burst],
|
|
203
|
+
dy: -1,
|
|
267
204
|
},
|
|
268
205
|
{
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
...sparkles("y..............y", 16, "..y..........y.."),
|
|
273
|
-
],
|
|
274
|
-
dy: -1,
|
|
206
|
+
legs: standingLegs,
|
|
207
|
+
behind: [index === 0 ? tailA : tailC],
|
|
208
|
+
front: [swordRaised, burst],
|
|
275
209
|
},
|
|
276
|
-
],
|
|
210
|
+
]),
|
|
277
211
|
},
|
|
278
212
|
};
|
|
279
213
|
export const animationOf = (activity) => animations[activity];
|
|
@@ -281,85 +215,108 @@ export const animationOf = (activity) => animations[activity];
|
|
|
281
215
|
// so every level from 2 to 9 changes exactly 1 piece.
|
|
282
216
|
export const gearOf = (level) => {
|
|
283
217
|
const tier = (slot) => Math.min(Math.max(Math.floor((level - 2 - slot) / 4) + 1, 0), 2);
|
|
284
|
-
return {
|
|
285
|
-
weapon: tier(0),
|
|
286
|
-
armor: tier(1),
|
|
287
|
-
helmet: tier(2),
|
|
288
|
-
backpack: tier(3),
|
|
289
|
-
};
|
|
218
|
+
return { weapon: tier(0), armor: tier(1), hood: tier(2), relic: tier(3) };
|
|
290
219
|
};
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
["h", "#6b4226"],
|
|
301
|
-
["H", "#8e5cc4"],
|
|
302
|
-
["k", "#2b2135"],
|
|
303
|
-
["L", "#D97757"],
|
|
304
|
-
["m", "#b5524f"],
|
|
305
|
-
["M", "#b8c0cc"],
|
|
306
|
-
["n", "#7a4f2a"],
|
|
307
|
-
["o", "#7a2e2e"],
|
|
308
|
-
["O", "#57e3f0"],
|
|
309
|
-
["p", "#3d4f7a"],
|
|
310
|
-
["q", "#4caf6a"],
|
|
311
|
-
["r", "#f08c8c"],
|
|
312
|
-
["s", "#f5c9a0"],
|
|
313
|
-
["v", "#c8c8c8"],
|
|
314
|
-
["V", "#57e3f0"],
|
|
315
|
-
["W", "#9b6b3d"],
|
|
316
|
-
["y", "#ffd84d"],
|
|
317
|
-
["Y", "#f2e6c8"],
|
|
220
|
+
const weapons = [
|
|
221
|
+
upper(2, 13, ".g.", "xxx", ".W.", ".W.", ".W.", ".W.", ".W.", ".w."),
|
|
222
|
+
upper(2, 11, ".g.", ".g.", "xxx", ".w.", ".W.", ".W.", ".W.", ".W.", ".W.", ".W.", ".W.", ".w."),
|
|
223
|
+
upper(1, 10, "..t", "..g", ".xxx", ".tw", ".tw", ".tw", ".tw", ".tw", ".tw", ".tw", ".tw", ".tw", "..t"),
|
|
224
|
+
];
|
|
225
|
+
const hoods = [
|
|
226
|
+
upper(0, 0, ""),
|
|
227
|
+
upper(4, 4, "SSSSSSS"),
|
|
228
|
+
upper(4, 0, ".Y....Y", ".YY..YY"),
|
|
318
229
|
];
|
|
230
|
+
// The relic is a companion orb that bobs beside the character.
|
|
231
|
+
const relics = [
|
|
232
|
+
() => [],
|
|
233
|
+
(bob) => [layer(17, 4 + bob, "t")],
|
|
234
|
+
(bob) => [layer(16, 3 + bob, ".y.", "ytt", ".tt")],
|
|
235
|
+
];
|
|
236
|
+
const orbBob = [0, 0, 1, 1];
|
|
319
237
|
const armorColors = [
|
|
320
|
-
["#
|
|
321
|
-
["#
|
|
322
|
-
["#
|
|
238
|
+
["#6B4A35", "#4A3324"],
|
|
239
|
+
["#A3ACB8", "#6A7380"],
|
|
240
|
+
["#D9B45A", "#9C7A2E"],
|
|
323
241
|
];
|
|
324
|
-
|
|
325
|
-
export function paletteOf(level) {
|
|
242
|
+
export function paletteOf(level, palette) {
|
|
326
243
|
const gear = gearOf(level);
|
|
327
244
|
const [armor, armorShade] = armorColors[gear.armor] ?? armorColors[0];
|
|
245
|
+
const { cloak, cloakShade, scarf, scarfShade, glow } = palette.sprite;
|
|
328
246
|
return new Map([
|
|
329
|
-
...fixedColors,
|
|
330
|
-
["a", armor],
|
|
331
247
|
["A", armorShade],
|
|
332
|
-
["
|
|
248
|
+
["a", armor],
|
|
249
|
+
["b", "#3B2D25"],
|
|
250
|
+
["C", cloak],
|
|
251
|
+
["c", cloakShade],
|
|
252
|
+
["D", "#50555F"],
|
|
253
|
+
["d", "#8A8F99"],
|
|
254
|
+
["E", glow],
|
|
255
|
+
["F", "#C8473F"],
|
|
256
|
+
["f", "#241F2B"],
|
|
257
|
+
["G", "#5F8F4E"],
|
|
258
|
+
["g", "#B8913A"],
|
|
259
|
+
["H", cloak],
|
|
260
|
+
["h", cloakShade],
|
|
261
|
+
["k", "#15121A"],
|
|
262
|
+
["L", "#4A505B"],
|
|
263
|
+
["l", glow],
|
|
264
|
+
["m", "#C99272"],
|
|
265
|
+
["N", armor],
|
|
266
|
+
["n", "#4A3628"],
|
|
267
|
+
["o", "#5A3A25"],
|
|
268
|
+
["P", "#23252F"],
|
|
269
|
+
["p", "#2E3140"],
|
|
270
|
+
["Q", "#E6E0D4"],
|
|
271
|
+
["S", scarf],
|
|
272
|
+
["s", scarfShade],
|
|
273
|
+
["t", glow],
|
|
274
|
+
["u", "#8FC6E8"],
|
|
275
|
+
["v", "#9AA0A8"],
|
|
276
|
+
["W", "#8792A0"],
|
|
277
|
+
["w", "#C9D3DE"],
|
|
278
|
+
["x", "#3D414B"],
|
|
279
|
+
["Y", "#E8DCC0"],
|
|
280
|
+
["y", palette.soft],
|
|
333
281
|
]);
|
|
334
282
|
}
|
|
335
|
-
// The pixel keys of 1 frame, row by row, "." where nothing is drawn.
|
|
336
|
-
|
|
283
|
+
// The pixel keys of 1 frame, row by row, "." where nothing is drawn. The
|
|
284
|
+
// counter keeps running across frames, so the relic bobs on its own beat.
|
|
285
|
+
export function composeFrame(activity, counter, level) {
|
|
337
286
|
const { frames } = animations[activity];
|
|
338
|
-
const frame = frames[
|
|
287
|
+
const frame = frames[counter % frames.length] ?? frames[0];
|
|
339
288
|
const gear = gearOf(level);
|
|
340
|
-
const canvas =
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
289
|
+
const canvas = Array.from({ length: spriteHeight }, () => Array.from({ length: spriteWidth }, () => "."));
|
|
290
|
+
if (!frame) {
|
|
291
|
+
return canvas.map((row) => row.join(""));
|
|
292
|
+
}
|
|
293
|
+
const lowerDy = frame.dy ?? 0;
|
|
294
|
+
const upperDy = lowerDy + (frame.breathe ? 1 : 0);
|
|
295
|
+
const head = frame.blink
|
|
296
|
+
? { ...hood, rows: hood.rows.map((row) => row.replaceAll("E", "f")) }
|
|
297
|
+
: hood;
|
|
346
298
|
const layers = [
|
|
347
299
|
weapons[gear.weapon],
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
300
|
+
...(frame.behind ?? []),
|
|
301
|
+
frame.legs,
|
|
302
|
+
torso,
|
|
303
|
+
neckScarf,
|
|
304
|
+
head,
|
|
305
|
+
hoods[gear.hood],
|
|
306
|
+
pauldron,
|
|
307
|
+
...(frame.front ?? []),
|
|
308
|
+
...(relics[gear.relic]?.(orbBob[counter % orbBob.length] ?? 0) ?? []),
|
|
353
309
|
];
|
|
354
|
-
for (const
|
|
355
|
-
if (!
|
|
310
|
+
for (const item of layers) {
|
|
311
|
+
if (!item) {
|
|
356
312
|
continue;
|
|
357
313
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
314
|
+
const dy = item.upper ? upperDy : lowerDy;
|
|
315
|
+
for (const [offset, row] of item.rows.entries()) {
|
|
316
|
+
const target = canvas[item.y + offset + dy];
|
|
317
|
+
for (const [index, key] of [...row].entries()) {
|
|
318
|
+
if (target && key !== "." && item.x + index < spriteWidth) {
|
|
319
|
+
target[item.x + index] = key;
|
|
363
320
|
}
|
|
364
321
|
}
|
|
365
322
|
}
|
|
@@ -374,13 +331,13 @@ export function toSegments(frame, palette) {
|
|
|
374
331
|
const bottom = frame[y + 1] ?? "";
|
|
375
332
|
const line = [];
|
|
376
333
|
for (let x = 0; x < spriteWidth; x++) {
|
|
377
|
-
const
|
|
378
|
-
const
|
|
379
|
-
const cell =
|
|
380
|
-
?
|
|
334
|
+
const upperColor = palette.get(top[x] ?? ".");
|
|
335
|
+
const lowerColor = palette.get(bottom[x] ?? ".");
|
|
336
|
+
const cell = upperColor === undefined
|
|
337
|
+
? lowerColor === undefined
|
|
381
338
|
? { text: " " }
|
|
382
|
-
: { text: "▄", color:
|
|
383
|
-
: { text: "▀", color:
|
|
339
|
+
: { text: "▄", color: lowerColor }
|
|
340
|
+
: { text: "▀", color: upperColor, backgroundColor: lowerColor };
|
|
384
341
|
const previous = line.at(-1);
|
|
385
342
|
if (previous &&
|
|
386
343
|
previous.color === cell.color &&
|