@rpgm-tools/neo-angband-core 0.17.0 → 0.18.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 +1 -1
- package/dist/mod/hooks.d.ts +27 -1
- package/dist/mod/hooks.d.ts.map +1 -1
- package/dist/mod/hooks.js +23 -0
- package/dist/mod/hooks.js.map +1 -1
- package/dist/mod/save-blocks.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/mod/hooks.ts +54 -1
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ import { Rng, ENGINE_VERSION, PARITY_BASELINE } from "@rpgm-tools/neo-angband-co
|
|
|
32
32
|
const rng = new Rng(1234);
|
|
33
33
|
console.log(rng.damroll(3, 6), rng.damroll(3, 6), rng.damroll(3, 6)); // 9 13 8
|
|
34
34
|
|
|
35
|
-
console.log(ENGINE_VERSION, PARITY_BASELINE); // 0.
|
|
35
|
+
console.log(ENGINE_VERSION, PARITY_BASELINE); // 0.18.0 4.2.6
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Two entry points:
|
package/dist/mod/hooks.d.ts
CHANGED
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
* with a hook installed and asserting the level is bit-identical.
|
|
71
71
|
*/
|
|
72
72
|
import type { GameState } from "../game/context.js";
|
|
73
|
+
import type { OptionStateData } from "../player/options.js";
|
|
73
74
|
/**
|
|
74
75
|
* A mod's behaviour contributions. Every member is optional; an absent member
|
|
75
76
|
* means "this mod does not touch that point" and core takes its faithful path.
|
|
@@ -180,6 +181,31 @@ export interface ModHooks {
|
|
|
180
181
|
* Serves: the bug-fixes mod's cosmetic string corrections.
|
|
181
182
|
*/
|
|
182
183
|
messageText?: (raw: string) => string;
|
|
184
|
+
/**
|
|
185
|
+
* The player finished changing their options (the '=' menu closed).
|
|
186
|
+
*
|
|
187
|
+
* A NOTIFICATION, and the only one here: every other hook is asked a question
|
|
188
|
+
* and its answer changes what the engine does, whereas this one is told a
|
|
189
|
+
* thing that already happened and core does not read the return value. The
|
|
190
|
+
* fold is "all-observe" for that reason - there is no answer to pick between,
|
|
191
|
+
* so every contributor simply runs.
|
|
192
|
+
*
|
|
193
|
+
* The payload is a SNAPSHOT (OptionState.snapshot()), not the live store. A
|
|
194
|
+
* mod that wants to react to a setting should read what the player chose; a
|
|
195
|
+
* mod that wants to CHANGE a setting has state.options and does not need this.
|
|
196
|
+
* Handing over the live object would blur the two, and a hook that mutated the
|
|
197
|
+
* store while the host was mid-repaint is a bug with no obvious author.
|
|
198
|
+
*
|
|
199
|
+
* Fired by the HOST, because the option screens are the host's - core's
|
|
200
|
+
* OptionState is the pure port of option.c and has no idea a menu exists. The
|
|
201
|
+
* host's own tests pin the call sites; a screen that edits options and forgets
|
|
202
|
+
* to fire this is a mod silently missing an event, which is why they are
|
|
203
|
+
* asserted rather than trusted.
|
|
204
|
+
*
|
|
205
|
+
* Serves: the QoL mod's "remember my settings" (persisting the player's
|
|
206
|
+
* choices past the character they were made on).
|
|
207
|
+
*/
|
|
208
|
+
optionsChanged?: (options: OptionStateData) => void;
|
|
183
209
|
}
|
|
184
210
|
/**
|
|
185
211
|
* Fold several mods' contributions into the single ModHooks core holds.
|
|
@@ -227,7 +253,7 @@ export interface ModHooks {
|
|
|
227
253
|
* (mod-sdk's `Fold`), so the host can hand these values straight to the conflict
|
|
228
254
|
* report and the compiler checks the two agree.
|
|
229
255
|
*/
|
|
230
|
-
export type ModHookFold = "all-must-agree" | "chained" | "last-answer" | "any-yes";
|
|
256
|
+
export type ModHookFold = "all-must-agree" | "chained" | "last-answer" | "any-yes" | "all-observe";
|
|
231
257
|
/**
|
|
232
258
|
* WHICH FOLD EACH HOOK USES, next to the function that implements it.
|
|
233
259
|
*
|
package/dist/mod/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/mod/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/mod/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,CACtB,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAC9B,IAAI,EAAE,OAAO,KACV,MAAM,GAAG,IAAI,CAAC;IAEnB;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,CACnB,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAC/C,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAC5C,MAAM,CAAC;IAEZ;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3D;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,KAAK,OAAO,CAAC;IAEpE;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC;IAE/G;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC;IAE/B;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB,gBAAgB,GAChB,SAAS,GACT,aAAa,GACb,SAAS,GACT,aAAa,CAAC;AAElB;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,QAAQ,EAAE,WAAW,CAAC,CASxE,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,QAAQ,CAAC;IAC9B,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GACrC,QAAQ,CA4EV;AAED,wBAAgB,eAAe,CAC7B,aAAa,EAAE,SAAS,QAAQ,EAAE,GACjC,QAAQ,GAAG,SAAS,CA6FtB"}
|
package/dist/mod/hooks.js
CHANGED
|
@@ -93,6 +93,7 @@ export const MOD_HOOK_FOLDS = {
|
|
|
93
93
|
historyAdd: "all-must-agree",
|
|
94
94
|
saveNoiseScent: "any-yes",
|
|
95
95
|
messageText: "chained",
|
|
96
|
+
optionsChanged: "all-observe",
|
|
96
97
|
};
|
|
97
98
|
/**
|
|
98
99
|
* ONE mod's contribution, with every hook wrapped so a throw cannot escape into
|
|
@@ -182,6 +183,14 @@ export function guardModHooks(hooks, onFault) {
|
|
|
182
183
|
* eat a message the player needed to read. */
|
|
183
184
|
out.messageText = (raw) => guard("messageText", () => text(raw), raw);
|
|
184
185
|
}
|
|
186
|
+
const options = hooks.optionsChanged;
|
|
187
|
+
if (options) {
|
|
188
|
+
/* Nothing to neutralise: core does not read an answer, so the neutral value
|
|
189
|
+
* is undefined and the guard exists only for the latch and the report. */
|
|
190
|
+
out.optionsChanged = (data) => {
|
|
191
|
+
guard("optionsChanged", () => options(data), undefined);
|
|
192
|
+
};
|
|
193
|
+
}
|
|
185
194
|
return out;
|
|
186
195
|
}
|
|
187
196
|
export function composeModHooks(contributions) {
|
|
@@ -261,6 +270,20 @@ export function composeModHooks(contributions) {
|
|
|
261
270
|
if (text.length > 0) {
|
|
262
271
|
out.messageText = (raw) => text.reduce((s, fn) => fn(s), raw);
|
|
263
272
|
}
|
|
273
|
+
const optionsChanged = list.map((c) => c.optionsChanged).filter(isFn);
|
|
274
|
+
if (optionsChanged.length > 0) {
|
|
275
|
+
/* LOAD order, and every one of them is told. There is no answer to choose
|
|
276
|
+
* between, so "later wins" has nothing to win: two mods both remembering the
|
|
277
|
+
* player's settings are not in conflict, they are two mods doing their own
|
|
278
|
+
* job with the same fact. Each gets its OWN copy - a mod that keeps the
|
|
279
|
+
* object it was handed and edits it later must not be editing what the next
|
|
280
|
+
* mod is about to read. */
|
|
281
|
+
out.optionsChanged = (data) => {
|
|
282
|
+
for (const fn of optionsChanged) {
|
|
283
|
+
fn({ ...data, values: { ...data.values }, birth: { ...data.birth } });
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
264
287
|
return out;
|
|
265
288
|
}
|
|
266
289
|
function isFn(v) {
|
package/dist/mod/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/mod/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/mod/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -128,7 +128,7 @@ export type OrphanStore = Record<string, OrphanEntry[]>;
|
|
|
128
128
|
* core pack outright, and versionMap's versions are only ever used to key
|
|
129
129
|
* quarantined MOD entities. An existing save keeps whatever it recorded.
|
|
130
130
|
*/
|
|
131
|
-
export declare const CORE_PACK_VERSION = "0.
|
|
131
|
+
export declare const CORE_PACK_VERSION = "0.18.0";
|
|
132
132
|
/** A core-only manifest: the base game with no mods, deterministic. */
|
|
133
133
|
export declare function coreOnlyManifest(): SaveManifest;
|
|
134
134
|
/**
|
package/dist/version.d.ts
CHANGED
|
@@ -21,5 +21,5 @@ export declare const PARITY_BASELINE = "4.2.6";
|
|
|
21
21
|
* released tag is iterated takes a MINOR bump, because a published tag is pinned
|
|
22
22
|
* by digest in a catalogue and must never be moved.
|
|
23
23
|
*/
|
|
24
|
-
export declare const ENGINE_VERSION = "0.
|
|
24
|
+
export declare const ENGINE_VERSION = "0.18.0";
|
|
25
25
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -21,5 +21,5 @@ export const PARITY_BASELINE = "4.2.6";
|
|
|
21
21
|
* released tag is iterated takes a MINOR bump, because a published tag is pinned
|
|
22
22
|
* by digest in a catalogue and must never be moved.
|
|
23
23
|
*/
|
|
24
|
-
export const ENGINE_VERSION = "0.
|
|
24
|
+
export const ENGINE_VERSION = "0.18.0";
|
|
25
25
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
package/src/mod/hooks.ts
CHANGED
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
*/
|
|
72
72
|
|
|
73
73
|
import type { GameState } from "../game/context.js";
|
|
74
|
+
import type { OptionStateData } from "../player/options.js";
|
|
74
75
|
|
|
75
76
|
/**
|
|
76
77
|
* A mod's behaviour contributions. Every member is optional; an absent member
|
|
@@ -182,6 +183,32 @@ export interface ModHooks {
|
|
|
182
183
|
* Serves: the bug-fixes mod's cosmetic string corrections.
|
|
183
184
|
*/
|
|
184
185
|
messageText?: (raw: string) => string;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The player finished changing their options (the '=' menu closed).
|
|
189
|
+
*
|
|
190
|
+
* A NOTIFICATION, and the only one here: every other hook is asked a question
|
|
191
|
+
* and its answer changes what the engine does, whereas this one is told a
|
|
192
|
+
* thing that already happened and core does not read the return value. The
|
|
193
|
+
* fold is "all-observe" for that reason - there is no answer to pick between,
|
|
194
|
+
* so every contributor simply runs.
|
|
195
|
+
*
|
|
196
|
+
* The payload is a SNAPSHOT (OptionState.snapshot()), not the live store. A
|
|
197
|
+
* mod that wants to react to a setting should read what the player chose; a
|
|
198
|
+
* mod that wants to CHANGE a setting has state.options and does not need this.
|
|
199
|
+
* Handing over the live object would blur the two, and a hook that mutated the
|
|
200
|
+
* store while the host was mid-repaint is a bug with no obvious author.
|
|
201
|
+
*
|
|
202
|
+
* Fired by the HOST, because the option screens are the host's - core's
|
|
203
|
+
* OptionState is the pure port of option.c and has no idea a menu exists. The
|
|
204
|
+
* host's own tests pin the call sites; a screen that edits options and forgets
|
|
205
|
+
* to fire this is a mod silently missing an event, which is why they are
|
|
206
|
+
* asserted rather than trusted.
|
|
207
|
+
*
|
|
208
|
+
* Serves: the QoL mod's "remember my settings" (persisting the player's
|
|
209
|
+
* choices past the character they were made on).
|
|
210
|
+
*/
|
|
211
|
+
optionsChanged?: (options: OptionStateData) => void;
|
|
185
212
|
}
|
|
186
213
|
|
|
187
214
|
/**
|
|
@@ -234,7 +261,8 @@ export type ModHookFold =
|
|
|
234
261
|
| "all-must-agree" // every contributor runs; the first refusal decides
|
|
235
262
|
| "chained" // each sees the previous one's output, so the last one speaks last
|
|
236
263
|
| "last-answer" // the LAST contributor with an opinion decides; earlier ones are not asked
|
|
237
|
-
| "any-yes"
|
|
264
|
+
| "any-yes" // one contributor asking for it is enough
|
|
265
|
+
| "all-observe"; // a notification: every contributor is told, and none of them answers
|
|
238
266
|
|
|
239
267
|
/**
|
|
240
268
|
* WHICH FOLD EACH HOOK USES, next to the function that implements it.
|
|
@@ -260,6 +288,7 @@ export const MOD_HOOK_FOLDS: Readonly<Record<keyof ModHooks, ModHookFold>> = {
|
|
|
260
288
|
historyAdd: "all-must-agree",
|
|
261
289
|
saveNoiseScent: "any-yes",
|
|
262
290
|
messageText: "chained",
|
|
291
|
+
optionsChanged: "all-observe",
|
|
263
292
|
};
|
|
264
293
|
|
|
265
294
|
/**
|
|
@@ -378,6 +407,15 @@ export function guardModHooks(
|
|
|
378
407
|
out.messageText = (raw): string => guard("messageText", () => text(raw), raw);
|
|
379
408
|
}
|
|
380
409
|
|
|
410
|
+
const options = hooks.optionsChanged;
|
|
411
|
+
if (options) {
|
|
412
|
+
/* Nothing to neutralise: core does not read an answer, so the neutral value
|
|
413
|
+
* is undefined and the guard exists only for the latch and the report. */
|
|
414
|
+
out.optionsChanged = (data): void => {
|
|
415
|
+
guard("optionsChanged", () => options(data), undefined);
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
381
419
|
return out;
|
|
382
420
|
}
|
|
383
421
|
|
|
@@ -460,6 +498,21 @@ export function composeModHooks(
|
|
|
460
498
|
out.messageText = (raw): string => text.reduce((s, fn) => fn(s), raw);
|
|
461
499
|
}
|
|
462
500
|
|
|
501
|
+
const optionsChanged = list.map((c) => c.optionsChanged).filter(isFn);
|
|
502
|
+
if (optionsChanged.length > 0) {
|
|
503
|
+
/* LOAD order, and every one of them is told. There is no answer to choose
|
|
504
|
+
* between, so "later wins" has nothing to win: two mods both remembering the
|
|
505
|
+
* player's settings are not in conflict, they are two mods doing their own
|
|
506
|
+
* job with the same fact. Each gets its OWN copy - a mod that keeps the
|
|
507
|
+
* object it was handed and edits it later must not be editing what the next
|
|
508
|
+
* mod is about to read. */
|
|
509
|
+
out.optionsChanged = (data): void => {
|
|
510
|
+
for (const fn of optionsChanged) {
|
|
511
|
+
fn({ ...data, values: { ...data.values }, birth: { ...data.birth } });
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
|
|
463
516
|
return out;
|
|
464
517
|
}
|
|
465
518
|
|
package/src/version.ts
CHANGED
|
@@ -23,4 +23,4 @@ export const PARITY_BASELINE = "4.2.6";
|
|
|
23
23
|
* released tag is iterated takes a MINOR bump, because a published tag is pinned
|
|
24
24
|
* by digest in a catalogue and must never be moved.
|
|
25
25
|
*/
|
|
26
|
-
export const ENGINE_VERSION = "0.
|
|
26
|
+
export const ENGINE_VERSION = "0.18.0";
|