@lewismoten/gamemaker-sandbox-engine 3.1.0 → 3.3.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.
Files changed (108) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/NOTICE.md +58 -753
  3. package/README.md +94 -10
  4. package/dist/assets/{music.worklet-NqOeNo6T.js → music.worklet-aD2x7RRM.js} +23 -21
  5. package/dist/audio/cmfLoad.js +10 -0
  6. package/dist/audio/cmfPlayer.js +201 -0
  7. package/dist/audio/context.js +75 -0
  8. package/dist/audio/engine.js +173 -0
  9. package/dist/audio/mix.js +40 -0
  10. package/dist/audio/opl.js +245 -0
  11. package/dist/audio/output.js +40 -0
  12. package/dist/core/gameFiles.js +89 -0
  13. package/dist/engine/character.js +187 -0
  14. package/dist/engine/funcKeys.js +164 -0
  15. package/dist/engine/game.js +133 -0
  16. package/dist/engine/keys.js +68 -0
  17. package/dist/engine/machine.js +192 -0
  18. package/dist/engine/menus.js +135 -0
  19. package/dist/engine/monsters.js +259 -0
  20. package/dist/engine/playGain.js +10 -0
  21. package/dist/engine/playerLook.js +48 -0
  22. package/dist/engine/recorder.js +127 -0
  23. package/dist/engine/render.js +45 -0
  24. package/dist/engine/scene.js +324 -0
  25. package/dist/engine/scroll.js +79 -0
  26. package/dist/engine/showGraphic.js +107 -0
  27. package/dist/engine/slowPc.js +98 -0
  28. package/dist/engine/slowPcMusic.js +46 -0
  29. package/dist/engine/touch.js +61 -0
  30. package/dist/engine/world.js +205 -0
  31. package/dist/formats/binary.js +120 -0
  32. package/dist/formats/blocks.js +103 -0
  33. package/dist/formats/character.js +83 -0
  34. package/dist/formats/cmf.js +37 -0
  35. package/dist/formats/cmfEdit.js +154 -0
  36. package/dist/formats/cmfPreview.js +89 -0
  37. package/dist/formats/cmfSong.js +190 -0
  38. package/dist/formats/fli.js +340 -0
  39. package/dist/formats/fliFrames.js +34 -0
  40. package/dist/formats/fliLimits.js +54 -0
  41. package/dist/formats/game.js +198 -0
  42. package/dist/formats/gif.js +125 -0
  43. package/dist/formats/gifProgressive.js +99 -0
  44. package/dist/formats/graphicScripts.js +44 -0
  45. package/dist/formats/highscore.js +30 -0
  46. package/dist/formats/jpeg.js +359 -0
  47. package/dist/formats/map.js +38 -0
  48. package/dist/formats/monster.js +69 -0
  49. package/dist/formats/palette.js +58 -0
  50. package/dist/formats/recording.js +17 -0
  51. package/dist/formats/sound.js +44 -0
  52. package/dist/formats/voc.js +303 -0
  53. package/dist/gfx/colorVision.js +45 -0
  54. package/dist/gfx/cp437Glyphs.js +337 -0
  55. package/dist/gfx/font8x8.js +10 -0
  56. package/dist/gfx/screen.js +151 -0
  57. package/dist/index.js +15 -0
  58. package/dist/input/chords.js +46 -0
  59. package/dist/input/deskMouse.js +24 -0
  60. package/dist/input/keyboard.js +82 -0
  61. package/dist/input/scancodes.js +143 -0
  62. package/dist/player/fileExtensions.js +118 -0
  63. package/dist/player/patchRules.js +129 -0
  64. package/dist/player/patchTable.js +1753 -0
  65. package/dist/text/cp437.js +44 -0
  66. package/dist/types/audio/cmfPlayer.d.ts +1 -1
  67. package/dist/types/audio/engine.d.ts +21 -0
  68. package/dist/types/audio/mix.d.ts +14 -0
  69. package/dist/types/audio/music.worklet.d.ts +8 -0
  70. package/dist/types/engine/character.d.ts +3 -3
  71. package/dist/types/engine/funcKeys.d.ts +8 -6
  72. package/dist/types/engine/game.d.ts +9 -4
  73. package/dist/types/engine/keys.d.ts +2 -2
  74. package/dist/types/engine/machine.d.ts +8 -4
  75. package/dist/types/engine/menus.d.ts +4 -4
  76. package/dist/types/engine/monsters.d.ts +1 -1
  77. package/dist/types/engine/playerLook.d.ts +20 -2
  78. package/dist/types/engine/recorder.d.ts +8 -1
  79. package/dist/types/engine/render.d.ts +2 -2
  80. package/dist/types/engine/scene.d.ts +41 -9
  81. package/dist/types/engine/scroll.d.ts +9 -1
  82. package/dist/types/engine/showGraphic.d.ts +2 -2
  83. package/dist/types/engine/slowPc.d.ts +64 -2
  84. package/dist/types/engine/slowPcMusic.d.ts +18 -0
  85. package/dist/types/engine/touch.d.ts +2 -2
  86. package/dist/types/engine/world.d.ts +28 -6
  87. package/dist/types/formats/cmfEdit.d.ts +53 -0
  88. package/dist/types/formats/cmfPreview.d.ts +19 -0
  89. package/dist/types/formats/cmfSong.d.ts +74 -0
  90. package/dist/types/formats/fli.d.ts +11 -0
  91. package/dist/types/formats/fliFrames.d.ts +18 -0
  92. package/dist/types/formats/fliLimits.d.ts +13 -0
  93. package/dist/types/formats/game.d.ts +7 -0
  94. package/dist/types/formats/gif.d.ts +1 -1
  95. package/dist/types/formats/gifProgressive.d.ts +46 -0
  96. package/dist/types/formats/jpeg.d.ts +20 -0
  97. package/dist/types/gfx/colorVision.d.ts +26 -0
  98. package/dist/types/gfx/screen.d.ts +4 -0
  99. package/dist/types/index.d.ts +4 -0
  100. package/dist/types/input/keyboard.d.ts +1 -1
  101. package/dist/types/{dosPlayer → player}/patchRules.d.ts +1 -1
  102. package/dist/types/{dosPlayer → player}/patchTable.d.ts +8 -5
  103. package/dist/types/text/cp437.d.ts +6 -0
  104. package/package.json +322 -9
  105. package/dist/engine.js +0 -5436
  106. package/dist/types/engine/package.d.ts +0 -4
  107. /package/dist/types/{project → core}/gameFiles.d.ts +0 -0
  108. /package/dist/types/{dosPlayer → player}/fileExtensions.d.ts +0 -0
