@datamoc/mw_games 0.10.0 → 0.12.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/CHANGELOG.md +83 -0
- package/dist/assets/loader.d.ts.map +1 -1
- package/dist/assets/loader.js +22 -2
- package/dist/assets/loader.js.map +1 -1
- package/dist/audio/Playable.d.ts +2 -0
- package/dist/audio/Playable.d.ts.map +1 -1
- package/dist/audio/Playable.js.map +1 -1
- package/dist/audio/Sound.d.ts +7 -1
- package/dist/audio/Sound.d.ts.map +1 -1
- package/dist/audio/Sound.js +8 -1
- package/dist/audio/Sound.js.map +1 -1
- package/dist/mw_games.global.js +56 -56
- package/dist/rpg/EventRunner.d.ts +4 -0
- package/dist/rpg/EventRunner.d.ts.map +1 -1
- package/dist/rpg/EventRunner.js +4 -4
- package/dist/rpg/EventRunner.js.map +1 -1
- package/dist/rpg/GridMover.d.ts +6 -0
- package/dist/rpg/GridMover.d.ts.map +1 -1
- package/dist/rpg/GridMover.js +17 -0
- package/dist/rpg/GridMover.js.map +1 -1
- package/dist/rpg/MoveRoute.d.ts +87 -0
- package/dist/rpg/MoveRoute.d.ts.map +1 -0
- package/dist/rpg/MoveRoute.js +110 -0
- package/dist/rpg/MoveRoute.js.map +1 -0
- package/dist/rpg/index.d.ts +2 -0
- package/dist/rpg/index.d.ts.map +1 -1
- package/dist/rpg/index.js +1 -0
- package/dist/rpg/index.js.map +1 -1
- package/dist/two-d/ui/EventDialogue.d.ts.map +1 -1
- package/dist/two-d/ui/EventDialogue.js +7 -1
- package/dist/two-d/ui/EventDialogue.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -2
- package/tools/compile-resources.d.mts +29 -0
- package/tools/compile-resources.mjs +61 -7
- package/tools/single-file.d.mts +1 -0
- package/tools/single-file.mjs +72 -28
- package/tools/webp-convert.d.mts +8 -0
- package/tools/webp-convert.mjs +90 -0
|
@@ -11,6 +11,8 @@ export interface EventChoice {
|
|
|
11
11
|
export interface DialogueRequest {
|
|
12
12
|
text: string;
|
|
13
13
|
speaker?: string;
|
|
14
|
+
/** an opaque, renderer-specific portrait image; `two-d/ui.messageBoxPresenter` expects a `Texture2D` */
|
|
15
|
+
portrait?: unknown;
|
|
14
16
|
/** present when the runner is asking rather than telling; resolve with the chosen `value` */
|
|
15
17
|
choices?: EventChoice[];
|
|
16
18
|
}
|
|
@@ -41,9 +43,11 @@ export interface MoveStep {
|
|
|
41
43
|
export type EventCommand = {
|
|
42
44
|
say: string;
|
|
43
45
|
speaker?: string;
|
|
46
|
+
portrait?: unknown;
|
|
44
47
|
} | {
|
|
45
48
|
ask: string;
|
|
46
49
|
speaker?: string;
|
|
50
|
+
portrait?: unknown;
|
|
47
51
|
choices: EventChoice[];
|
|
48
52
|
store?: string;
|
|
49
53
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventRunner.d.ts","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAC/E,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACX;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GACrB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"EventRunner.d.ts","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,wGAAwG;IACxG,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAC/E,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACX;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GACrB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7F;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACrC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IAClC,qFAAqF;IACrF,OAAO,EAAE,iBAAiB,CAAC;IAE3B,IAAI,EAAE,SAAS,CAAC;IAEhB,sFAAsF;IACtF,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,OAAO,CAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,OAAO,CAAC,SAAS,CAAS;IAE1B,YAAY,OAAO,EAAE,kBAAkB,EAGtC;IAED,MAAM,IAAI,IAAI,CAEb;IAEK,GAAG,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAMtE;YAEa,IAAI;IAiDlB,OAAO,CAAC,KAAK;CAQb"}
|
package/dist/rpg/EventRunner.js
CHANGED
|
@@ -32,11 +32,11 @@ export class EventRunner {
|
|
|
32
32
|
}
|
|
33
33
|
async step(command) {
|
|
34
34
|
if ('say' in command) {
|
|
35
|
-
await this.speak(command.say, command.speaker);
|
|
35
|
+
await this.speak(command.say, command.speaker, command.portrait);
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
if ('ask' in command) {
|
|
39
|
-
const chosen = await this.speak(command.ask, command.speaker, command.choices);
|
|
39
|
+
const chosen = await this.speak(command.ask, command.speaker, command.portrait, command.choices);
|
|
40
40
|
if (command.store)
|
|
41
41
|
this.state.answers[command.store] = chosen;
|
|
42
42
|
return;
|
|
@@ -71,8 +71,8 @@ export class EventRunner {
|
|
|
71
71
|
await command.call(this.state);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
speak(text, speaker, choices) {
|
|
75
|
-
return this.options.present({ text, speaker, choices });
|
|
74
|
+
speak(text, speaker, portrait, choices) {
|
|
75
|
+
return this.options.present({ text, speaker, portrait, choices });
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
//# sourceMappingURL=EventRunner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventRunner.js","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EventRunner.js","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"AAiCA,OAAO,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AA0CjE;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,WAAW;IAKvB,YAAY,OAA2B;QAF/B,cAAS,GAAG,KAAK,CAAC;QAGzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAClD,CAAC;IAED,MAAM;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,QAAiC;QAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,SAAS;gBAAE,MAAM;YAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,OAAqB;QACvC,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjE,OAAO;QACR,CAAC;QAED,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YACjG,IAAI,OAAO,CAAC,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;YAC9D,OAAO;QACR,CAAC;QAED,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;YAC/E,OAAO;QACR,CAAC;QAED,IAAI,WAAW,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5D,OAAO;QACR,CAAC;QAED,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YAChE,OAAO;QACR,CAAC;QAED,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC9D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3E,OAAO;QACR,CAAC;QAED,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5D,OAAO;QACR,CAAC;QAED,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO;QACR,CAAC;QAED,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;YACvB,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAEO,KAAK,CACZ,IAAY,EACZ,OAA2B,EAC3B,QAAkB,EAClB,OAAuB;QAEvB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;CACD"}
|
package/dist/rpg/GridMover.d.ts
CHANGED
|
@@ -57,6 +57,12 @@ export declare class GridMover {
|
|
|
57
57
|
turnTo(dx: number, dy: number): void;
|
|
58
58
|
/** starts moving one tile in the given direction; false when already moving */
|
|
59
59
|
moveBy(dx: number, dy: number): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Repositions by a delta instantly, with no tween and no walk animation - what a "jump"
|
|
62
|
+
* move-route step is, as opposed to `moveBy`'s glide. Refuses while a `moveBy` is still in
|
|
63
|
+
* flight, the same as `moveBy` itself does, rather than fighting over `x`/`y` mid-tween.
|
|
64
|
+
*/
|
|
65
|
+
jumpBy(dx: number, dy: number): boolean;
|
|
60
66
|
update(dt: number): void;
|
|
61
67
|
private place;
|
|
62
68
|
private playWalk;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridMover.d.ts","sourceRoot":"","sources":["../../src/rpg/GridMover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,oBAAoB,CAAC;AAE5E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IAEnB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sFAAsF;IACtF,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,MAAM,CAAC;IAElD,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,MAAM,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,SAAS;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,UAAU,CAAU;IAE5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAmB;IAElC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,QAAQ,CAAK;IAErB,YAAY,MAAM,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAWjF;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;OAKG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAInC;IAED,+EAA+E;IAC/E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAUtC;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAcvB;IAED,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,QAAQ;CAGhB"}
|
|
1
|
+
{"version":3,"file":"GridMover.d.ts","sourceRoot":"","sources":["../../src/rpg/GridMover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,oBAAoB,CAAC;AAE5E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IAEnB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sFAAsF;IACtF,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,MAAM,CAAC;IAElD,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,MAAM,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,SAAS;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,UAAU,CAAU;IAE5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAmB;IAElC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,QAAQ,CAAK;IAErB,YAAY,MAAM,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAWjF;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;OAKG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAInC;IAED,+EAA+E;IAC/E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAUtC;IAED;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAWtC;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAcvB;IAED,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,QAAQ;CAGhB"}
|
package/dist/rpg/GridMover.js
CHANGED
|
@@ -64,6 +64,23 @@ export class GridMover {
|
|
|
64
64
|
this.playWalk();
|
|
65
65
|
return true;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Repositions by a delta instantly, with no tween and no walk animation - what a "jump"
|
|
69
|
+
* move-route step is, as opposed to `moveBy`'s glide. Refuses while a `moveBy` is still in
|
|
70
|
+
* flight, the same as `moveBy` itself does, rather than fighting over `x`/`y` mid-tween.
|
|
71
|
+
*/
|
|
72
|
+
jumpBy(dx, dy) {
|
|
73
|
+
if (this.target)
|
|
74
|
+
return false;
|
|
75
|
+
this.facing = directionOf(dx, dy);
|
|
76
|
+
this.x += dx;
|
|
77
|
+
this.y += dy;
|
|
78
|
+
this.fromX = this.x;
|
|
79
|
+
this.fromY = this.y;
|
|
80
|
+
this.place();
|
|
81
|
+
this.playIdle();
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
67
84
|
update(dt) {
|
|
68
85
|
this.sprite.update?.(dt);
|
|
69
86
|
if (!this.target)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridMover.js","sourceRoot":"","sources":["../../src/rpg/GridMover.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GridMover.js","sourceRoot":"","sources":["../../src/rpg/GridMover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { GridMover, type Direction4 } from './GridMover.ts';
|
|
2
|
+
/**
|
|
3
|
+
* One step of a `MoveRoute`, run in order against a `GridMover`. Unlike `GridMover.moveBy`
|
|
4
|
+
* itself, a route step does not always know its own `dx`/`dy` up front - `random`, `toward`
|
|
5
|
+
* and `away` resolve a direction only when the runner actually reaches that step, against
|
|
6
|
+
* wherever the mover and (for `toward`/`away`) the target happen to be at that moment.
|
|
7
|
+
*/
|
|
8
|
+
export type MoveRouteStep = {
|
|
9
|
+
dir: Direction4;
|
|
10
|
+
} | {
|
|
11
|
+
dir: 'random';
|
|
12
|
+
} | {
|
|
13
|
+
dir: 'toward' | 'away';
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
} | {
|
|
17
|
+
turn: Direction4 | 'random';
|
|
18
|
+
} | {
|
|
19
|
+
jump: {
|
|
20
|
+
dx: number;
|
|
21
|
+
dy: number;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
wait: number;
|
|
25
|
+
};
|
|
26
|
+
export interface MoveRoute {
|
|
27
|
+
steps: readonly MoveRouteStep[];
|
|
28
|
+
/** loops back to the first step once the last one finishes, rather than stopping there */
|
|
29
|
+
repeat?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* when a directional step's target tile is refused by `canMove`, move on to the next step
|
|
32
|
+
* immediately rather than retrying the same step every tick until it opens up
|
|
33
|
+
*/
|
|
34
|
+
skippable?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface MoveRouteOptions {
|
|
37
|
+
/** asked before every directional/jump step, the same contract `GridMover` itself expects of its caller */
|
|
38
|
+
canMove?: (dx: number, dy: number) => boolean;
|
|
39
|
+
/** source of randomness for `random` steps; defaults to `Math.random` */
|
|
40
|
+
random?: () => number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Drives a `GridMover` through a `MoveRoute` over successive `update(dt)` calls - the piece
|
|
44
|
+
* `GridMover`'s own one-step-at-a-time `moveBy`/`turnTo` deliberately leaves out (see its own
|
|
45
|
+
* doc comment: whether a step is passable is the caller's question, not the mover's). Works
|
|
46
|
+
* against any `GridMover`, not only the player's - an NPC's wandering or patrol route is the
|
|
47
|
+
* same shape as a scripted cutscene walk.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { GridMover, MoveRouteRunner, type MoveRoute } from '@datamoc/mw_games/rpg';
|
|
52
|
+
* import type { MovableSprite } from '@datamoc/mw_games/rpg';
|
|
53
|
+
*
|
|
54
|
+
* declare const npcSprite: MovableSprite;
|
|
55
|
+
* declare function tilePassable(x: number, y: number): boolean;
|
|
56
|
+
*
|
|
57
|
+
* const mover = new GridMover(npcSprite, 3, 3, { tileWidth: 32, tileHeight: 32 });
|
|
58
|
+
* const patrol: MoveRoute = {
|
|
59
|
+
* steps: [{ dir: 'right' }, { dir: 'right' }, { wait: 1 }, { dir: 'left' }, { dir: 'left' }],
|
|
60
|
+
* repeat: true,
|
|
61
|
+
* };
|
|
62
|
+
* const route = new MoveRouteRunner(mover, patrol, {
|
|
63
|
+
* canMove: (dx, dy) => tilePassable(mover.x + dx, mover.y + dy),
|
|
64
|
+
* });
|
|
65
|
+
*
|
|
66
|
+
* // in the game loop:
|
|
67
|
+
* mover.update(1 / 60);
|
|
68
|
+
* route.update(1 / 60);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare class MoveRouteRunner {
|
|
72
|
+
private mover;
|
|
73
|
+
private route;
|
|
74
|
+
private options;
|
|
75
|
+
private index;
|
|
76
|
+
private waiting;
|
|
77
|
+
constructor(mover: GridMover, route: MoveRoute, options?: MoveRouteOptions);
|
|
78
|
+
/** true once a non-repeating route has run every step */
|
|
79
|
+
get done(): boolean;
|
|
80
|
+
update(dt: number): void;
|
|
81
|
+
/** @returns whether the step actually moved/turned/waited, so the runner can decide to skip it */
|
|
82
|
+
private runStep;
|
|
83
|
+
private resolveDirection;
|
|
84
|
+
private attempt;
|
|
85
|
+
private pickDirection;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=MoveRoute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MoveRoute.d.ts","sourceRoot":"","sources":["../../src/rpg/MoveRoute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAW5D;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACtB;IAAE,GAAG,EAAE,UAAU,CAAA;CAAE,GACnB;IAAE,GAAG,EAAE,QAAQ,CAAA;CAAE,GACjB;IAAE,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpB,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAEhC,0FAA0F;IAC1F,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAChC,2GAA2G;IAC3G,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAE9C,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAK;IAEpB,YAAY,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE,gBAAqB,EAI7E;IAED,yDAAyD;IACzD,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAevB;IAED,kGAAkG;IAClG,OAAO,CAAC,OAAO;IAqBf,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,aAAa;CAIrB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { GridMover } from './GridMover.js';
|
|
2
|
+
const DIRECTIONS = ['up', 'down', 'left', 'right'];
|
|
3
|
+
const DELTA = {
|
|
4
|
+
up: { dx: 0, dy: -1 },
|
|
5
|
+
down: { dx: 0, dy: 1 },
|
|
6
|
+
left: { dx: -1, dy: 0 },
|
|
7
|
+
right: { dx: 1, dy: 0 },
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Drives a `GridMover` through a `MoveRoute` over successive `update(dt)` calls - the piece
|
|
11
|
+
* `GridMover`'s own one-step-at-a-time `moveBy`/`turnTo` deliberately leaves out (see its own
|
|
12
|
+
* doc comment: whether a step is passable is the caller's question, not the mover's). Works
|
|
13
|
+
* against any `GridMover`, not only the player's - an NPC's wandering or patrol route is the
|
|
14
|
+
* same shape as a scripted cutscene walk.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { GridMover, MoveRouteRunner, type MoveRoute } from '@datamoc/mw_games/rpg';
|
|
19
|
+
* import type { MovableSprite } from '@datamoc/mw_games/rpg';
|
|
20
|
+
*
|
|
21
|
+
* declare const npcSprite: MovableSprite;
|
|
22
|
+
* declare function tilePassable(x: number, y: number): boolean;
|
|
23
|
+
*
|
|
24
|
+
* const mover = new GridMover(npcSprite, 3, 3, { tileWidth: 32, tileHeight: 32 });
|
|
25
|
+
* const patrol: MoveRoute = {
|
|
26
|
+
* steps: [{ dir: 'right' }, { dir: 'right' }, { wait: 1 }, { dir: 'left' }, { dir: 'left' }],
|
|
27
|
+
* repeat: true,
|
|
28
|
+
* };
|
|
29
|
+
* const route = new MoveRouteRunner(mover, patrol, {
|
|
30
|
+
* canMove: (dx, dy) => tilePassable(mover.x + dx, mover.y + dy),
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // in the game loop:
|
|
34
|
+
* mover.update(1 / 60);
|
|
35
|
+
* route.update(1 / 60);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export class MoveRouteRunner {
|
|
39
|
+
constructor(mover, route, options = {}) {
|
|
40
|
+
this.index = 0;
|
|
41
|
+
this.waiting = 0;
|
|
42
|
+
this.mover = mover;
|
|
43
|
+
this.route = route;
|
|
44
|
+
this.options = options;
|
|
45
|
+
}
|
|
46
|
+
/** true once a non-repeating route has run every step */
|
|
47
|
+
get done() {
|
|
48
|
+
return !this.route.repeat && this.index >= this.route.steps.length;
|
|
49
|
+
}
|
|
50
|
+
update(dt) {
|
|
51
|
+
if (this.mover.isMoving || this.done)
|
|
52
|
+
return;
|
|
53
|
+
if (this.waiting > 0) {
|
|
54
|
+
this.waiting = Math.max(0, this.waiting - dt);
|
|
55
|
+
if (this.waiting > 0)
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (this.index >= this.route.steps.length) {
|
|
59
|
+
this.index = 0;
|
|
60
|
+
}
|
|
61
|
+
const step = this.route.steps[this.index];
|
|
62
|
+
const advanced = this.runStep(step);
|
|
63
|
+
if (advanced || this.route.skippable)
|
|
64
|
+
this.index++;
|
|
65
|
+
}
|
|
66
|
+
/** @returns whether the step actually moved/turned/waited, so the runner can decide to skip it */
|
|
67
|
+
runStep(step) {
|
|
68
|
+
if ('turn' in step) {
|
|
69
|
+
const direction = step.turn === 'random' ? this.pickDirection() : step.turn;
|
|
70
|
+
const { dx, dy } = DELTA[direction];
|
|
71
|
+
this.mover.turnTo(dx, dy);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
if ('wait' in step) {
|
|
75
|
+
this.waiting = step.wait;
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if ('jump' in step) {
|
|
79
|
+
return this.attempt(step.jump.dx, step.jump.dy, (dx, dy) => this.mover.jumpBy(dx, dy));
|
|
80
|
+
}
|
|
81
|
+
const { dx, dy } = this.resolveDirection(step);
|
|
82
|
+
return this.attempt(dx, dy, (dx, dy) => this.mover.moveBy(dx, dy));
|
|
83
|
+
}
|
|
84
|
+
resolveDirection(step) {
|
|
85
|
+
if (step.dir === 'random')
|
|
86
|
+
return DELTA[this.pickDirection()];
|
|
87
|
+
if (step.dir === 'toward' || step.dir === 'away') {
|
|
88
|
+
const sign = step.dir === 'toward' ? 1 : -1;
|
|
89
|
+
const ddx = step.x - this.mover.x;
|
|
90
|
+
const ddy = step.y - this.mover.y;
|
|
91
|
+
//the larger axis first, matching the direction a step would actually close (or open)
|
|
92
|
+
return Math.abs(ddx) >= Math.abs(ddy)
|
|
93
|
+
? { dx: sign * Math.sign(ddx) || 0, dy: 0 }
|
|
94
|
+
: { dx: 0, dy: sign * Math.sign(ddy) || 0 };
|
|
95
|
+
}
|
|
96
|
+
return DELTA[step.dir];
|
|
97
|
+
}
|
|
98
|
+
attempt(dx, dy, move) {
|
|
99
|
+
if (dx === 0 && dy === 0)
|
|
100
|
+
return true;
|
|
101
|
+
if (this.options.canMove && !this.options.canMove(dx, dy))
|
|
102
|
+
return false;
|
|
103
|
+
return move(dx, dy);
|
|
104
|
+
}
|
|
105
|
+
pickDirection() {
|
|
106
|
+
const random = this.options.random ?? Math.random;
|
|
107
|
+
return DIRECTIONS[Math.floor(random() * DIRECTIONS.length)];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=MoveRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MoveRoute.js","sourceRoot":"","sources":["../../src/rpg/MoveRoute.ts"],"names":[],"mappings":"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"}
|
package/dist/rpg/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export { EventRunner } from './EventRunner.ts';
|
|
|
9
9
|
export type { EventCommand, EventRunnerState, EventRunnerOptions, MoveStep, DialoguePresenter, DialogueRequest, EventChoice, } from './EventRunner.ts';
|
|
10
10
|
export { GridMover } from './GridMover.ts';
|
|
11
11
|
export type { GridMoverOptions, Direction4 } from './GridMover.ts';
|
|
12
|
+
export { MoveRouteRunner } from './MoveRoute.ts';
|
|
13
|
+
export type { MoveRoute, MoveRouteStep, MoveRouteOptions } from './MoveRoute.ts';
|
|
12
14
|
export { FreeMover } from './FreeMover.ts';
|
|
13
15
|
export type { FreeMoverOptions } from './FreeMover.ts';
|
|
14
16
|
export { aabbOverlap, circleOverlap, circleAabbOverlap, resolveAabbAgainstTiles } from './Collision.ts';
|
package/dist/rpg/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,WAAW,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACxG,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxG,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,WAAW,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACxG,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxG,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/rpg/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export { GameState } from './GameState.js';
|
|
|
4
4
|
export { activePage, conditionHolds } from './Event.js';
|
|
5
5
|
export { EventRunner } from './EventRunner.js';
|
|
6
6
|
export { GridMover } from './GridMover.js';
|
|
7
|
+
export { MoveRouteRunner } from './MoveRoute.js';
|
|
7
8
|
export { FreeMover } from './FreeMover.js';
|
|
8
9
|
export { aabbOverlap, circleOverlap, circleAabbOverlap, resolveAabbAgainstTiles } from './Collision.js';
|
|
9
10
|
export { QuestLog, questsFromRows } from './Quest.js';
|
package/dist/rpg/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAU/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAExG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAU/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAExG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventDialogue.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/EventDialogue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"EventDialogue.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/EventDialogue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,MAAM,WAAW,0BAA0B;IAC1C,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;CACrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,0BAA+B,GAAG,iBAAiB,CAqBrH"}
|
|
@@ -17,7 +17,13 @@ export function messageBoxPresenter(windows, options = {}) {
|
|
|
17
17
|
width: options.width ?? 480,
|
|
18
18
|
height: options.height ?? 120,
|
|
19
19
|
speed: options.speed ?? 45,
|
|
20
|
-
pages: [
|
|
20
|
+
pages: [
|
|
21
|
+
{
|
|
22
|
+
text: request.text,
|
|
23
|
+
speaker: request.speaker,
|
|
24
|
+
portrait: request.portrait,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
21
27
|
choices: request.choices,
|
|
22
28
|
anchor: options.anchor ?? 'bottom',
|
|
23
29
|
onDone: (chosen) => resolve(chosen),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventDialogue.js","sourceRoot":"","sources":["../../../src/two-d/ui/EventDialogue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"EventDialogue.js","sourceRoot":"","sources":["../../../src/two-d/ui/EventDialogue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAa7C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAoB,EAAE,OAAO,GAA+B,EAAE;IACjG,OAAO,CAAC,OAAO,EAAE,EAAE,CAClB,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACvB,OAAO,CAAC,IAAI,CACX,IAAI,UAAU,CAAC;YACd,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG;YAC7B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;YAC1B,KAAK,EAAE;gBACN;oBACC,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,QAAQ,EAAE,OAAO,CAAC,QAAiC;iBACnD;aACD;YACD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,QAAQ;YAClC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACnC,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* this from `package.json` automatically, chosen because this project's own build already
|
|
10
10
|
* has no step before `tsc`/`vite` that this would need to run ahead of.
|
|
11
11
|
*/
|
|
12
|
-
export declare const version = "0.
|
|
12
|
+
export declare const version = "0.12.0";
|
|
13
13
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* this from `package.json` automatically, chosen because this project's own build already
|
|
10
10
|
* has no step before `tsc`/`vite` that this would need to run ahead of.
|
|
11
11
|
*/
|
|
12
|
-
export const version = '0.
|
|
12
|
+
export const version = '0.12.0';
|
|
13
13
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datamoc/mw_games",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "A local-file game framework: renderer-free game logic, drawn through PixiJS in 2D or Babylon.js in 3D, with mobile and desktop packaging.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -39,6 +39,9 @@
|
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
41
|
"tools/compile-resources.mjs",
|
|
42
|
+
"tools/compile-resources.d.mts",
|
|
43
|
+
"tools/webp-convert.mjs",
|
|
44
|
+
"tools/webp-convert.d.mts",
|
|
42
45
|
"tools/extract-html.mjs",
|
|
43
46
|
"tools/extract-html.d.mts",
|
|
44
47
|
"tools/compress-dist.mjs",
|
|
@@ -133,6 +136,7 @@
|
|
|
133
136
|
},
|
|
134
137
|
"./tools/compile-resources": "./tools/compile-resources.mjs",
|
|
135
138
|
"./tools/compress-dist": "./tools/compress-dist.mjs",
|
|
139
|
+
"./tools/webp-convert": "./tools/webp-convert.mjs",
|
|
136
140
|
"./two-d": {
|
|
137
141
|
"types": "./dist/two-d/index.d.ts",
|
|
138
142
|
"import": "./dist/two-d/index.js"
|
|
@@ -243,7 +247,7 @@
|
|
|
243
247
|
"webpage:examples": "node tools/build-webpage-examples.mjs",
|
|
244
248
|
"webpage:docs": "node tools/build-webpage-docs.mjs",
|
|
245
249
|
"webpage:diagrams": "node tools/make-example-diagrams.mjs && node tools/make-architecture-diagrams.mjs",
|
|
246
|
-
"mobile:build": "
|
|
250
|
+
"mobile:build": "vite build --config examples/tower-defense/vite.config.ts && node tools/emit-page.mjs examples/tower-defense --no-compress",
|
|
247
251
|
"cap:cli": "node --require ./tools/capacitor-node-workaround.cjs ./node_modules/@capacitor/cli/bin/capacitor",
|
|
248
252
|
"cap:add:android": "npm run mobile:build && npm run cap:cli -- add android",
|
|
249
253
|
"cap:add:ios": "npm run mobile:build && npm run cap:cli -- add ios",
|
|
@@ -292,6 +296,7 @@
|
|
|
292
296
|
"pixi.js": "^8.20.1",
|
|
293
297
|
"playwright-core": "^1.62.1",
|
|
294
298
|
"prettier": "^3.9.6",
|
|
299
|
+
"sharp": "^0.35.4",
|
|
295
300
|
"typescript": "^7.0.2",
|
|
296
301
|
"vite": "^8.2.2",
|
|
297
302
|
"ws": "^8.21.3"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const DEFAULT_MIME: Record<string, string>;
|
|
2
|
+
|
|
3
|
+
export function walk(dir: string): AsyncGenerator<string>;
|
|
4
|
+
|
|
5
|
+
export interface CompileResourcesOptions {
|
|
6
|
+
from: string;
|
|
7
|
+
to: string;
|
|
8
|
+
mime?: Record<string, string>;
|
|
9
|
+
groupBy?: (key: string) => string;
|
|
10
|
+
toWebp?: boolean;
|
|
11
|
+
webpLossless?: boolean;
|
|
12
|
+
webpQuality?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CompileResourcesGroup {
|
|
16
|
+
name: string;
|
|
17
|
+
count: number;
|
|
18
|
+
size: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CompileResourcesResult {
|
|
22
|
+
groups: CompileResourcesGroup[];
|
|
23
|
+
rawBytes: number;
|
|
24
|
+
embeddedBytes: number;
|
|
25
|
+
webpConverted: number;
|
|
26
|
+
skipped: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function compileResources(options: CompileResourcesOptions): Promise<CompileResourcesResult>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readdir, readFile, mkdir, writeFile, rm } from 'node:fs/promises';
|
|
2
2
|
import { join, extname, relative, sep, dirname, basename } from 'node:path';
|
|
3
|
+
import { WEBP_CONVERTIBLE_EXTENSIONS } from './webp-convert.mjs';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Turns a folder of assets into scripts a `file://` page can load.
|
|
@@ -56,9 +57,27 @@ export async function* walk(dir) {
|
|
|
56
57
|
* @param options.to folder to write the generated scripts into
|
|
57
58
|
* @param options.mime extension to MIME type, merged over the defaults
|
|
58
59
|
* @param options.groupBy how to name the script an asset lands in; defaults to its top folder
|
|
60
|
+
* @param options.toWebp convert `.png`/`.jpg`/`.jpeg` assets to WebP before embedding
|
|
61
|
+
* (default false - see `tools/webp-convert.mjs`). The asset's *key* never changes (a game
|
|
62
|
+
* still calls `load('tiles.png')` in both dev and built modes; dev mode serves the literal
|
|
63
|
+
* file from disk, unconverted), only the embedded `data:` URI's bytes and MIME type do, and
|
|
64
|
+
* only when the WebP result is actually smaller - a conversion that would not save
|
|
65
|
+
* anything is silently skipped rather than embedded anyway.
|
|
66
|
+
* @param options.webpLossless use WebP's lossless mode when converting (default true - a
|
|
67
|
+
* pixel-art tileset's exact colours survive; set false only with `webpQuality` to opt into
|
|
68
|
+
* lossy re-encoding for photographic source art)
|
|
69
|
+
* @param options.webpQuality 0-100, used only when `webpLossless` is false (default 90)
|
|
59
70
|
* @returns the group names, in the order the page should load them
|
|
60
71
|
*/
|
|
61
|
-
export async function compileResources({
|
|
72
|
+
export async function compileResources({
|
|
73
|
+
from,
|
|
74
|
+
to,
|
|
75
|
+
mime = {},
|
|
76
|
+
groupBy,
|
|
77
|
+
toWebp: convertToWebp = false,
|
|
78
|
+
webpLossless = true,
|
|
79
|
+
webpQuality = 90,
|
|
80
|
+
} = {}) {
|
|
62
81
|
if (!from || !to) throw new Error('compileResources needs both `from` and `to`');
|
|
63
82
|
|
|
64
83
|
const types = { ...DEFAULT_MIME, ...mime };
|
|
@@ -70,9 +89,16 @@ export async function compileResources({ from, to, mime = {}, groupBy } = {}) {
|
|
|
70
89
|
const groups = new Map();
|
|
71
90
|
let skipped = 0;
|
|
72
91
|
let rawBytes = 0;
|
|
92
|
+
let embeddedBytes = 0;
|
|
93
|
+
let webpConverted = 0;
|
|
94
|
+
|
|
95
|
+
// only paid when toWebp is actually used, so a build that never asks for it never imports
|
|
96
|
+
// (or requires installing) sharp
|
|
97
|
+
const toWebp = convertToWebp ? (await import('./webp-convert.mjs')).toWebp : null;
|
|
73
98
|
|
|
74
99
|
for await (const file of walk(from)) {
|
|
75
|
-
const
|
|
100
|
+
const ext = extname(file).toLowerCase();
|
|
101
|
+
const type = types[ext];
|
|
76
102
|
if (!type) {
|
|
77
103
|
skipped++;
|
|
78
104
|
continue;
|
|
@@ -81,10 +107,22 @@ export async function compileResources({ from, to, mime = {}, groupBy } = {}) {
|
|
|
81
107
|
const key = relative(from, file).split(sep).join('/');
|
|
82
108
|
const data = await readFile(file);
|
|
83
109
|
|
|
110
|
+
let mimeType = type;
|
|
111
|
+
let bytes = data;
|
|
112
|
+
if (toWebp && WEBP_CONVERTIBLE_EXTENSIONS.has(ext)) {
|
|
113
|
+
const webp = await toWebp(data, { lossless: webpLossless, quality: webpQuality });
|
|
114
|
+
if (webp.length < data.length) {
|
|
115
|
+
mimeType = 'image/webp';
|
|
116
|
+
bytes = webp;
|
|
117
|
+
webpConverted++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
84
121
|
const name = group(key);
|
|
85
122
|
if (!groups.has(name)) groups.set(name, {});
|
|
86
|
-
groups.get(name)[key] = `data:${
|
|
123
|
+
groups.get(name)[key] = `data:${mimeType};base64,${bytes.toString('base64')}`;
|
|
87
124
|
rawBytes += data.length;
|
|
125
|
+
embeddedBytes += bytes.length;
|
|
88
126
|
}
|
|
89
127
|
|
|
90
128
|
const written = [];
|
|
@@ -98,7 +136,7 @@ export async function compileResources({ from, to, mime = {}, groupBy } = {}) {
|
|
|
98
136
|
written.push({ name, count: Object.keys(assets).length, size: js.length });
|
|
99
137
|
}
|
|
100
138
|
|
|
101
|
-
return { groups: written, rawBytes, skipped };
|
|
139
|
+
return { groups: written, rawBytes, embeddedBytes, webpConverted, skipped };
|
|
102
140
|
}
|
|
103
141
|
|
|
104
142
|
// ---------------------------------------------------------------- CLI
|
|
@@ -106,17 +144,27 @@ export async function compileResources({ from, to, mime = {}, groupBy } = {}) {
|
|
|
106
144
|
const isMain = process.argv[1] && import.meta.url.endsWith(basename(process.argv[1]));
|
|
107
145
|
|
|
108
146
|
if (isMain) {
|
|
109
|
-
const
|
|
147
|
+
const args = process.argv.slice(2);
|
|
148
|
+
const [from, to] = args.filter((a) => !a.startsWith('--'));
|
|
110
149
|
if (!from || !to) {
|
|
111
|
-
console.error(
|
|
150
|
+
console.error(
|
|
151
|
+
'usage: node compile-resources.mjs <asset folder> <output folder> [--to-webp] [--webp-lossy[=quality]]',
|
|
152
|
+
);
|
|
112
153
|
process.exit(1);
|
|
113
154
|
}
|
|
155
|
+
const toWebp = args.includes('--to-webp');
|
|
156
|
+
const lossyFlag = args.find((a) => a === '--webp-lossy' || a.startsWith('--webp-lossy='));
|
|
157
|
+
const webpLossless = !lossyFlag;
|
|
158
|
+
const webpQuality = lossyFlag && lossyFlag.includes('=') ? Number(lossyFlag.split('=')[1]) : 90;
|
|
114
159
|
|
|
115
|
-
const { groups, rawBytes, skipped } = await compileResources({
|
|
160
|
+
const { groups, rawBytes, embeddedBytes, webpConverted, skipped } = await compileResources({
|
|
116
161
|
from,
|
|
117
162
|
to,
|
|
118
163
|
//a flat folder has no subdirectories to group by, so everything lands in one file
|
|
119
164
|
groupBy: (key) => (key.includes('/') ? key.slice(0, key.indexOf('/')) : 'assets'),
|
|
165
|
+
toWebp,
|
|
166
|
+
webpLossless,
|
|
167
|
+
webpQuality,
|
|
120
168
|
});
|
|
121
169
|
|
|
122
170
|
const kb = (n) => (n / 1024).toFixed(1).padStart(8) + ' KB';
|
|
@@ -124,6 +172,12 @@ if (isMain) {
|
|
|
124
172
|
console.log(` ${join(relative(process.cwd(), to), name + '.js').padEnd(40)}${kb(size)} (${count} files)`);
|
|
125
173
|
}
|
|
126
174
|
console.log(` ${groups.length} script(s), ${kb(rawBytes)} of assets` + (skipped ? `, ${skipped} skipped` : ''));
|
|
175
|
+
if (toWebp) {
|
|
176
|
+
console.log(
|
|
177
|
+
` ${webpConverted} image(s) converted to WebP (${webpLossless ? 'lossless' : `lossy, quality ${webpQuality}`}), ` +
|
|
178
|
+
`${kb(rawBytes)} -> ${kb(embeddedBytes)} embedded`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
127
181
|
}
|
|
128
182
|
|
|
129
183
|
export { dirname };
|