@maka/maka-cli 5.49.0 → 5.50.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/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +20 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +9 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/contacts.d.ts +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/contacts.js +27 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/contacts.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/give.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/give.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +43 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +6 -24
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/loot.d.ts +21 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/loot.js +93 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/loot.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.d.ts +4 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +23 -31
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.d.ts +32 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +313 -17
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/note.d.ts +25 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/note.js +57 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/note.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +20 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +9 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +13 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +66 -9
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +37 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +47 -19
- package/bundle/typescript/src/commands/game/sideQuest/game.js +182 -70
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless.js +17 -2
- package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +62 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +31 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +28 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +24 -6
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +85 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +182 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +4 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +17 -7
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +17 -13
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +29 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +5 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +87 -8
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +28 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +7 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/range.d.ts +22 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/range.js +69 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/range.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.d.ts +186 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +742 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.d.ts +34 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.js +524 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.d.ts +273 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +890 -24
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Category } from '../types/shared/item-enum.js';
|
|
2
|
+
const RANGE_BRACKETS = {
|
|
3
|
+
pistol: { short: 5, medium: 20, long: 40, extreme: 60 },
|
|
4
|
+
smg: { short: 5, medium: 15, long: 30, extreme: 50 },
|
|
5
|
+
// Indoor-capped: canon's assault-rifle extreme band (351-550m) never
|
|
6
|
+
// fits inside a room this engine can synthesize (huge tops out at
|
|
7
|
+
// ~34m diagonal) -- the bracket still orders correctly, it just never
|
|
8
|
+
// reaches its outer edge in play.
|
|
9
|
+
rifle: { short: 25, medium: 150, long: 350, extreme: 550 },
|
|
10
|
+
shotgun: { short: 15, medium: 30, long: 45, extreme: 60 },
|
|
11
|
+
throw: { short: 5, medium: 10, long: 20, extreme: 40 },
|
|
12
|
+
};
|
|
13
|
+
const NAME_HINTS = [
|
|
14
|
+
[/\b(assault rifle|sniper rifle|carbine|\brifle\b)\b/i, 'rifle'],
|
|
15
|
+
[/\bshotgun|scattergun\b/i, 'shotgun'],
|
|
16
|
+
[/\b(smg|submachine|machine pistol|uzi|mp5|mp7)\b/i, 'smg'],
|
|
17
|
+
[/\b(knife|blade|katana|sword|axe|club|bat|baton|monofilament|garrote|fist|unarmed)\b/i, 'melee'],
|
|
18
|
+
[/\b(grenade|throwing|shuriken)\b/i, 'throw'],
|
|
19
|
+
];
|
|
20
|
+
/** Melee category always wins outright; otherwise name keywords, then
|
|
21
|
+
* a pistol default (see module doc). */
|
|
22
|
+
export function classifyWeapon(item) {
|
|
23
|
+
if (!item)
|
|
24
|
+
return 'pistol';
|
|
25
|
+
if (item.category === Category.MeleeWeapon)
|
|
26
|
+
return 'melee';
|
|
27
|
+
for (const [re, cls] of NAME_HINTS) {
|
|
28
|
+
if (re.test(item.name))
|
|
29
|
+
return cls;
|
|
30
|
+
}
|
|
31
|
+
return 'pistol';
|
|
32
|
+
}
|
|
33
|
+
export function isFirearmClass(cls) {
|
|
34
|
+
return cls !== 'melee';
|
|
35
|
+
}
|
|
36
|
+
/** SR5 range-bracket dice-pool penalty (p.185): 0 / -1 / -3 / -6, or
|
|
37
|
+
* 'out-of-range' beyond the extreme band. Melee has no range penalty
|
|
38
|
+
* -- callers gate melee through adjacency instead (see attack.ts). */
|
|
39
|
+
export function rangePenalty(meters, cls) {
|
|
40
|
+
if (cls === 'melee')
|
|
41
|
+
return 0;
|
|
42
|
+
const b = RANGE_BRACKETS[cls];
|
|
43
|
+
if (meters <= b.short)
|
|
44
|
+
return 0;
|
|
45
|
+
if (meters <= b.medium)
|
|
46
|
+
return -1;
|
|
47
|
+
if (meters <= b.long)
|
|
48
|
+
return -3;
|
|
49
|
+
if (meters <= b.extreme)
|
|
50
|
+
return -6;
|
|
51
|
+
return 'out-of-range';
|
|
52
|
+
}
|
|
53
|
+
/** The bracket NAME a distance falls in, for narration/meta lines
|
|
54
|
+
* ("~22 m, long range"). */
|
|
55
|
+
export function rangeBracketName(meters, cls) {
|
|
56
|
+
if (cls === 'melee')
|
|
57
|
+
return 'short';
|
|
58
|
+
const b = RANGE_BRACKETS[cls];
|
|
59
|
+
if (meters <= b.short)
|
|
60
|
+
return 'short';
|
|
61
|
+
if (meters <= b.medium)
|
|
62
|
+
return 'medium';
|
|
63
|
+
if (meters <= b.long)
|
|
64
|
+
return 'long';
|
|
65
|
+
if (meters <= b.extreme)
|
|
66
|
+
return 'extreme';
|
|
67
|
+
return 'out-of-range';
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/range.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Direction } from '../types/shared/direction-enum.js';
|
|
2
|
+
/**
|
|
3
|
+
* ROOM GRIDS (spatial wave, 2026-08-25; player ruling: barriers should
|
|
4
|
+
* be impassable TERRAIN removable by the proper mechanism, not a door
|
|
5
|
+
* lock -- which meant rooms first needed actual SPACE). Every room's
|
|
6
|
+
* size class maps to an x,y,z cell grid; every "at" spot (see
|
|
7
|
+
* utilities/spots.ts) anchors to a cell in it. This module is the pure
|
|
8
|
+
* spatial engine: layout synthesis, pathing, distance, and cover --
|
|
9
|
+
* NO Room/Scene import (map-view.ts precedent), so it stays safe in
|
|
10
|
+
* the server's engine graph (no import.meta anywhere reachable from
|
|
11
|
+
* headless.js).
|
|
12
|
+
*
|
|
13
|
+
* THE KEYSTONE (never violate): actors never gain coordinates. A
|
|
14
|
+
* Player's only position is still `atSpot: string` (spots.ts). This
|
|
15
|
+
* module only answers "where is spot X, and what lies between spots
|
|
16
|
+
* X and Y" -- spots.ts translates spot NAMES into grid queries, and
|
|
17
|
+
* nothing above that layer ever touches a GridCoord directly.
|
|
18
|
+
*
|
|
19
|
+
* DETERMINISM CONTRACT: `synthesizeGrid` is a pure function seeded by
|
|
20
|
+
* `roomName` (mulberry32 PRNG over an FNV-1a hash) -- identical input
|
|
21
|
+
* always produces an identical grid, on any machine, any process, any
|
|
22
|
+
* reload. The grid is therefore NEVER serialized into seeds or saves;
|
|
23
|
+
* it's recomputed on demand from data that already IS persisted (the
|
|
24
|
+
* room's spots/size/exits/puzzle hints). See Room.ensureGrid.
|
|
25
|
+
*/
|
|
26
|
+
export interface GridCoord {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
z: number;
|
|
30
|
+
}
|
|
31
|
+
export declare const METERS_PER_CELL = 2;
|
|
32
|
+
export declare const METERS_PER_LEVEL = 3;
|
|
33
|
+
export declare const key: (c: GridCoord) => string;
|
|
34
|
+
export type RoomSize = 'tiny' | 'small' | 'medium' | 'large' | 'huge';
|
|
35
|
+
export type WallSide = 'north' | 'south' | 'east' | 'west';
|
|
36
|
+
export type SpotPlace = WallSide | 'northeast corner' | 'northwest corner' | 'southeast corner' | 'southwest corner' | 'center';
|
|
37
|
+
export type VerticalKind = 'stairs' | 'ladder' | 'climb';
|
|
38
|
+
/** The x,y cell footprint a size class implies -- the same table
|
|
39
|
+
* synthesis uses, exposed for DISPLAY-ONLY consumers that have no
|
|
40
|
+
* grid to read (utilities/room-view.ts draws a spotless room's shell
|
|
41
|
+
* from this; a spotless room never synthesizes a grid, THE COMPAT
|
|
42
|
+
* RULE, and must not start doing so just to be drawn). */
|
|
43
|
+
export declare function dimsForSize(size?: RoomSize): {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
};
|
|
47
|
+
interface IVerticalLink {
|
|
48
|
+
kind: VerticalKind;
|
|
49
|
+
toZ: number;
|
|
50
|
+
}
|
|
51
|
+
export interface ITerrainRegion {
|
|
52
|
+
id: string;
|
|
53
|
+
label: string;
|
|
54
|
+
/** The puzzle whose solve/bypass clears this region (solve.ts /
|
|
55
|
+
* bypass-command.ts call Room.clearTerrainFor(puzzleName)). */
|
|
56
|
+
puzzleName: string;
|
|
57
|
+
cells: GridCoord[];
|
|
58
|
+
cleared: boolean;
|
|
59
|
+
cover: 'partial' | 'good';
|
|
60
|
+
/** False when synthesis couldn't seal the guarded cell within the
|
|
61
|
+
* footprint budget (an open room, a small footprint hint) -- the
|
|
62
|
+
* region still renders and still gives cover, but movement is never
|
|
63
|
+
* blocked by it. Logged at synthesis time; never bricks a room. */
|
|
64
|
+
blocking: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface IRoomGrid {
|
|
67
|
+
dims: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
z: number;
|
|
71
|
+
};
|
|
72
|
+
/** Cells permitting a z transition, keyed at the LOWER (from) cell.
|
|
73
|
+
* Both directions are pathable (going down is always free; going up
|
|
74
|
+
* costs a roll for 'climb' -- move.ts enforces that, this module
|
|
75
|
+
* only tracks connectivity). */
|
|
76
|
+
vertical: Map<string, IVerticalLink>;
|
|
77
|
+
/** A spot's ANCHOR cell -- its address for distance, pathing targets
|
|
78
|
+
* and terrain guarding. Always the first cell of its footprint. */
|
|
79
|
+
spotCells: Map<string, GridCoord>;
|
|
80
|
+
/** THE FURNITURE ITSELF (player ruling 2026-08-25: "bar, table,
|
|
81
|
+
* booths can have larger geometry than just one cell"): every cell
|
|
82
|
+
* a named place physically fills, anchor included. A long bar runs
|
|
83
|
+
* three cells down its wall; a crate is one. Bodies never stand in
|
|
84
|
+
* these (see spots.ts seatingIn) and movement routes around them. */
|
|
85
|
+
spotFootprints: Map<string, GridCoord[]>;
|
|
86
|
+
exitCells: Map<Direction, GridCoord>;
|
|
87
|
+
terrain: Map<string, ITerrainRegion>;
|
|
88
|
+
}
|
|
89
|
+
export interface IGridSynthesisSpot {
|
|
90
|
+
name: string;
|
|
91
|
+
place?: SpotPlace;
|
|
92
|
+
level?: number;
|
|
93
|
+
tags?: string[];
|
|
94
|
+
}
|
|
95
|
+
export interface IGridSynthesisExit {
|
|
96
|
+
direction: Direction;
|
|
97
|
+
spotName?: string;
|
|
98
|
+
}
|
|
99
|
+
export interface IGridSynthesisLevel {
|
|
100
|
+
name: string;
|
|
101
|
+
side: WallSide;
|
|
102
|
+
kind: 'catwalk' | 'balcony' | 'mezzanine';
|
|
103
|
+
}
|
|
104
|
+
export interface IGridSynthesisTerrainHint {
|
|
105
|
+
puzzleName: string;
|
|
106
|
+
label: string;
|
|
107
|
+
guards: {
|
|
108
|
+
kind: 'exit';
|
|
109
|
+
direction: Direction;
|
|
110
|
+
} | {
|
|
111
|
+
kind: 'spot';
|
|
112
|
+
spotName: string;
|
|
113
|
+
};
|
|
114
|
+
footprint: 'small' | 'medium' | 'large';
|
|
115
|
+
}
|
|
116
|
+
export interface IGridSynthesisInput {
|
|
117
|
+
roomName: string;
|
|
118
|
+
size?: RoomSize;
|
|
119
|
+
spots: IGridSynthesisSpot[];
|
|
120
|
+
exits: IGridSynthesisExit[];
|
|
121
|
+
levels?: IGridSynthesisLevel[];
|
|
122
|
+
terrainHints: IGridSynthesisTerrainHint[];
|
|
123
|
+
}
|
|
124
|
+
/** FNV-1a, 32-bit. Deterministic string -> uint32. */
|
|
125
|
+
export declare function hashFnv1a(str: string): number;
|
|
126
|
+
/** mulberry32: tiny, fast, deterministic PRNG -- () => [0,1). */
|
|
127
|
+
export declare function mulberry32(seed: number): () => number;
|
|
128
|
+
/** Whether an uncleared blocking region seals this cell -- the same
|
|
129
|
+
* test pathing uses, exposed so spots.ts can seat bodies only on
|
|
130
|
+
* ground they could actually stand on. */
|
|
131
|
+
export declare function isCellBlocked(grid: IRoomGrid, c: GridCoord): boolean;
|
|
132
|
+
/** BFS shortest path between two cells, or undefined if unreachable
|
|
133
|
+
* through open (non-blocked, in-bounds) cells. `levelCells` recomputed
|
|
134
|
+
* from the grid's synthesis metadata (kept on the grid via a WeakMap
|
|
135
|
+
* so callers never have to pass it around -- see synthesizeGrid).
|
|
136
|
+
*
|
|
137
|
+
* FOUR PASSES, cheapest-and-safest first. Two things are avoided when
|
|
138
|
+
* anything else will do, and they are NOT equally bad:
|
|
139
|
+
* 1. a 'climb' link is the RISKY alternative to a level's own stairs
|
|
140
|
+
* or ladder (move.ts rolls Athletics on it, and a failure is a
|
|
141
|
+
* fall), so it is the LAST thing given up;
|
|
142
|
+
* 2. a cell holding somebody's body is merely in the way -- squeezing
|
|
143
|
+
* past a bystander beats free-climbing a wall every time.
|
|
144
|
+
* Hence: (no climb, no squeeze) -> (no climb, squeeze) -> (climb, no
|
|
145
|
+
* squeeze) -> (climb, squeeze). Bodies never make a destination
|
|
146
|
+
* unreachable on their own; the worst they can do is force a squeeze,
|
|
147
|
+
* which move.ts narrates. `pathSqueezes` tells a caller which
|
|
148
|
+
* happened. */
|
|
149
|
+
export declare function findPath(grid: IRoomGrid, from: GridCoord, to: GridCoord, occupied?: ReadonlySet<string>): GridCoord[] | undefined;
|
|
150
|
+
/** Whether this route threads a cell somebody is standing in -- i.e.
|
|
151
|
+
* findPath had to fall back past the no-squeeze passes. */
|
|
152
|
+
export declare function pathSqueezes(path: GridCoord[], occupied?: ReadonlySet<string>): boolean;
|
|
153
|
+
/** Straight-line 3D distance in meters between two cells. */
|
|
154
|
+
export declare function distanceMeters(a: GridCoord, b: GridCoord): number;
|
|
155
|
+
/** Every cell that exists at z-level `z`: ground (z=0) is implicitly the
|
|
156
|
+
* whole x*y footprint; an upper level is only its declared strip. The
|
|
157
|
+
* shape utilities/room-view.ts needs to draw each floor without
|
|
158
|
+
* reaching into LEVEL_CELLS itself (module-private -- see
|
|
159
|
+
* synthesizeGrid). Declared before LEVEL_CELLS below; fine at call
|
|
160
|
+
* time (the const is bound long before any consumer runs). */
|
|
161
|
+
export declare function levelFootprint(grid: IRoomGrid, z: number): GridCoord[];
|
|
162
|
+
/** Cover between two cells: any uncleared terrain region (blocking OR
|
|
163
|
+
* degraded-to-scenery -- both still occlude) whose cells intersect
|
|
164
|
+
* the line of fire, excluding the two endpoints themselves. 'good'
|
|
165
|
+
* wins over 'partial' when both are present. */
|
|
166
|
+
export declare function coverBetween(grid: IRoomGrid, from: GridCoord, to: GridCoord): 'partial' | 'good' | undefined;
|
|
167
|
+
/** Which uncleared blocking region is sealing the path from `from` to
|
|
168
|
+
* `to`: re-runs BFS with each candidate region's cells excluded, and
|
|
169
|
+
* returns the smallest one whose removal opens a path. Undefined when
|
|
170
|
+
* no path exists even with every region cleared (a genuinely
|
|
171
|
+
* disconnected room -- a synthesis bug, not a player-facing state). */
|
|
172
|
+
export declare function blockingRegionFor(grid: IRoomGrid, from: GridCoord, to: GridCoord): ITerrainRegion | undefined;
|
|
173
|
+
/** SR5 p.172 (RAG-verified): DV = meters fallen, only beyond 3m; AP-4
|
|
174
|
+
* applies at the caller (resisted with Body+Armor -- move.ts's job). */
|
|
175
|
+
export declare function fallDamageDV(zSteps: number): number;
|
|
176
|
+
/** Does this path cross a 'climb' vertical link (the riskier route --
|
|
177
|
+
* stairs/ladder never roll anything)? Returns the z-delta of the
|
|
178
|
+
* riskiest crossing (for fallDamageDV), or undefined when the path
|
|
179
|
+
* never touches one. */
|
|
180
|
+
export declare function pathClimbSteps(grid: IRoomGrid, path: GridCoord[]): number | undefined;
|
|
181
|
+
/** Deterministic synthesis -- see the module doc for the contract.
|
|
182
|
+
* Order of operations below IS the contract; never reorder without
|
|
183
|
+
* bumping every consumer of the determinism guarantee. */
|
|
184
|
+
export declare function synthesizeGrid(input: IGridSynthesisInput): IRoomGrid;
|
|
185
|
+
export declare const OPEN_FLOOR_NAME = "open floor";
|
|
186
|
+
export {};
|