@kevin5251984/guild 0.2.12 → 0.2.14

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.
@@ -1,432 +0,0 @@
1
- /* 18×32 tavern buddy. Handle-seeded hair/skin/cloth + outline. Not a cast. */
2
- (function (root) {
3
- "use strict";
4
- const W = 18;
5
- const H = 32;
6
- const OUT = [27, 21, 16];
7
- const SHOE = [
8
- [44, 36, 32],
9
- [62, 44, 34],
10
- ];
11
- const PANTS = [
12
- [42, 48, 62],
13
- [58, 48, 40],
14
- [46, 58, 48],
15
- [72, 64, 58],
16
- ];
17
- const HAIR_RGB = [
18
- [42, 28, 18],
19
- [22, 18, 16],
20
- [196, 163, 90],
21
- [122, 52, 44],
22
- [58, 72, 108],
23
- [88, 56, 140],
24
- [154, 86, 46],
25
- [72, 44, 58],
26
- ];
27
- const SKIN = [
28
- { hi: [255, 221, 189], base: [247, 201, 170], sh: [212, 158, 126], line: [168, 112, 82] },
29
- { hi: [232, 182, 136], base: [214, 162, 116], sh: [176, 126, 86], line: [138, 92, 60] },
30
- { hi: [196, 148, 108], base: [176, 128, 90], sh: [140, 98, 68], line: [104, 70, 48] },
31
- { hi: [168, 118, 86], base: [146, 100, 70], sh: [112, 76, 52], line: [80, 54, 36] },
32
- { hi: [130, 90, 64], base: [108, 74, 52], sh: [82, 56, 38], line: [56, 38, 26] },
33
- ];
34
- const L = 4;
35
- const R = 13;
36
-
37
- function clamp(v) {
38
- return v < 0 ? 0 : v > 255 ? 255 : Math.round(v);
39
- }
40
- function shades(rgb, hi = 1.22, lo = 0.68) {
41
- return [
42
- [clamp(rgb[0] * hi), clamp(rgb[1] * hi), clamp(rgb[2] * hi)],
43
- rgb,
44
- [clamp(rgb[0] * lo), clamp(rgb[1] * lo), clamp(rgb[2] * lo)],
45
- ];
46
- }
47
- function parseHex(hex) {
48
- const h = String(hex || "#7c6af7").replace("#", "");
49
- const full = h.length === 3 ? h[0] + h[0] + h[1] + h[1] + h[2] + h[2] : h;
50
- return [
51
- parseInt(full.slice(0, 2), 16) || 120,
52
- parseInt(full.slice(2, 4), 16) || 100,
53
- parseInt(full.slice(4, 6), 16) || 90,
54
- ];
55
- }
56
- function set(buf, x, y, c, a = 255) {
57
- if (x < 0 || x >= W || y < 0 || y >= H) return;
58
- const i = (y * W + x) * 4;
59
- buf[i] = c[0];
60
- buf[i + 1] = c[1];
61
- buf[i + 2] = c[2];
62
- buf[i + 3] = a;
63
- }
64
- function alpha(buf, x, y) {
65
- if (x < 0 || x >= W || y < 0 || y >= H) return 0;
66
- return buf[(y * W + x) * 4 + 3];
67
- }
68
- function rect(buf, x0, y0, x1, y1, c) {
69
- for (let y = y0; y <= y1; y++) for (let x = x0; x <= x1; x++) set(buf, x, y, c);
70
- }
71
- function dots(buf, pts, c) {
72
- for (const [x, y] of pts) set(buf, x, y, c);
73
- }
74
-
75
- function drawHead(buf, s) {
76
- for (let y = 4; y <= 16; y++) {
77
- for (let x = L; x <= R; x++) {
78
- if ((x === L || x === R) && (y === 4 || y === 16)) continue;
79
- if ((x === L + 1 || x === R - 1) && y === 4) continue;
80
- set(buf, x, y, s.base);
81
- }
82
- }
83
- for (let y = 6; y <= 11; y++) set(buf, 5, y, s.hi);
84
- set(buf, 6, 5, s.hi);
85
- set(buf, 7, 5, s.hi);
86
- for (let y = 6; y <= 15; y++) set(buf, 12, y, s.sh);
87
- for (const x of [7, 8, 9, 10, 11]) set(buf, x, 16, s.sh);
88
- set(buf, 3, 9, s.base);
89
- set(buf, 3, 10, s.base);
90
- set(buf, 3, 11, s.sh);
91
- set(buf, 14, 9, s.base);
92
- set(buf, 14, 10, s.base);
93
- set(buf, 14, 11, s.sh);
94
- rect(buf, 7, 17, 10, 18, s.sh);
95
- rect(buf, 7, 17, 9, 17, s.base);
96
- }
97
-
98
- function drawFace(buf, s, brow, mouth, blush, lashes) {
99
- const white = [250, 248, 244];
100
- const pup = [46, 38, 42];
101
- const glint = [252, 250, 248];
102
- const lash = [54, 40, 48];
103
- const lip = [158, 86, 80];
104
- set(buf, 5, 9, white);
105
- set(buf, 6, 9, pup);
106
- set(buf, 10, 9, pup);
107
- set(buf, 11, 9, white);
108
- set(buf, 5, 9, glint);
109
- if (lashes) {
110
- for (const x of [5, 6, 10, 11]) set(buf, x, 8, lash);
111
- set(buf, 4, 8, lash);
112
- set(buf, 12, 8, lash);
113
- set(buf, 10, 9, glint);
114
- }
115
- if (brow === 0) for (const x of [5, 6, 10, 11]) set(buf, x, 7, s.line);
116
- else if (brow === 1) {
117
- set(buf, 5, 8, s.line);
118
- set(buf, 6, 7, s.line);
119
- set(buf, 10, 7, s.line);
120
- set(buf, 11, 8, s.line);
121
- } else if (brow === 2) for (const x of [5, 6, 10, 11]) set(buf, x, 6, s.line);
122
- else {
123
- set(buf, 5, 7, s.line);
124
- set(buf, 11, 7, s.line);
125
- set(buf, 6, 7, s.sh);
126
- set(buf, 10, 7, s.sh);
127
- }
128
- set(buf, 8, 11, s.sh);
129
- set(buf, 8, 12, s.sh);
130
- set(buf, 7, 12, s.sh);
131
- const mouths = [
132
- [[7, 14], [8, 14], [9, 14], [10, 14]],
133
- [[7, 14], [8, 14], [9, 14], [10, 14], [6, 13], [11, 13]],
134
- [[7, 15], [8, 15], [9, 15], [10, 15]],
135
- [[6, 14], [7, 14], [8, 14], [9, 14], [10, 14], [11, 14], [6, 13], [11, 13]],
136
- ];
137
- dots(buf, mouths[mouth], lip);
138
- if (blush) {
139
- set(buf, 5, 12, [228, 140, 128]);
140
- set(buf, 12, 12, [228, 140, 128]);
141
- }
142
- }
143
-
144
- function hairShort(buf, hi, base, sh) {
145
- rect(buf, L, 2, R, 4, base);
146
- rect(buf, L - 1, 3, R + 1, 5, base);
147
- for (let y = 6; y <= 8; y++) {
148
- set(buf, L - 1, y, base);
149
- set(buf, L, y, base);
150
- set(buf, R, y, base);
151
- set(buf, R + 1, y, base);
152
- }
153
- for (let x = L; x <= R; x++) set(buf, x, 5, base);
154
- for (let y = 2; y <= 5; y++) set(buf, 8, y, sh);
155
- for (let x = L; x <= 7; x++) if (alpha(buf, x, 2)) set(buf, x, 2, hi);
156
- for (let x = L; x <= 7; x++) if (alpha(buf, x, 3)) set(buf, x, 3, hi);
157
- }
158
- function hairFringe(buf, hi, base, sh, skinBase) {
159
- hairShort(buf, hi, base, sh);
160
- rect(buf, 6, 6, 11, 6, base);
161
- set(buf, 8, 6, skinBase);
162
- set(buf, 9, 6, skinBase);
163
- set(buf, 7, 6, hi);
164
- set(buf, 10, 6, base);
165
- }
166
- function hairLong(buf, hi, base, sh, skinBase) {
167
- hairShort(buf, hi, base, sh);
168
- rect(buf, 6, 6, 11, 6, base);
169
- set(buf, 8, 6, skinBase);
170
- set(buf, 9, 6, skinBase);
171
- for (let y = 9; y <= 18; y++) {
172
- set(buf, L - 1, y, base);
173
- set(buf, R + 1, y, sh);
174
- }
175
- set(buf, L - 1, 19, base);
176
- set(buf, R + 1, 19, sh);
177
- }
178
- function hairBun(buf, hi, base, sh, skinBase) {
179
- rect(buf, L, 3, R, 5, base);
180
- rect(buf, L - 1, 4, R + 1, 5, base);
181
- rect(buf, 7, 1, 10, 2, base);
182
- set(buf, 8, 0, hi);
183
- set(buf, 9, 0, base);
184
- rect(buf, 6, 6, 11, 6, base);
185
- set(buf, 8, 6, skinBase);
186
- set(buf, 9, 6, skinBase);
187
- for (let y = 6; y <= 8; y++) {
188
- set(buf, L, y, base);
189
- set(buf, R, y, sh);
190
- }
191
- for (let x = L; x <= R; x++) if (alpha(buf, x, 3)) set(buf, x, 3, hi);
192
- }
193
- function hairCurly(buf, hi, base, sh, skinBase) {
194
- rect(buf, L, 3, R, 5, base);
195
- const pts = [
196
- [4, 2], [5, 1], [6, 2], [7, 1], [8, 2], [9, 1], [10, 2], [11, 1], [12, 2], [13, 2],
197
- [3, 3], [3, 4], [3, 5], [3, 6], [14, 3], [14, 4], [14, 5], [14, 6], [4, 6], [13, 6],
198
- ];
199
- dots(buf, pts, base);
200
- rect(buf, 6, 6, 11, 6, base);
201
- set(buf, 8, 6, skinBase);
202
- set(buf, 9, 6, skinBase);
203
- dots(buf, [[5, 1], [7, 1], [9, 1], [11, 1]], hi);
204
- set(buf, R + 1, 5, sh);
205
- }
206
- function hairSpiky(buf, hi, base, sh, skinBase) {
207
- rect(buf, L, 3, R, 5, base);
208
- rect(buf, L - 1, 4, R + 1, 5, base);
209
- dots(buf, [[5, 2], [6, 1], [7, 2], [8, 1], [9, 2], [10, 1], [11, 2], [12, 1], [13, 2]], base);
210
- dots(buf, [[6, 1], [8, 1], [10, 1], [12, 1]], hi);
211
- rect(buf, 6, 6, 11, 6, base);
212
- set(buf, 8, 6, skinBase);
213
- set(buf, 9, 6, skinBase);
214
- for (let y = 6; y <= 7; y++) {
215
- set(buf, L, y, base);
216
- set(buf, R, y, sh);
217
- }
218
- }
219
- function hairBob(buf, hi, base, sh, skinBase) {
220
- hairShort(buf, hi, base, sh);
221
- rect(buf, 5, 6, 12, 6, base);
222
- set(buf, 8, 6, skinBase);
223
- set(buf, 9, 6, skinBase);
224
- for (let y = 7; y <= 12; y++) {
225
- set(buf, L - 1, y, base);
226
- set(buf, R + 1, y, sh);
227
- }
228
- set(buf, L - 1, 13, base);
229
- set(buf, R + 1, 13, sh);
230
- }
231
- function hairPony(buf, hi, base, sh) {
232
- hairShort(buf, hi, base, sh);
233
- rect(buf, 11, 0, 13, 2, base);
234
- set(buf, 12, 0, hi);
235
- set(buf, 13, 3, sh);
236
- set(buf, 14, 1, base);
237
- set(buf, 14, 2, sh);
238
- }
239
-
240
- const HAIR_FNS = [hairShort, hairFringe, hairLong, hairBun, hairCurly, hairSpiky, hairBob, hairPony];
241
-
242
- function drawFacial(buf, kind, color) {
243
- const [, base, sh] = shades(color);
244
- if (kind === 1) {
245
- for (const x of [6, 7, 8, 9, 10]) set(buf, x, 13, base);
246
- set(buf, 6, 12, base);
247
- set(buf, 10, 12, base);
248
- } else if (kind === 2) {
249
- dots(buf, [[5, 14], [6, 15], [7, 15], [8, 15], [9, 15], [10, 15], [11, 14], [12, 13], [4, 13]], sh);
250
- } else if (kind === 3) {
251
- rect(buf, 8, 14, 9, 15, base);
252
- rect(buf, 7, 13, 10, 13, base);
253
- }
254
- }
255
-
256
- function drawGlasses(buf) {
257
- const frame = [60, 54, 62];
258
- const glint = [236, 240, 246];
259
- for (const x of [5, 6]) {
260
- set(buf, x, 8, frame);
261
- set(buf, x, 10, frame);
262
- }
263
- set(buf, 4, 9, frame);
264
- set(buf, 7, 9, frame);
265
- for (const x of [10, 11]) {
266
- set(buf, x, 8, frame);
267
- set(buf, x, 10, frame);
268
- }
269
- set(buf, 9, 9, frame);
270
- set(buf, 12, 9, frame);
271
- set(buf, 8, 8, frame);
272
- set(buf, 3, 9, frame);
273
- set(buf, 13, 9, frame);
274
- set(buf, 4, 8, glint);
275
- set(buf, 9, 8, glint);
276
- }
277
-
278
- function drawBody(buf, cloth, c1, c2, skin) {
279
- const [hi, base, sh] = shades(c1);
280
- rect(buf, 4, 18, 13, 18, base);
281
- rect(buf, 3, 19, 14, 19, base);
282
- rect(buf, 4, 20, 13, 24, base);
283
- for (let y = 20; y <= 24; y++) {
284
- set(buf, 3, y, sh);
285
- set(buf, 14, y, sh);
286
- set(buf, 13, y, sh);
287
- }
288
- set(buf, 3, 24, skin.sh);
289
- set(buf, 14, 24, skin.sh);
290
- if (cloth === 0) {
291
- for (const [x, y] of [[6, 18], [7, 18], [10, 18], [11, 18]]) set(buf, x, y, sh);
292
- rect(buf, 7, 18, 10, 19, skin.sh);
293
- } else if (cloth === 1) {
294
- const inner = c2 ? shades(c2)[1] : [235, 233, 226];
295
- for (let y = 18; y <= 24; y++) {
296
- set(buf, 8, y, inner);
297
- set(buf, 9, y, inner);
298
- }
299
- for (const [x, y] of [[6, 18], [7, 18], [10, 18], [11, 18]]) set(buf, x, y, sh);
300
- } else if (cloth === 2) {
301
- for (const [x, y] of [[6, 18], [7, 18], [10, 18], [11, 18]]) set(buf, x, y, hi);
302
- set(buf, 8, 19, sh);
303
- set(buf, 8, 21, sh);
304
- } else if (cloth === 3) {
305
- for (const x of [6, 7, 8, 9, 10, 11]) set(buf, x, 18, sh);
306
- } else if (cloth === 4) {
307
- const inner = c2 ? shades(c2)[1] : [238, 236, 228];
308
- rect(buf, 7, 18, 10, 19, inner);
309
- for (const [x, y] of [[6, 18], [7, 19], [11, 18], [10, 19]]) set(buf, x, y, sh);
310
- for (let y = 20; y <= 24; y += 2) set(buf, 8, y, sh);
311
- } else {
312
- const apron = [236, 224, 196];
313
- rect(buf, 7, 20, 10, 24, apron);
314
- set(buf, 8, 19, apron);
315
- set(buf, 9, 19, apron);
316
- for (const [x, y] of [[6, 18], [7, 18], [10, 18], [11, 18]]) set(buf, x, y, hi);
317
- }
318
- }
319
-
320
- function drawLegs(buf, pants, shoe, short) {
321
- const top = short ? 26 : 25;
322
- const foot = short ? 30 : 31;
323
- const [, base, sh] = shades(pants);
324
- rect(buf, 5, top, 7, foot - 1, base);
325
- rect(buf, 10, top, 12, foot - 1, base);
326
- for (let y = top; y <= foot - 1; y++) {
327
- set(buf, 7, y, sh);
328
- set(buf, 12, y, sh);
329
- }
330
- rect(buf, 5, foot, 7, foot, shoe);
331
- rect(buf, 10, foot, 12, foot, shoe);
332
- }
333
-
334
- function elfEars(buf, s) {
335
- dots(buf, [[2, 8], [2, 7], [3, 7], [3, 8]], s.base);
336
- set(buf, 2, 7, s.hi);
337
- dots(buf, [[15, 8], [15, 7], [14, 7], [14, 8]], s.base);
338
- set(buf, 15, 7, s.hi);
339
- }
340
-
341
- function demiEars(buf, s) {
342
- set(buf, 3, 8, s.base);
343
- set(buf, 2, 9, s.sh);
344
- set(buf, 14, 8, s.base);
345
- set(buf, 15, 9, s.sh);
346
- }
347
-
348
- function dwarfStout(buf, clothRgb, skin) {
349
- const sh = shades(clothRgb)[2];
350
- for (let y = 19; y <= 24; y++) {
351
- set(buf, 2, y, sh);
352
- set(buf, 15, y, sh);
353
- }
354
- for (const x of [5, 6, 10, 11]) set(buf, x, 7, skin.line);
355
- }
356
-
357
- function outlinePass(buf) {
358
- const pts = [];
359
- for (let y = 0; y < H; y++) {
360
- for (let x = 0; x < W; x++) {
361
- if (alpha(buf, x, y) !== 0) continue;
362
- if (
363
- alpha(buf, x + 1, y) === 255 ||
364
- alpha(buf, x - 1, y) === 255 ||
365
- alpha(buf, x, y + 1) === 255 ||
366
- alpha(buf, x, y - 1) === 255
367
- ) {
368
- pts.push([x, y]);
369
- }
370
- }
371
- }
372
- for (const [x, y] of pts) set(buf, x, y, OUT);
373
- }
374
-
375
- function fnv(key) {
376
- let n = 2166136261;
377
- const s = String(key || "");
378
- for (let i = 0; i < s.length; i++) {
379
- n ^= s.charCodeAt(i);
380
- n = Math.imul(n, 16777619);
381
- }
382
- return n >>> 0;
383
- }
384
-
385
- function buddyPixels(shirt, seed) {
386
- const n = typeof seed === "string" ? fnv(seed) : seed >>> 0;
387
- const buf = new Uint8ClampedArray(W * H * 4);
388
- const race = (n >>> 20) % 4;
389
- const skin = SKIN[n % SKIN.length];
390
- const hairc = HAIR_RGB[(n * 3) % HAIR_RGB.length];
391
- const [hi, base, sh] = shades(hairc);
392
- const cloth = n % 6;
393
- const pants = PANTS[(n * 5) % PANTS.length];
394
- const shoe = SHOE[n % SHOE.length];
395
- const shirtRgb = parseHex(shirt);
396
- const accent = shades(shirtRgb)[2];
397
- const brow = race === 1 ? 0 : (n * 7) % 4;
398
- const mouth = [1, 3, 0, 1][n % 4];
399
- const lashes = cloth === 1 || cloth === 5 || (n % 5 === 2);
400
- const blush = lashes && n % 3 !== 0;
401
- const glasses = n % 19 === 0;
402
- const facial = 0;
403
- drawBody(buf, cloth, shirtRgb, accent, skin);
404
- drawLegs(buf, pants, shoe, race === 1);
405
- drawHead(buf, skin);
406
- drawFace(buf, skin, brow, mouth, blush, lashes);
407
- if (facial) drawFacial(buf, facial, hairc);
408
- HAIR_FNS[n % HAIR_FNS.length](buf, hi, base, sh, skin.base);
409
- if (glasses) drawGlasses(buf);
410
- if (race === 1) dwarfStout(buf, shirtRgb, skin);
411
- if (race === 2) elfEars(buf, skin);
412
- if (race === 3) demiEars(buf, skin);
413
- outlinePass(buf);
414
- return buf;
415
- }
416
-
417
- function drawBuddy(canvas, shirt, seed) {
418
- const ctx = canvas.getContext("2d");
419
- canvas.width = W;
420
- canvas.height = H;
421
- ctx.imageSmoothingEnabled = false;
422
- const img = ctx.createImageData(W, H);
423
- img.data.set(buddyPixels(shirt, seed));
424
- ctx.putImageData(img, 0, 0);
425
- }
426
-
427
- root.BUDDY_W = W;
428
- root.BUDDY_H = H;
429
- root.buddyFnv = fnv;
430
- root.buddyPixels = buddyPixels;
431
- root.drawBuddy = drawBuddy;
432
- })(typeof globalThis !== "undefined" ? globalThis : this);