@rpgm-tools/neo-angband-core 0.32.0 → 0.34.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/game/effect-general.d.ts.map +1 -1
- package/dist/game/effect-general.js +4 -2
- package/dist/game/effect-general.js.map +1 -1
- package/dist/game/project-cast.d.ts.map +1 -1
- package/dist/game/project-cast.js +7 -0
- package/dist/game/project-cast.js.map +1 -1
- package/dist/mod/hooks.d.ts +138 -18
- package/dist/mod/hooks.d.ts.map +1 -1
- package/dist/mod/hooks.js +62 -0
- package/dist/mod/hooks.js.map +1 -1
- package/dist/mod/save-blocks.d.ts +1 -1
- package/dist/obj/knowledge.d.ts +16 -2
- package/dist/obj/knowledge.d.ts.map +1 -1
- package/dist/obj/knowledge.js +17 -1
- package/dist/obj/knowledge.js.map +1 -1
- package/dist/player/history.d.ts +7 -2
- package/dist/player/history.d.ts.map +1 -1
- package/dist/player/history.js +12 -4
- package/dist/player/history.js.map +1 -1
- package/dist/session/game.d.ts.map +1 -1
- package/dist/session/game.js +15 -5
- package/dist/session/game.js.map +1 -1
- package/dist/session/save.d.ts +2 -0
- package/dist/session/save.d.ts.map +1 -1
- package/dist/session/save.js +2 -0
- package/dist/session/save.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/world/project.d.ts +16 -1
- package/dist/world/project.d.ts.map +1 -1
- package/dist/world/project.js +17 -1
- package/dist/world/project.js.map +1 -1
- package/package.json +1 -1
- package/src/game/effect-general.ts +9 -2
- package/src/game/project-cast.ts +7 -0
- package/src/mod/hooks.ts +216 -14
- package/src/obj/knowledge.ts +16 -0
- package/src/player/history.ts +21 -6
- package/src/session/game.ts +19 -8
- package/src/session/save.ts +4 -0
- package/src/version.ts +1 -1
- package/src/world/project.ts +33 -2
package/src/session/game.ts
CHANGED
|
@@ -1132,22 +1132,22 @@ function wireGame(
|
|
|
1132
1132
|
* per lethal blow, duplicates included, so with no hook installed the
|
|
1133
1133
|
* `?? true` below IS the faithful answer. `duplicate` tells a mod what it
|
|
1134
1134
|
* needs to decide without core deciding anything. */
|
|
1135
|
-
const
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
}) ?? true;
|
|
1135
|
+
const entry: import("../mod/hooks.js").HistoryAddEntry = {
|
|
1136
|
+
what: `Killed ${mon.race.name}`,
|
|
1137
|
+
type: HIST.SLAY_UNIQUE,
|
|
1138
|
+
duplicate: alreadyDead,
|
|
1139
|
+
};
|
|
1140
|
+
const wanted = state.modHooks?.historyAdd?.(entry) ?? true;
|
|
1142
1141
|
if (wanted) {
|
|
1143
1142
|
const stamp = historyStamp(state);
|
|
1144
1143
|
historyAdd(
|
|
1145
1144
|
state.actor.player,
|
|
1146
|
-
what,
|
|
1145
|
+
entry.what,
|
|
1147
1146
|
HIST.SLAY_UNIQUE,
|
|
1148
1147
|
stamp.dlev,
|
|
1149
1148
|
stamp.clev,
|
|
1150
1149
|
stamp.turn,
|
|
1150
|
+
entry.expandUserInput,
|
|
1151
1151
|
);
|
|
1152
1152
|
}
|
|
1153
1153
|
}
|
|
@@ -2659,6 +2659,11 @@ function makeChangeLevel(
|
|
|
2659
2659
|
state.traps = stash.traps;
|
|
2660
2660
|
state.known = stash.known;
|
|
2661
2661
|
if (stash.decoy) state.decoy = stash.decoy;
|
|
2662
|
+
/* A level restored after single combat is the same kind of revisit as
|
|
2663
|
+
* one recovered from birth_levels_persist. Faithful core leaves every
|
|
2664
|
+
* field untouched; an opt-in mod can update transient per-level state
|
|
2665
|
+
* before the player and its monsters resume. */
|
|
2666
|
+
state.modHooks?.levelRevisited?.(state.chunk, stash.turn, state.turn);
|
|
2662
2667
|
const back = state.oldGrid ?? state.actor.grid;
|
|
2663
2668
|
state.actor.grid = back;
|
|
2664
2669
|
state.chunk.setMon(back, -1);
|
|
@@ -2788,6 +2793,12 @@ function makeChangeLevel(
|
|
|
2788
2793
|
* the turns the level was frozen (turn - chunk->freeze-turn). */
|
|
2789
2794
|
restoreMonsters(state, state.turn - stored.turn);
|
|
2790
2795
|
|
|
2796
|
+
/* A restored persistent level is live again. Core deliberately does
|
|
2797
|
+
* nothing here, matching 4.2.6; a mod may observe the exact freeze and
|
|
2798
|
+
* resume turns to update level-owned transient state before any monster
|
|
2799
|
+
* can receive a turn. */
|
|
2800
|
+
state.modHooks?.levelRevisited?.(state.chunk, stored.turn, state.turn);
|
|
2801
|
+
|
|
2791
2802
|
/* Place the player (prepare_next_level non-arena, L1497-1501): sanitize
|
|
2792
2803
|
* the retained grid into a legal arrival square, then player_place.
|
|
2793
2804
|
* DEFERRAL: exact stair-connector matching (dun->persist / one_off_*
|
package/src/session/save.ts
CHANGED
|
@@ -1401,6 +1401,8 @@ export interface SavedHistoryInfo {
|
|
|
1401
1401
|
artifactName: string;
|
|
1402
1402
|
turn: number;
|
|
1403
1403
|
event: string;
|
|
1404
|
+
/** A mod saved `event` as raw user input for display-time expansion. */
|
|
1405
|
+
expandUserInput?: true;
|
|
1404
1406
|
/** Legacy JSON saves used a numeric aIdx; never written by this version. */
|
|
1405
1407
|
aIdx?: number;
|
|
1406
1408
|
}
|
|
@@ -1455,6 +1457,7 @@ export function serializePlayer(
|
|
|
1455
1457
|
artifactName: ids.artifactName(e.aIdx) ?? "",
|
|
1456
1458
|
turn: e.turn,
|
|
1457
1459
|
event: e.event,
|
|
1460
|
+
...(e.expandUserInput === true ? { expandUserInput: true } : {}),
|
|
1458
1461
|
})),
|
|
1459
1462
|
equipment: [...p.equipment],
|
|
1460
1463
|
objKnown: {
|
|
@@ -1581,6 +1584,7 @@ export function deserializePlayer(
|
|
|
1581
1584
|
aIdx,
|
|
1582
1585
|
turn: e.turn,
|
|
1583
1586
|
event: e.event,
|
|
1587
|
+
...(e.expandUserInput === true ? { expandUserInput: true } : {}),
|
|
1584
1588
|
});
|
|
1585
1589
|
}
|
|
1586
1590
|
p.equipment = [...data.equipment];
|
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.34.0";
|
package/src/world/project.ts
CHANGED
|
@@ -290,7 +290,13 @@ export interface ProjectParams {
|
|
|
290
290
|
origin: Loc;
|
|
291
291
|
/** finish: the target grid, or a grid to travel toward. */
|
|
292
292
|
finish: Loc;
|
|
293
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* rad: 0 = bolt/beam, 1..20 = ball radius, or max arc length.
|
|
295
|
+
*
|
|
296
|
+
* The upper end is a convention rather than a rule - nothing in 4.2.6 checks
|
|
297
|
+
* it, and a radius above `maxRange` produces distances the damage table has
|
|
298
|
+
* no entry for. `resolveRadius` is where that can be decided.
|
|
299
|
+
*/
|
|
294
300
|
rad: number;
|
|
295
301
|
/** typ: GF_ projection type, opaque to the driver; passed to the hooks. */
|
|
296
302
|
typ: number;
|
|
@@ -312,6 +318,15 @@ export interface ProjectParams {
|
|
|
312
318
|
believedWall?: (grid: Loc) => boolean;
|
|
313
319
|
/** cave->decoy: PROJECT_STOP breaks the path here (project.c:218). */
|
|
314
320
|
decoy?: Loc | null;
|
|
321
|
+
/**
|
|
322
|
+
* The mod behaviour seam for `rad` (ModHooks.projectionRadius), threaded in
|
|
323
|
+
* by the caller because this driver holds no GameState and must not learn
|
|
324
|
+
* about one. Absent is the faithful path: `rad` is used exactly as given.
|
|
325
|
+
*
|
|
326
|
+
* Called once, before any geometry is built, and given the same `maxRange`
|
|
327
|
+
* the damage table below is sized by.
|
|
328
|
+
*/
|
|
329
|
+
resolveRadius?: (rad: number, maxRange: number) => number;
|
|
315
330
|
}
|
|
316
331
|
|
|
317
332
|
/** The computed blast: pure geometry + damage, no side effects. */
|
|
@@ -354,6 +369,15 @@ export function computeProjection(c: Chunk, p: ProjectParams): Projection {
|
|
|
354
369
|
const degreesOfArc = p.degreesOfArc ?? 0;
|
|
355
370
|
const diameterOfSource = p.diameterOfSource ?? 0;
|
|
356
371
|
|
|
372
|
+
/* THE RADIUS SEAM (ModHooks.projectionRadius, threaded in as resolveRadius).
|
|
373
|
+
* Faithful 4.2.6 takes the radius as given and never checks it against
|
|
374
|
+
* max_range, which is what leaves `damAtDist` below - sized max_range + 1 -
|
|
375
|
+
* short of the distances a larger radius produces. The upstream fix for that
|
|
376
|
+
* (issue #6671) is one clamp here, and it is a mod's to install: core carries
|
|
377
|
+
* the tag's behaviour, warts included, and holds only the point at which the
|
|
378
|
+
* radius can be decided. */
|
|
379
|
+
if (p.resolveRadius) rad = p.resolveRadius(rad, maxRange);
|
|
380
|
+
|
|
357
381
|
/* No projection path - jump to target. */
|
|
358
382
|
let start: Loc;
|
|
359
383
|
if (flg & PROJECT.JUMP) {
|
|
@@ -518,7 +542,14 @@ export function computeProjection(c: Chunk, p: ProjectParams): Projection {
|
|
|
518
542
|
}
|
|
519
543
|
}
|
|
520
544
|
|
|
521
|
-
/* Calculate and store the actual damage at each distance.
|
|
545
|
+
/* Calculate and store the actual damage at each distance.
|
|
546
|
+
*
|
|
547
|
+
* SIZED BY max_range, NOT BY rad, exactly as upstream sizes dam_at_dist. A
|
|
548
|
+
* radius above max_range therefore leaves the far distances with no entry at
|
|
549
|
+
* all, and every read of one is a hole the caller cannot see: the C reads
|
|
550
|
+
* stale memory, and this reads `undefined` straight into the damage a handler
|
|
551
|
+
* is handed. Whether the radius can get there is decided above, by
|
|
552
|
+
* resolveRadius. */
|
|
522
553
|
const damAtDist: number[] = new Array(maxRange + 1);
|
|
523
554
|
for (let i = 0; i <= maxRange; i++) {
|
|
524
555
|
let damTemp: number;
|