@@ -0,0 +1,192 @@
1
+ import { Screen as d } from "../gfx/screen.js";
2
+ import { Keyboard as m } from "../input/keyboard.js";
3
+ import { listenDeskMouse as u, Mickeys as p } from "../input/deskMouse.js";
4
+ import { AudioEngine as y } from "../audio/engine.js";
5
+ import { PALETTE_SIZE as c } from "../formats/palette.js";
6
+ const w = 6;
7
+ class k extends Error {
8
+ constructor() {
9
+ super("Game aborted");
10
+ }
11
+ }
12
+ class E {
13
+ screen;
14
+ keyboard = new m();
15
+ audio;
16
+ files;
17
+ pointer = { x: 160, y: 100, clicks: 0 };
18
+ aborted = !1;
19
+ /** Observer only (the walkthrough player's item marks): a picture, cartoon, text page or slide list is about to be shown. Never changes timing. */
20
+ onItem;
21
+ frameWaiters = [];
22
+ raf = 0;
23
+ /** The ball mouse on the desk moves the pointer and clicks too. */
24
+ offDeskMouse;
25
+ /** The engine was made here (not passed in): it goes with the Machine. */
26
+ ownsAudio;
27
+ constructor(t, e, i, s = {}) {
28
+ if (this.screen = new d(t), this.files = e, this.ownsAudio = !i, this.audio = i ?? new y(), s.input === !1 ? (this.offDeskMouse = () => {
29
+ }, this.keyboard.attach = this.keyboard.detach = () => {
30
+ }) : this.listen(t), s.frames === "manual") return;
31
+ const o = () => {
32
+ this.presentFrame(), this.raf = requestAnimationFrame(o);
33
+ };
34
+ this.raf = requestAnimationFrame(o);
35
+ }
36
+ listen(t) {
37
+ t.addEventListener("pointerdown", this.onPointer), t.addEventListener("pointermove", this.onMove);
38
+ const e = new p();
39
+ let i = 0;
40
+ this.offDeskMouse = u((s, o, r) => {
41
+ const [h, a] = e.take(s, o);
42
+ this.pointer.x = Math.max(0, Math.min(319, this.pointer.x + h)), this.pointer.y = Math.max(0, Math.min(199, this.pointer.y + a)), r & ~i && (this.pointer.clicks++, this.audio.resume()), i = r;
43
+ });
44
+ }
45
+ /** The time in ms the game goes by (waits, fades, animations, the game clock). */
46
+ now() {
47
+ return performance.now();
48
+ }
49
+ /** One display frame: the screen is shown (unless `show` is false) and everything waiting for a frame goes on. */
50
+ presentFrame(t = !0) {
51
+ t && this.screen.present();
52
+ const e = this.frameWaiters;
53
+ this.frameWaiters = [], e.forEach((i) => i());
54
+ }
55
+ /** How many are waiting for the next frame (a stepped Machine's game is idle when one is). */
56
+ get frameWaiting() {
57
+ return this.frameWaiters.length;
58
+ }
59
+ toScreen(t) {
60
+ const e = this.screen.canvas.getBoundingClientRect();
61
+ this.pointer.x = Math.floor((t.clientX - e.left) / e.width * 320), this.pointer.y = Math.floor((t.clientY - e.top) / e.height * 200);
62
+ }
63
+ onPointer = (t) => {
64
+ this.toScreen(t), this.pointer.clicks++, this.audio.resume();
65
+ };
66
+ onMove = (t) => this.toScreen(t);
67
+ destroy() {
68
+ this.aborted = !0, this.raf && cancelAnimationFrame(this.raf), this.keyboard.detach(), this.ownsAudio ? this.audio.dispose() : this.audio.stopAll(), this.screen.canvas.removeEventListener("pointerdown", this.onPointer), this.screen.canvas.removeEventListener("pointermove", this.onMove), this.offDeskMouse();
69
+ const t = this.frameWaiters;
70
+ this.frameWaiters = [], t.forEach((e) => e());
71
+ }
72
+ /** Told when the game waits for files still on their way (true) and when they are in. */
73
+ onLoading;
74
+ /**
75
+ * Waits for game files still on their way from the site (a hosted game starts before
76
+ * all its files are in, project/streamGame.ts); a short wait shows no cue. Names the
77
+ * game doesn't have, or that are in already, return at once.
78
+ */
79
+ async need(...t) {
80
+ const e = this.files.stream?.need(t.filter((s) => !!s));
81
+ if (!e) return;
82
+ const i = setTimeout(() => this.onLoading?.(!0), 150);
83
+ try {
84
+ await e;
85
+ } finally {
86
+ clearTimeout(i), this.onLoading?.(!1);
87
+ }
88
+ this.polledAt = this.now(), this.checkAbort();
89
+ }
90
+ /** Fetches these game files next, if they are still on their way, without waiting. */
91
+ want(...t) {
92
+ this.files.stream?.want(t.filter((e) => !!e));
93
+ }
94
+ checkAbort() {
95
+ if (this.aborted) throw new k();
96
+ }
97
+ /** Waits for the next animation frame (the screen is presented every frame). */
98
+ frame() {
99
+ return this.checkAbort(), this.pollKeys(), new Promise((t) => this.frameWaiters.push(t)).then(() => this.checkAbort());
100
+ }
101
+ async sleep(t) {
102
+ const e = this.now() + t;
103
+ for (; this.now() < e; ) await this.frame();
104
+ }
105
+ takeClick() {
106
+ return this.pointer.clicks ? (this.pointer.clicks = 0, !0) : !1;
107
+ }
108
+ /**
109
+ * PauseTimeKey: waits up to `seconds` (forever if omitted) for a key or click.
110
+ * Returns the key, a pseudo key for a click (ascii 1, as the C returned 1 for a mouse
111
+ * button; scan 28 is Enter's), or undefined on time out (the C returned FALSE).
112
+ */
113
+ async pauseTimeKey(t = 1 / 0) {
114
+ const e = this.now() + t * 1e3;
115
+ return this.takeClick(), this.waiting(async () => {
116
+ for (; ; ) {
117
+ const i = this.keyboard.readKey();
118
+ if (i) return i;
119
+ if (this.takeClick()) return { scan: 28, ascii: 1, key: "" };
120
+ if (this.now() >= e) return;
121
+ await this.frame();
122
+ }
123
+ });
124
+ }
125
+ waitDepth = 0;
126
+ polledAt = 0;
127
+ /**
128
+ * Runs `fn` as PLAYGAME code that read keys through GetKey (key waits, pictures,
129
+ * animations, text pages): while it runs, each frame hands the demo recorder the polls
130
+ * the DOS PC would have made meanwhile (keyPoll). Gameplay itself stole the keyboard
131
+ * interrupt and never called GetKey, so it does not count.
132
+ */
133
+ async waiting(t) {
134
+ this.waitDepth++ === 0 && (this.polledAt = this.now());
135
+ try {
136
+ return await t();
137
+ } finally {
138
+ if (--this.waitDepth === 0 && this.keyPollEnd) for (const e of this.keyPollEnd()) this.keyboard.feed(e);
139
+ }
140
+ }
141
+ pollKeys() {
142
+ if (!this.keyPoll || this.waitDepth === 0) return;
143
+ const t = this.now(), e = Math.max(1, Math.round((t - this.polledAt) * w));
144
+ this.polledAt = t;
145
+ for (const i of this.keyPoll(e)) this.keyboard.feed(i);
146
+ }
147
+ /**
148
+ * Demo playback: called while a screen waits for a key with how many GetKey polls the
149
+ * DOS PC would have made meanwhile; returns recorded keys that become pending.
150
+ */
151
+ keyPoll;
152
+ /** Demo playback: a key-reading screen ended; returns recorded keys it must have taken. */
153
+ keyPollEnd;
154
+ /** Demo playback: one GetKey poll by a screen (tick-counted recordings); returns the recorded keys now due. */
155
+ keyPollOnce;
156
+ /** Clears keyboard input (while (GetKey(1)) GetKey(0)). */
157
+ flushKeys() {
158
+ this.keyboard.clear(), this.pointer.clicks = 0;
159
+ }
160
+ /**
161
+ * FadeTo: 65 retrace-synchronized steps from the current palette to `dest`. The C
162
+ * waited for one VGA vertical retrace (70 Hz in mode 13h) per step, hence steps/70 s;
163
+ * it stepped each channel Bresenham-style, which the truncated d*step/steps matches
164
+ * at every step.
165
+ */
166
+ async fadeTo(t, e = 65) {
167
+ if (e <= 0) {
168
+ this.screen.setPalette(t);
169
+ return;
170
+ }
171
+ const i = this.screen.palette.slice(), s = this.now(), o = e / 70 * 1e3;
172
+ for (; ; ) {
173
+ const r = Math.min(1, (this.now() - s) / o), h = Math.floor(r * e), a = new Uint8Array(c);
174
+ for (let n = 0; n < c; n++) {
175
+ const f = (t[n] ?? 0) - i[n];
176
+ a[n] = i[n] + Math.trunc(f * h / e);
177
+ }
178
+ if (this.screen.setPalette(a), r >= 1) break;
179
+ await this.frame();
180
+ }
181
+ this.screen.setPalette(t);
182
+ }
183
+ async fadeAllTo(t, e, i, s = 65) {
184
+ const o = new Uint8Array(c);
185
+ for (let r = 0; r < 256; r++) o.set([t, e, i], r * 3);
186
+ await this.fadeTo(o, s);
187
+ }
188
+ }
189
+ export {
190
+ k as GameAborted,
191
+ E as Machine
192
+ };
@@ -0,0 +1,135 @@
1
+ import { STOCK_LOOK as m } from "./playerLook.js";
2
+ import { placeFor as p, insertHighScore as b, serializeHighScores as M, parseHighScores as K } from "../formats/highscore.js";
3
+ import { PALETTE_SIZE as F } from "../formats/palette.js";
4
+ async function P(t, e, n, i, a, c, u = 1 / 0, r = 1, o = !0, f = 5) {
5
+ const s = (l) => n - 8 + l * i;
6
+ let w = t.screen.getCol(e, s(r));
7
+ o ? t.flushKeys() : t.takeClick();
8
+ let g = t.now();
9
+ for (; ; ) {
10
+ t.screen.boxFill(e, s(r), e + f, s(r) + 4, c);
11
+ const l = t.keyboard.readKey();
12
+ let h = 0;
13
+ if (t.takeClick()) {
14
+ const d = Math.floor((t.pointer.y - (n - 8) + i / 2) / i);
15
+ if (d >= 1 && d <= a)
16
+ return t.screen.boxFill(e, s(r), e + f, s(r) + 4, w), d;
17
+ }
18
+ if (l) {
19
+ if (g = t.now(), l.ascii === 13) return r;
20
+ if (l.ascii === 27) return 0;
21
+ l.scan === 72 && (h = -1), l.scan === 80 && (h = 1);
22
+ } else if (t.now() - g > u * 1e3) return a + 1;
23
+ h && (t.screen.boxFill(e, s(r), e + f, s(r) + 4, w), r += h, r < 1 && (r = a), r > a && (r = 1), w = t.screen.getCol(e, s(r))), await t.frame();
24
+ }
25
+ }
26
+ async function C(t, e, n, i, a, c, u) {
27
+ let r = c.slice(0, u);
28
+ t.screen.write(e, n, i, r), t.flushKeys();
29
+ const o = (f) => {
30
+ const s = r.length;
31
+ s < u ? t.screen.box(e + s * 8, n, e + (s + 1) * 8 - 2, n + 7, f) : t.screen.line(e + s * 8 - 1, n, e + s * 8 - 1, n + 7, f);
32
+ };
33
+ for (; ; ) {
34
+ const f = Math.floor(t.now() / 450) % 2 === 0;
35
+ o(f ? i : a);
36
+ const s = t.keyboard.readKey();
37
+ if (!s) {
38
+ await t.frame();
39
+ continue;
40
+ }
41
+ if (o(a), s.ascii === 27) return null;
42
+ if (s.ascii === 13) return r;
43
+ s.ascii === 8 || s.scan === 75 ? r.length && (r = r.slice(0, -1), t.screen.boxFill(e + r.length * 8, n, e + (r.length + 1) * 8 - 1, n + 7, a)) : s.ascii >= 32 && s.ascii < 256 && r.length < u && (r += String.fromCharCode(s.ascii), t.screen.write(e, n, i, r));
44
+ }
45
+ }
46
+ function H(t = Math.random) {
47
+ const e = new Uint8Array(F), n = 2;
48
+ let [i, a, c] = [0, 0, 0], [u, r, o] = [0, 0, 0];
49
+ const f = () => Math.floor(t() * 2);
50
+ for (let s = 0; s < 256; s++) {
51
+ if (s % (64 / n) === 0)
52
+ do
53
+ o === 0 && (o = f()), r === 0 && (r = f()), u === 0 && (u = f());
54
+ while (o === 0 && r === 0 && u === 0);
55
+ u === 1 && (i += n), r === 1 && (a += n), o === 1 && (c += n), u === 2 && (i -= n), r === 2 && (a -= n), o === 2 && (c -= n), i >= 63 && ([u, i] = [2, 63]), c >= 63 && ([o, c] = [2, 63]), a >= 63 && ([r, a] = [2, 63]), i < 0 && ([i, u] = [0, 0]), a < 0 && ([a, r] = [0, 0]), c < 0 && ([c, o] = [0, 0]), e.set([i, a, c], s * 3);
56
+ }
57
+ return e;
58
+ }
59
+ function Y(t, e, n = Math.random) {
60
+ t.screen.clear(), e.set(H(n)), t.screen.setPalette(e);
61
+ for (let i = 0; i <= 100; i++) t.screen.box(40 - Math.trunc(i * 4 / 10), 100 - i, 280 + Math.trunc(i * 4 / 10), 180 + Math.trunc(i * 2 / 10), i);
62
+ }
63
+ function y(t) {
64
+ return `${t}.his`;
65
+ }
66
+ function S(t, e) {
67
+ const n = t.files.get(y(e));
68
+ return n ? K(n) : Array.from({ length: 10 }, () => ({ score: 0, name: "" }));
69
+ }
70
+ function A(t, e, n, i) {
71
+ const a = e.color(n, "color.select.menu");
72
+ t.write(e.num("layout.menu.titleX"), e.num("layout.menu.titleY"), a, i);
73
+ for (const c of N) t.write(e.num(`layout.menu.${c}.x`), e.num(`layout.menu.${c}.y`), a, e.text(`str.menu.${c}`));
74
+ return a;
75
+ }
76
+ const N = ["play", "instructions", "storyline", "credits", "highScores", "quit"];
77
+ function R(t) {
78
+ return {
79
+ x: t.num("layout.menu.markerX"),
80
+ y: t.num("layout.menu.firstY"),
81
+ dy: t.num("layout.menu.spacing"),
82
+ idle: t.seconds("timing.menu.idleSeconds"),
83
+ width: t.num("border.marker.width")
84
+ };
85
+ }
86
+ function _(t, e, n, i) {
87
+ t.write(
88
+ e.num("layout.menu.noFile.x"),
89
+ e.num("layout.menu.noFile.y"),
90
+ e.color(n, "color.select.menuMessages"),
91
+ e.text(`str.menu.${i}`)
92
+ );
93
+ }
94
+ function $(t, e, n, i, a) {
95
+ const c = e.color(n, "color.select.hsTitle"), u = e.color(n, "color.select.hsRows");
96
+ t.write(e.num("layout.hiscore.title.x"), e.num("layout.hiscore.title.y"), c, e.text("str.hiscore.title"));
97
+ let r = e.num("layout.hiscore.rowSpacing"), o = e.num("layout.hiscore.firstRowY");
98
+ const f = e.num("layout.hiscore.rows");
99
+ for (let s = 0; s < f; s++)
100
+ i[s].score !== 0 && t.write(20, o, u, `${String(i[s].score).padStart(10)} ${i[s].name}`), o += r, s % 2 === 0 && r--, r--;
101
+ a > 0 && t.write(20, o, u, e.format("str.hiscore.latest", a)), t.write(e.num("layout.hiscore.anyKey.x"), e.num("layout.hiscore.anyKey.y"), c, e.text("str.hiscore.anyKey"));
102
+ }
103
+ async function v(t, e, n, i = -1, a = m) {
104
+ await t.need(y(e));
105
+ const c = S(t, e);
106
+ t.screen.setPalette(n), $(t.screen, a, n, c, i), await t.pauseTimeKey(a.seconds("timing.highScores"));
107
+ }
108
+ function x(t, e, n, i) {
109
+ const a = e.color(n, "color.select.hsPrompt"), c = e.color(n, "color.select.hsName");
110
+ return t.write(e.num("layout.hiscore.congrats.x"), e.num("layout.hiscore.congrats.y"), a, e.text("str.hiscore.congrats")), t.write(0, 100, c, e.format("str.hiscore.place", i)), t.write(e.num("layout.hiscore.enterName.x"), e.num("layout.hiscore.enterName.y"), a, e.text("str.hiscore.enterName")), c;
111
+ }
112
+ async function D(t, e, n, i, a = m) {
113
+ await t.need(y(e));
114
+ const c = S(t, e), u = p(c, i);
115
+ let r = 0, o = c;
116
+ if (u >= 0) {
117
+ const f = x(t.screen, a, n, u + 1), s = await C(t, 136, 120, f, 0, "", 22) ?? "";
118
+ o = b(c, u, { score: i, name: s }), r = u + 1;
119
+ }
120
+ return t.files.set(y(e), M(o)), r;
121
+ }
122
+ export {
123
+ D as checkHighScores,
124
+ Y as drawDefaultScreen,
125
+ $ as drawHighScores,
126
+ A as drawMenu,
127
+ x as drawNewHighScore,
128
+ _ as drawNoFile,
129
+ C as gGet,
130
+ P as gVertMenu,
131
+ y as highScoreFile,
132
+ R as menuMarker,
133
+ S as readHighScores,
134
+ v as showHighScores
135
+ };
@@ -0,0 +1,259 @@
1
+ import { BACKBL as tr, BLEN as i, MONBL as k, TRANSPARENT as p, CHARBL as Y, SOLRIG as C, SOLLEF as R, SOLBOT as F, SOLTOP as D } from "../formats/blocks.js";
2
+ import { LASTMON as N, LASTSL as O, ATTACKMOVEMENT as A, MAXMARCH as X, NORMALMOVEMENT as S } from "../formats/monster.js";
3
+ import { chrFrame as cr } from "./keys.js";
4
+ import { onscrn as or, doBlockTouchChar as nr, doSound as H, KILLSOUND as V } from "./touch.js";
5
+ import { SCRNBLEN as _, SCRNBWID as j, mapBlock as v, MONMOVESPEED as q, random as E, mapMonAt as J, setMapMon as Q, OFFSCRN as T, CHARPOWER as er, sign as m, shownBlock as fr } from "./world.js";
6
+ import { LASTMM as b, MWID as h, MLEN as d } from "../formats/map.js";
7
+ const sr = { x: 0, y: 0, pic: 0, orient: 0 };
8
+ function P(r, o, n) {
9
+ return n >= 0 ? r.march[o]?.[n] ?? sr : o === 1 ? r.march[0][X - 1] : { x: r.end, y: r.towards, pic: r.close[0], orient: r.close[1] };
10
+ }
11
+ function w(r) {
12
+ r.delta = { x: 0, y: 0 }, r.scrPos = { x: T, y: T }, r.oldPos = { ...r.scrPos }, r.picDrawn = !1, r.curx[1] = 0, r.cury[1] = 0, r.curPic = -1, r.offl = -1, r.offs = 0, r.curMarch = S, r.orient = 0, r.dest = 0;
13
+ }
14
+ function W(r, o) {
15
+ const n = r.mi[o];
16
+ if (n.curPic >= 0 && n.curPic < O) {
17
+ const f = r.mon[r.mm[o].monnum]?.pic[n.curPic][0] ?? k;
18
+ return f < k && f >= 0 ? f : k;
19
+ }
20
+ return k;
21
+ }
22
+ function ir(r, o) {
23
+ const n = or(r, o.curx[0], o.cury[0], o.scrPos);
24
+ return n && (o.scrPos.x += o.curx[1], o.scrPos.y += o.cury[1]), n;
25
+ }
26
+ function I(r, o, n) {
27
+ let c = o - r.curx[0], f = n - r.cury[0];
28
+ c > d / 2 && (c -= d), c < -d / 2 && (c += d), f > h / 2 && (f -= h), f < -h / 2 && (f += h), r.delta = { x: c * i, y: f * i };
29
+ }
30
+ function B(r, o) {
31
+ const n = { x: 0, y: 0 }, c = Math.abs(r.delta.x), f = Math.abs(r.delta.y);
32
+ if (c >= f)
33
+ for (let e = 0; e < o; e++) {
34
+ if (r.offl >= c) {
35
+ r.offl = -1;
36
+ break;
37
+ }
38
+ r.offl++, n.x += m(r.delta.x), r.offs += f, r.offs >= c && (r.offs -= c, n.y += m(r.delta.y));
39
+ }
40
+ else
41
+ for (let e = 0; e < o; e++) {
42
+ if (r.offl >= f) {
43
+ r.offl = -1;
44
+ break;
45
+ }
46
+ r.offl++, r.offs += c, n.y += m(r.delta.y), r.offs >= f && (r.offs -= f, n.x += m(r.delta.x));
47
+ }
48
+ return n;
49
+ }
50
+ function z(r) {
51
+ r.y < 0 ? r.y += h : r.y >= h && (r.y -= h), r.x < 0 ? r.x += d : r.x >= d && (r.x -= d);
52
+ }
53
+ const L = (r, o, n) => fr(r, v(r, o, n)).solid;
54
+ function Z(r, o, n, c) {
55
+ let f, e;
56
+ o.curx[1] + n.x < 0 ? (c.x--, f = C, e = 1) : (c.x++, f = R, e = 3), z(c);
57
+ let t = L(r, c.x, c.y);
58
+ return o.cury[1] + n.y > i / 4 && (t |= L(r, c.x, (c.y + 1) % h)), o.cury[1] + n.y < -i / 4 && (t |= L(r, c.x, (c.y - 1 + h) % h)), t & f ? (n.x = -o.curx[1], c.x += e === 1 ? 1 : -1, !0) : !1;
59
+ }
60
+ function $(r, o, n, c) {
61
+ let f, e;
62
+ o.cury[1] + n.y < 0 ? (c.y--, f = F, e = 1) : (c.y++, f = D, e = 3), z(c);
63
+ let t = L(r, c.x, c.y);
64
+ return o.curx[1] + n.x > i / 4 && (t |= L(r, (c.x + 1) % d, c.y)), o.curx[1] + n.x < -i / 4 && (t |= L(r, (c.x - 1 + d) % d, c.y)), t & f ? (n.y = -o.cury[1], c.y += e === 1 ? 1 : -1, !0) : !1;
65
+ }
66
+ function ur(r, o, n) {
67
+ const c = { x: o.curx[0], y: o.cury[0] };
68
+ let f = !1;
69
+ return Math.abs(n.x) > Math.abs(n.y) ? (f = Z(r, o, n, c) || f, n.y && (f = $(r, o, n, c) || f)) : (n.y && (f = $(r, o, n, c) || f), n.x && (f = Z(r, o, n, c) || f)), f;
70
+ }
71
+ function lr(r, o) {
72
+ const n = r.mi[o];
73
+ return Math.abs(n.curx[0] - r.chr.x[0]) < r.tune.attackX && Math.abs(n.cury[0] - r.chr.y[0]) < r.tune.attackY;
74
+ }
75
+ function G(r, o, n, c, f) {
76
+ if (o >= b) {
77
+ let e = r.firstEmptyMM;
78
+ for (let t = 0; t <= b; t++) {
79
+ if (e >= 0 && e < b && r.mm[e].monnum === N) {
80
+ o = e;
81
+ break;
82
+ }
83
+ e++, e >= b && (e = 0);
84
+ }
85
+ r.firstEmptyMM = Math.max(0, e);
86
+ }
87
+ if (o < b && o >= 0) {
88
+ r.mm[o].monnum = n & 255;
89
+ const e = r.mi[o];
90
+ return e.birthTime = r.clock, e.nextAni = r.clock, e.nextMove = r.clock, e.curx[0] = c, e.cury[0] = f, e.target = { x: c, y: f }, o;
91
+ }
92
+ return b;
93
+ }
94
+ function g(r, o) {
95
+ const n = r.mon[r.mm[o].monnum];
96
+ if (!n || n.end === -2) return !1;
97
+ if (n.newmon === N || n.newmon < 0)
98
+ return r.mm[o].monnum = N, o < r.firstEmptyMM && (r.firstEmptyMM = Math.max(0, o - 1)), !0;
99
+ const c = r.mi[o];
100
+ return G(r, o, n.newmon, c.curx[0], c.cury[0]), c.offl = -1, c.curMarch = S, c.dest = 0, c.curPic = 0, c.fromchar > 0 && c.fromchar++, !1;
101
+ }
102
+ function gr(r) {
103
+ r.birthFlag.fill(0);
104
+ for (const o of r.blkMon)
105
+ o.nexttime <= r.clock && (o.nexttime += r.bg[o.blnum].birthTime, r.birthFlag[o.blnum] = 1);
106
+ for (let o = r.mx - _ / 2; o < r.mx + _ * 3 / 2; o++)
107
+ for (let n = r.my - j / 2; n < r.my + j * 3 / 2; n++) {
108
+ const c = (o + d) % d, f = (n + h) % h, e = r.blkmap[v(r, c, f)] ?? tr;
109
+ if (!r.birthFlag[e]) continue;
110
+ const t = G(r, b, r.bg[e].birthMon, c, f);
111
+ t < b && (r.mi[t].fromchar = 0, w(r.mi[t]));
112
+ }
113
+ }
114
+ function Pr(r, o, n, c) {
115
+ const f = G(r, b, c, o, n);
116
+ if (f >= b) return;
117
+ const e = r.mi[f];
118
+ w(e), e.fromchar = 1, e.curx[1] = r.chr.x[1], e.cury[1] = r.chr.y[1], e.offl = -1;
119
+ const t = r.mon[c & 255];
120
+ if (t && t.towards < 64) {
121
+ const { netx: u, nety: x } = r.ci;
122
+ e.delta = { x: u * i, y: x * i }, Math.abs(u) - Math.abs(x) > 0 ? e.orient = u < 0 ? 4 : 0 : e.orient = x < 0 ? 3 : 1;
123
+ }
124
+ }
125
+ function ar(r, o, n) {
126
+ const c = r.mi[o], f = r.mon[n];
127
+ if (c.dest === X || P(f, c.curMarch, c.dest).pic === 0) {
128
+ if (f.end === -1 && c.curMarch === S && g(r, o)) return !0;
129
+ c.dest = 0, c.curMarch = S;
130
+ }
131
+ const e = P(f, c.curMarch, c.dest), t = { x: e.x + c.curx[0], y: e.y + c.cury[0] };
132
+ if (c.dest !== 0) {
133
+ const u = P(f, c.curMarch, c.dest - 1);
134
+ t.x -= u.x, t.y -= u.y;
135
+ }
136
+ return c.orient = e.orient, z(t), c.target = t, I(c, t.x, t.y), c.offl = 0, c.offs = 0, c.dest++, !1;
137
+ }
138
+ function K(r, o, n, c, f, e) {
139
+ const t = Math.abs(c - r), u = Math.abs(f - o);
140
+ if (c -= t, r -= t, f -= u, o -= u, t > i || u > i) return !1;
141
+ const x = (l) => l >= 0 && l < n.length ? n[l] : p, M = (l) => l >= 0 && l < e.length ? e[l] : p;
142
+ let s, a;
143
+ if (c >= r && f >= o) {
144
+ s = i * u, a = 0;
145
+ for (let l = 0; l < o + i - f; l++) {
146
+ s += t;
147
+ for (let y = 0; y < r + i - c; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
148
+ a += t;
149
+ }
150
+ return !1;
151
+ }
152
+ if (c >= r && f <= o) {
153
+ s = 0, a = u * i;
154
+ for (let l = 0; l < f + i - o; l++) {
155
+ s += t;
156
+ for (let y = 0; y < r + i - c; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
157
+ a += t;
158
+ }
159
+ return !1;
160
+ }
161
+ if (c <= r && f >= o) {
162
+ a = 0, s = u * i;
163
+ for (let l = 0; l < o + i - f; l++) {
164
+ a += t;
165
+ for (let y = 0; y < c + i - r; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
166
+ s += t;
167
+ }
168
+ return !1;
169
+ }
170
+ a = i * u, s = 0;
171
+ for (let l = 0; l < f + i - o; l++) {
172
+ a += t;
173
+ for (let y = 0; y < c + i - r; y++, s++, a++) if (x(s) !== p && M(a) !== p) return !0;
174
+ s += t;
175
+ }
176
+ return !1;
177
+ }
178
+ function xr(r, o) {
179
+ const n = r.mi[o], { ci: c } = r;
180
+ if (n.scrPos.x === T) return !1;
181
+ const f = Math.min(n.scrPos.x, c.scrx), e = Math.min(n.scrPos.y, c.scry), t = { x: c.scrx - f, y: c.scry - e }, u = { x: n.scrPos.x - f, y: n.scrPos.y - e }, x = { x: Math.max(t.x, u.x), y: Math.max(t.y, u.y) };
182
+ let M = !1;
183
+ if (u.x <= t.x + i && u.x + i >= t.x && u.y <= t.y + i && u.y + i * 2 >= t.y) {
184
+ let s = W(r, o);
185
+ if (s >= k) return !1;
186
+ const a = cr(r), l = r.mblk[s].pixels;
187
+ a.pic2 < Y && (M = K(t.x, t.y, r.cblk[a.pic2].pixels, u.x, u.y, l)), a.pic1 < Y && (M = K(t.x, t.y, r.cblk[a.pic1].pixels, u.x, u.y + i, l) || M), M && (s = r.mblk[s].solid, s > 0 && (x.x >= x.y ? r.monsolid |= t.x === 0 ? C & s : R & s : r.monsolid |= t.y === 0 ? F & s : D & s, r.mmSolid = o)), r.monsolid & C && r.monsolid & R && (r.monsolid |= t.y === 0 ? F & s : D & s), r.monsolid & F && r.monsolid & D && (r.monsolid |= t.x === 0 ? C & s : R & s);
188
+ }
189
+ return M;
190
+ }
191
+ function yr(r, o, n, c) {
192
+ const f = r.mm[o].monnum, e = r.mm[n].monnum;
193
+ if (f >= N || e >= N) return n;
194
+ const t = r.mon[f], u = r.mon[e];
195
+ if (t.power === u.power) return n;
196
+ const x = c & 1 ? i : 0, M = c & 2 ? i : 0, s = W(r, o);
197
+ if (s >= k) return n;
198
+ const a = W(r, n);
199
+ if (a >= k) return o;
200
+ const l = r.mi[o], y = r.mi[n];
201
+ return K(l.curx[1] + x, l.cury[1] + M, r.mblk[s].pixels, y.curx[1], y.cury[1], r.mblk[a].pixels) ? t.power < u.power ? (g(r, o), y.fromchar > 0 ? (r.ci.score += t.upscore, H(r, V), g(r, n), b) : n) : (g(r, n), l.fromchar > 0 ? (r.ci.score += u.upscore, H(r, V), g(r, o), b) : o) : n;
202
+ }
203
+ function Ar(r) {
204
+ const { clock: o, chr: n } = r;
205
+ for (let c = 0; c < b; c++) {
206
+ const f = r.mm[c].monnum;
207
+ if (f >= N) continue;
208
+ const e = r.mon[f], t = r.mi[c];
209
+ if (!e || (o >= t.nextAni && (t.curPic++, (t.curPic >= O || e.pic[t.curPic][0] >= k) && (t.curPic = e.pic[0][0] < k ? 0 : O), t.nextAni = t.curPic < O ? o + e.pic[t.curPic][1] : o + 1e5), o < t.nextMove)) continue;
210
+ const u = Math.trunc((o - t.nextMove + 1) / q);
211
+ t.nextMove = o + q, e.activate !== 0 && t.curMarch !== A && lr(r, c) && (t.curMarch = A, t.dest = 1);
212
+ let x;
213
+ if (t.curMarch === A && e.activate === 2) {
214
+ const l = P(e, A, t.dest);
215
+ t.target = { x: (l.x + n.x[0] + d) % d, y: (l.y + n.y[0] + h) % h }, I(t, t.target.x, t.target.y), t.offl = 0, x = B(t, l.pic * u), t.offl === -1 && (t.dest++, t.offs = 0, t.dest === X || P(e, A, t.dest).pic === 0 ? (t.curMarch = S, t.dest = 0) : t.orient = P(e, A, t.dest).orient);
216
+ } else if (e.towards === 0) {
217
+ if (t.offl === -1 && ar(r, c, f)) continue;
218
+ x = B(t, P(e, t.curMarch, t.dest - 1).pic * u);
219
+ } else e.towards < 64 ? (t.fromchar || (I(t, n.x[0], n.y[0]), t.delta.x += n.x[1] - t.curx[1], t.delta.y += n.y[1] - t.cury[1], e.towards < 0 && (t.delta = { x: -t.delta.x, y: -t.delta.y }), t.delta.x < 0 ? t.orient |= 4 : t.orient = 0), x = B(t, Math.abs(e.towards) * u)) : (t.curx[0] === t.target.x && t.cury[0] === t.target.y && (E(r, 2) ? t.target.x = (t.target.x + E(r, 7) + 5) % d : (t.target.x -= E(r, 7) + 5, t.target.x < 0 && (t.target.x += d)), E(r, 2) ? t.target.y = (t.target.y + E(r, 7) + 5) % h : (t.target.y -= E(r, 7) + 5, t.target.y < 0 && (t.target.y += h)), I(t, t.target.x, t.target.y), t.offl = 0, t.offs = 0), x = B(t, (e.towards >> 6) * u));
220
+ if (e.thru && ur(r, t, x) && t.fromchar > 0 && g(r, c)) continue;
221
+ for (x.x === 0 && x.y === 0 ? t.target = { x: t.curx[0], y: t.cury[0] } : (t.curx[1] += x.x, t.cury[1] += x.y), J(r, t.curx[0], t.cury[0]) === c && Q(r, t.curx[0], t.cury[0], b); t.curx[1] >= i; )
222
+ t.curx[1] -= i, t.curx[0]++;
223
+ for (; t.curx[1] < 0; )
224
+ t.curx[1] += i, t.curx[0]--;
225
+ for (; t.cury[1] >= i; )
226
+ t.cury[1] -= i, t.cury[0]++;
227
+ for (; t.cury[1] < 0; )
228
+ t.cury[1] += i, t.cury[0]--;
229
+ if (t.curx[0] < 0 && (t.curx[0] += d), t.cury[0] < 0 && (t.cury[0] += h), t.curx[0] >= d && (t.curx[0] -= d), t.cury[0] >= h && (t.cury[0] -= h), ir(r, t) || (t.scrPos = { x: T, y: T }), t.curPic >= 0 && t.curPic < O && xr(r, c) && t.fromchar !== 1) {
230
+ const l = W(r, c), y = nr(r, r.mblk[l]) - 1;
231
+ if (r.mon[r.mm[c].monnum]?.power < er && g(r, c)) {
232
+ y || H(r, V);
233
+ continue;
234
+ }
235
+ }
236
+ let M = c;
237
+ const s = t.curx[0], a = t.cury[0];
238
+ for (const [l, y, rr] of [
239
+ [0, 0, 0],
240
+ [1, 0, 1],
241
+ [1, 1, 3],
242
+ [0, 1, 2]
243
+ ]) {
244
+ const U = J(r, s + l, a + y);
245
+ U < b && (M = yr(r, U, c, rr));
246
+ }
247
+ M < b && Q(r, r.mi[M].curx[0], r.mi[M].cury[0], M), e.end > 0 && t.birthTime + e.end <= o && g(r, c);
248
+ }
249
+ }
250
+ export {
251
+ G as birthMon,
252
+ gr as blockBirthMonsters,
253
+ ir as calcDraw,
254
+ Pr as charBirthMon,
255
+ W as monPicNum,
256
+ Ar as moveAllMonsters,
257
+ K as picChkTouch,
258
+ w as resetMonInfo
259
+ };
@@ -0,0 +1,10 @@
1
+ const t = () => ({ banked: 0, base: 0 });
2
+ function b(a, n, e) {
3
+ a.banked += Math.max(0, n - a.base), a.base = e;
4
+ }
5
+ const s = (a, n) => a.banked + Math.max(0, n - a.base);
6
+ export {
7
+ s as gainAtEnd,
8
+ b as gainAtLoad,
9
+ t as newPlayGain
10
+ };
@@ -0,0 +1,48 @@
1
+ import { matchColor as p } from "../formats/palette.js";
2
+ import { PATCHES as i } from "../player/patchTable.js";
3
+ import { cleanPatches as l } from "../player/patchRules.js";
4
+ import { STOCK_TUNING as d } from "./world.js";
5
+ const m = new Map(i.map((o) => [o.id, o]));
6
+ function k(o, e) {
7
+ let c = 0;
8
+ return o.replace(/%([-0]*)(\d*)l?([ds])/g, (n, s, t, r) => {
9
+ const f = e[c++], a = String(r === "d" ? Math.trunc(Number(f)) : f), u = Number(t || 0);
10
+ return s.includes("-") ? a.padEnd(u) : s.includes("0") && r === "d" ? a.padStart(u, "0") : a.padStart(u);
11
+ });
12
+ }
13
+ function y(o, e) {
14
+ const c = l(o), n = (t) => {
15
+ const r = m.get(t);
16
+ if (!r) throw new Error(`No player patch ${t}`);
17
+ return c[t] ?? (r.kind === "fkey" ? "on" : r.stock);
18
+ }, s = (t) => n(t);
19
+ return {
20
+ text: (t) => n(t),
21
+ format: (t, ...r) => k(n(t), r),
22
+ color: (t, r) => {
23
+ const [f, a, u] = s(`color.rgb.${n(r)}`);
24
+ return p(t, f, a, u);
25
+ },
26
+ rgb: s,
27
+ frame: (t) => n(t),
28
+ num: (t) => n(t),
29
+ seconds: (t) => {
30
+ const r = n(t);
31
+ return r < 0 ? r & 65535 : r;
32
+ },
33
+ fkeyOn: (t) => !m.has(`table.fkeys.F${t}`) || n(`table.fkeys.F${t}`) !== "off",
34
+ ...e ? { about: e } : {}
35
+ };
36
+ }
37
+ function O(o) {
38
+ const e = {};
39
+ for (const c of Object.keys(d)) e[c] = o.num(`play.${c}`);
40
+ return e;
41
+ }
42
+ const N = y();
43
+ export {
44
+ N as STOCK_LOOK,
45
+ O as playTuning,
46
+ y as playerLook,
47
+ k as sprintf
48
+ };