@rpgm-tools/neo-angband-content 0.11.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/LICENSE.md +43 -0
- package/README.md +65 -0
- package/dist/compile.d.ts +10 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +42 -0
- package/dist/compile.js.map +1 -0
- package/dist/data-exactness.reader.d.ts +105 -0
- package/dist/data-exactness.reader.d.ts.map +1 -0
- package/dist/data-exactness.reader.js +547 -0
- package/dist/data-exactness.reader.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +70 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +365 -0
- package/dist/parser.js.map +1 -0
- package/dist/records.d.ts +101 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +244 -0
- package/dist/records.js.map +1 -0
- package/dist/specs/generate.d.ts +12 -0
- package/dist/specs/generate.d.ts.map +1 -0
- package/dist/specs/generate.js +57 -0
- package/dist/specs/generate.js.map +1 -0
- package/dist/specs/index.d.ts +9 -0
- package/dist/specs/index.d.ts.map +1 -0
- package/dist/specs/index.js +60 -0
- package/dist/specs/index.js.map +1 -0
- package/dist/specs/init.d.ts +23 -0
- package/dist/specs/init.d.ts.map +1 -0
- package/dist/specs/init.js +305 -0
- package/dist/specs/init.js.map +1 -0
- package/dist/specs/misc.d.ts +33 -0
- package/dist/specs/misc.d.ts.map +1 -0
- package/dist/specs/misc.js +146 -0
- package/dist/specs/misc.js.map +1 -0
- package/dist/specs/mon-init.d.ts +22 -0
- package/dist/specs/mon-init.d.ts.map +1 -0
- package/dist/specs/mon-init.js +157 -0
- package/dist/specs/mon-init.js.map +1 -0
- package/dist/specs/obj-init.d.ts +19 -0
- package/dist/specs/obj-init.d.ts.map +1 -0
- package/dist/specs/obj-init.js +219 -0
- package/dist/specs/obj-init.js.map +1 -0
- package/dist/specs/ui-entry.d.ts +22 -0
- package/dist/specs/ui-entry.d.ts.map +1 -0
- package/dist/specs/ui-entry.js +69 -0
- package/dist/specs/ui-entry.js.map +1 -0
- package/dist/specs/visuals.d.ts +26 -0
- package/dist/specs/visuals.d.ts.map +1 -0
- package/dist/specs/visuals.js +35 -0
- package/dist/specs/visuals.js.map +1 -0
- package/pack/activation.json +3340 -0
- package/pack/artifact.json +5146 -0
- package/pack/blow_effects.json +370 -0
- package/pack/blow_methods.json +286 -0
- package/pack/body.json +59 -0
- package/pack/brand.json +100 -0
- package/pack/chest_trap.json +117 -0
- package/pack/class.json +5501 -0
- package/pack/constants.json +470 -0
- package/pack/curse.json +580 -0
- package/pack/dungeon_profile.json +836 -0
- package/pack/ego_item.json +2900 -0
- package/pack/flavor.json +1541 -0
- package/pack/hints.json +303 -0
- package/pack/history.json +1656 -0
- package/pack/manifest.json +52 -0
- package/pack/monster.json +29392 -0
- package/pack/monster_base.json +688 -0
- package/pack/monster_spell.json +2735 -0
- package/pack/names.json +1204 -0
- package/pack/object.json +11877 -0
- package/pack/object_base.json +364 -0
- package/pack/object_property.json +2034 -0
- package/pack/p_race.json +447 -0
- package/pack/pain.json +150 -0
- package/pack/pit.json +617 -0
- package/pack/player_property.json +519 -0
- package/pack/player_timed.json +1321 -0
- package/pack/projection.json +664 -0
- package/pack/quest.json +18 -0
- package/pack/realm.json +34 -0
- package/pack/room_template.json +9571 -0
- package/pack/shape.json +263 -0
- package/pack/slay.json +116 -0
- package/pack/store.json +675 -0
- package/pack/summon.json +143 -0
- package/pack/terrain.json +511 -0
- package/pack/trap.json +1483 -0
- package/pack/ui_entry.json +382 -0
- package/pack/ui_entry_base.json +60 -0
- package/pack/ui_entry_renderer.json +43 -0
- package/pack/ui_knowledge.json +302 -0
- package/pack/vault.json +4355 -0
- package/pack/visuals.json +680 -0
- package/pack/world.json +1030 -0
- package/package.json +67 -0
- package/src/compile.ts +55 -0
- package/src/data-exactness.reader.ts +559 -0
- package/src/index.ts +31 -0
- package/src/parser.ts +406 -0
- package/src/records.ts +341 -0
- package/src/specs/generate.ts +61 -0
- package/src/specs/index.ts +103 -0
- package/src/specs/init.ts +322 -0
- package/src/specs/misc.ts +153 -0
- package/src/specs/mon-init.ts +165 -0
- package/src/specs/obj-init.ts +230 -0
- package/src/specs/ui-entry.ts +74 -0
- package/src/specs/visuals.ts +37 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specs for the gamedata files whose upstream parsers live in src/init.c:
|
|
3
|
+
* constants, world, player_property, names, trap, terrain (feat), body,
|
|
4
|
+
* history, p_race, realm, shape, class, flavor, hints.
|
|
5
|
+
*
|
|
6
|
+
* Format strings are copied verbatim from the parser_reg() calls.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { FileSpec } from "../records.js";
|
|
10
|
+
|
|
11
|
+
function validIntRange(range: string): boolean {
|
|
12
|
+
const match = /^\s*(-?\d+)\s+to\s+(-?\d+)\s*$/.exec(range);
|
|
13
|
+
if (!match) return false;
|
|
14
|
+
const lo = BigInt(match[1]!);
|
|
15
|
+
const hi = BigInt(match[2]!);
|
|
16
|
+
/* grab_int_range rejects INT_MIN and INT_MAX too (datafile.c:328-331). */
|
|
17
|
+
return lo > -2147483648n && lo < 2147483647n && hi > -2147483648n && hi < 2147483647n;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const constantsSpec: FileSpec = {
|
|
21
|
+
name: "constants",
|
|
22
|
+
upstream: ["src/init.c"],
|
|
23
|
+
/* constants.txt fills a single struct angband_constants; the whole file
|
|
24
|
+
* compiles to one record of grouped, labelled values. */
|
|
25
|
+
recordStart: null,
|
|
26
|
+
directives: [
|
|
27
|
+
{ fmt: "level-max sym label int value", repeat: true },
|
|
28
|
+
{ fmt: "mon-gen sym label int value", repeat: true },
|
|
29
|
+
{ fmt: "mon-play sym label int value", repeat: true },
|
|
30
|
+
{ fmt: "dun-gen sym label int value", repeat: true },
|
|
31
|
+
{ fmt: "world sym label int value", repeat: true },
|
|
32
|
+
{ fmt: "carry-cap sym label int value", repeat: true },
|
|
33
|
+
{ fmt: "store sym label int value", repeat: true },
|
|
34
|
+
{ fmt: "obj-make sym label int value", repeat: true },
|
|
35
|
+
{ fmt: "player sym label int value", repeat: true },
|
|
36
|
+
{ fmt: "melee-critical sym label int value", repeat: true },
|
|
37
|
+
{ fmt: "melee-critical-level int cutoff int mult int add str msg", repeat: true },
|
|
38
|
+
{ fmt: "ranged-critical sym label int value", repeat: true },
|
|
39
|
+
{ fmt: "ranged-critical-level int cutoff int mult int add str msg", repeat: true },
|
|
40
|
+
{ fmt: "o-melee-critical sym label int value", repeat: true },
|
|
41
|
+
{ fmt: "o-melee-critical-level uint chance uint dice str msg", repeat: true },
|
|
42
|
+
{ fmt: "o-ranged-critical sym label int value", repeat: true },
|
|
43
|
+
{ fmt: "o-ranged-critical-level uint chance uint dice str msg", repeat: true },
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const worldSpec: FileSpec = {
|
|
48
|
+
name: "world",
|
|
49
|
+
upstream: ["src/init.c"],
|
|
50
|
+
recordStart: "level",
|
|
51
|
+
directives: [{ fmt: "level int depth sym name sym up sym down" }],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const playerPropertySpec: FileSpec = {
|
|
55
|
+
name: "player_property",
|
|
56
|
+
upstream: ["src/init.c"],
|
|
57
|
+
recordStart: "type",
|
|
58
|
+
directives: [
|
|
59
|
+
{ fmt: "type str type" },
|
|
60
|
+
{ fmt: "code str code" },
|
|
61
|
+
{ fmt: "desc str desc", repeat: true },
|
|
62
|
+
{ fmt: "name str desc" },
|
|
63
|
+
{ fmt: "value int value" },
|
|
64
|
+
{ fmt: "bindui sym ui int aux sym uival" },
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const namesSpec: FileSpec = {
|
|
69
|
+
name: "names",
|
|
70
|
+
upstream: ["src/init.c"],
|
|
71
|
+
recordStart: "section",
|
|
72
|
+
directives: [
|
|
73
|
+
{ fmt: "section uint section" },
|
|
74
|
+
{ fmt: "word str name", repeat: true },
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const trapSpec: FileSpec = {
|
|
79
|
+
name: "trap",
|
|
80
|
+
upstream: ["src/init.c"],
|
|
81
|
+
recordStart: "name",
|
|
82
|
+
directives: [
|
|
83
|
+
{ fmt: "name sym name str desc" },
|
|
84
|
+
{ fmt: "graphics char glyph sym color" },
|
|
85
|
+
{ fmt: "appear uint rarity uint mindepth uint maxnum" },
|
|
86
|
+
{ fmt: "visibility str visibility" },
|
|
87
|
+
{ fmt: "flags ?str flags", repeat: true },
|
|
88
|
+
{ fmt: "effect sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
89
|
+
{ fmt: "effect-yx int y int x", childOf: ["effect"] },
|
|
90
|
+
{ fmt: "dice str dice", childOf: ["effect"] },
|
|
91
|
+
{ fmt: "expr sym name sym base str expr", childOf: ["effect"], repeat: true },
|
|
92
|
+
{ fmt: "effect-xtra sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
93
|
+
{ fmt: "effect-yx-xtra int y int x", childOf: ["effect-xtra"] },
|
|
94
|
+
{ fmt: "dice-xtra str dice", childOf: ["effect-xtra"] },
|
|
95
|
+
{ fmt: "expr-xtra sym name sym base str expr", childOf: ["effect-xtra"], repeat: true },
|
|
96
|
+
{ fmt: "save str flags" },
|
|
97
|
+
{ fmt: "desc str text", repeat: true },
|
|
98
|
+
{ fmt: "msg str text", repeat: true },
|
|
99
|
+
{ fmt: "msg-good str text", repeat: true },
|
|
100
|
+
{ fmt: "msg-bad str text", repeat: true },
|
|
101
|
+
{ fmt: "msg-xtra str text", repeat: true },
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const terrainSpec: FileSpec = {
|
|
106
|
+
name: "terrain",
|
|
107
|
+
upstream: ["src/init.c"],
|
|
108
|
+
recordStart: "code",
|
|
109
|
+
directives: [
|
|
110
|
+
{ fmt: "code str code" },
|
|
111
|
+
/* parse_feat_name returns PARSE_ERROR_REPEATED_DIRECTIVE when f->name is set
|
|
112
|
+
* (init.c:2059-2060). */
|
|
113
|
+
{ fmt: "name str name", rejectRepeated: () => true },
|
|
114
|
+
{ fmt: "graphics char glyph sym color" },
|
|
115
|
+
{ fmt: "mimic str feat" },
|
|
116
|
+
{ fmt: "priority uint priority" },
|
|
117
|
+
{ fmt: "flags ?str flags", repeat: true },
|
|
118
|
+
{ fmt: "digging int dig" },
|
|
119
|
+
{ fmt: "desc str text", repeat: true },
|
|
120
|
+
{ fmt: "walk-msg str text", repeat: true },
|
|
121
|
+
{ fmt: "run-msg str text", repeat: true },
|
|
122
|
+
{ fmt: "hurt-msg str text", repeat: true },
|
|
123
|
+
{ fmt: "die-msg str text", repeat: true },
|
|
124
|
+
{ fmt: "confused-msg str text", repeat: true },
|
|
125
|
+
{ fmt: "look-prefix str text", repeat: true },
|
|
126
|
+
{ fmt: "look-in-preposition str text", repeat: true },
|
|
127
|
+
{ fmt: "resist-flag sym flag", repeat: true },
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const bodySpec: FileSpec = {
|
|
132
|
+
name: "body",
|
|
133
|
+
upstream: ["src/init.c"],
|
|
134
|
+
recordStart: "body",
|
|
135
|
+
directives: [
|
|
136
|
+
{ fmt: "body str name" },
|
|
137
|
+
{ fmt: "slot sym slot sym name", repeat: true },
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const historySpec: FileSpec = {
|
|
142
|
+
name: "history",
|
|
143
|
+
upstream: ["src/init.c"],
|
|
144
|
+
recordStart: "chart",
|
|
145
|
+
directives: [
|
|
146
|
+
{ fmt: "chart uint chart int next int roll" },
|
|
147
|
+
{ fmt: "phrase str text", repeat: true },
|
|
148
|
+
],
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const pRaceSpec: FileSpec = {
|
|
152
|
+
name: "p_race",
|
|
153
|
+
upstream: ["src/init.c"],
|
|
154
|
+
recordStart: "name",
|
|
155
|
+
directives: [
|
|
156
|
+
{ fmt: "name str name" },
|
|
157
|
+
{ fmt: "stats int str int int int wis int dex int con" },
|
|
158
|
+
{ fmt: "skill-disarm-phys int disarm" },
|
|
159
|
+
{ fmt: "skill-disarm-magic int disarm" },
|
|
160
|
+
{ fmt: "skill-device int device" },
|
|
161
|
+
{ fmt: "skill-save int save" },
|
|
162
|
+
{ fmt: "skill-stealth int stealth" },
|
|
163
|
+
{ fmt: "skill-search int search" },
|
|
164
|
+
{ fmt: "skill-melee int melee" },
|
|
165
|
+
{ fmt: "skill-shoot int shoot" },
|
|
166
|
+
{ fmt: "skill-throw int throw" },
|
|
167
|
+
{ fmt: "skill-dig int dig" },
|
|
168
|
+
{ fmt: "hitdie int mhp" },
|
|
169
|
+
{ fmt: "exp int exp" },
|
|
170
|
+
{ fmt: "infravision int infra" },
|
|
171
|
+
{ fmt: "history uint hist" },
|
|
172
|
+
{ fmt: "age int base_age int mod_age" },
|
|
173
|
+
{ fmt: "height int base_hgt int mod_hgt" },
|
|
174
|
+
{ fmt: "weight int base_wgt int mod_wgt" },
|
|
175
|
+
{ fmt: "obj-flags ?str flags", repeat: true },
|
|
176
|
+
{ fmt: "player-flags ?str flags", repeat: true },
|
|
177
|
+
{ fmt: "values str values", repeat: true },
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const realmSpec: FileSpec = {
|
|
182
|
+
name: "realm",
|
|
183
|
+
upstream: ["src/init.c"],
|
|
184
|
+
recordStart: "name",
|
|
185
|
+
directives: [
|
|
186
|
+
{ fmt: "name str name" },
|
|
187
|
+
{ fmt: "stat sym stat" },
|
|
188
|
+
{ fmt: "verb str verb" },
|
|
189
|
+
{ fmt: "spell-noun str spell" },
|
|
190
|
+
{ fmt: "book-noun str book" },
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const shapeSpec: FileSpec = {
|
|
195
|
+
name: "shape",
|
|
196
|
+
upstream: ["src/init.c"],
|
|
197
|
+
recordStart: "name",
|
|
198
|
+
directives: [
|
|
199
|
+
{ fmt: "name str name" },
|
|
200
|
+
{ fmt: "combat int to-h int to-d int to-a" },
|
|
201
|
+
{ fmt: "skill-disarm-phys int disarm" },
|
|
202
|
+
{ fmt: "skill-disarm-magic int disarm" },
|
|
203
|
+
{ fmt: "skill-save int save" },
|
|
204
|
+
{ fmt: "skill-stealth int stealth" },
|
|
205
|
+
{ fmt: "skill-search int search" },
|
|
206
|
+
{ fmt: "skill-melee int melee" },
|
|
207
|
+
{ fmt: "skill-throw int throw" },
|
|
208
|
+
{ fmt: "skill-dig int dig" },
|
|
209
|
+
{ fmt: "obj-flags ?str flags", repeat: true },
|
|
210
|
+
{ fmt: "player-flags ?str flags", repeat: true },
|
|
211
|
+
{ fmt: "values str values", repeat: true },
|
|
212
|
+
{ fmt: "effect sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
213
|
+
{ fmt: "effect-yx int y int x", childOf: ["effect"] },
|
|
214
|
+
{ fmt: "dice str dice", childOf: ["effect"] },
|
|
215
|
+
{ fmt: "expr sym name sym base str expr", childOf: ["effect"], repeat: true },
|
|
216
|
+
{ fmt: "effect-msg str text", childOf: ["effect"], repeat: true },
|
|
217
|
+
{ fmt: "blow str blow", repeat: true },
|
|
218
|
+
],
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export const classSpec: FileSpec = {
|
|
222
|
+
name: "class",
|
|
223
|
+
upstream: ["src/init.c"],
|
|
224
|
+
recordStart: "name",
|
|
225
|
+
directives: [
|
|
226
|
+
{ fmt: "name str name" },
|
|
227
|
+
{ fmt: "stats int str int int int wis int dex int con" },
|
|
228
|
+
{ fmt: "skill-disarm-phys int base int incr" },
|
|
229
|
+
{ fmt: "skill-disarm-magic int base int incr" },
|
|
230
|
+
{ fmt: "skill-device int base int incr" },
|
|
231
|
+
{ fmt: "skill-save int base int incr" },
|
|
232
|
+
{ fmt: "skill-stealth int base int incr" },
|
|
233
|
+
{ fmt: "skill-search int base int incr" },
|
|
234
|
+
{ fmt: "skill-melee int base int incr" },
|
|
235
|
+
{ fmt: "skill-shoot int base int incr" },
|
|
236
|
+
{ fmt: "skill-throw int base int incr" },
|
|
237
|
+
{ fmt: "skill-dig int base int incr" },
|
|
238
|
+
{ fmt: "hitdie int mhp" },
|
|
239
|
+
{ fmt: "exp int exp" },
|
|
240
|
+
{ fmt: "max-attacks int max-attacks" },
|
|
241
|
+
{ fmt: "min-weight int min-weight" },
|
|
242
|
+
{ fmt: "strength-multiplier int att-multiply" },
|
|
243
|
+
{ fmt: "title str title", repeat: true },
|
|
244
|
+
{ fmt: "equip sym tval sym sval uint min uint max sym eopts", repeat: true },
|
|
245
|
+
{ fmt: "obj-flags ?str flags", repeat: true },
|
|
246
|
+
{ fmt: "player-flags ?str flags", repeat: true },
|
|
247
|
+
/* parse_class_magic rejects once c->magic.books is non-NULL
|
|
248
|
+
* (init.c:3714-3716). */
|
|
249
|
+
{ fmt: "magic uint first uint weight uint books", rejectRepeated: (prior) =>
|
|
250
|
+
(prior as { books?: number }).books !== 0 },
|
|
251
|
+
{
|
|
252
|
+
fmt: "book sym tval sym quality sym name uint spells str realm",
|
|
253
|
+
repeat: true,
|
|
254
|
+
/* parse_class_book checks the allocated magic-book capacity after tval
|
|
255
|
+
* resolution (init.c:3735-3746). The registry-dependent tval half is
|
|
256
|
+
* intentionally deferred; this structural half is available here. */
|
|
257
|
+
validate: ({ record }) => {
|
|
258
|
+
const magic = record.magic as { books?: number } | undefined;
|
|
259
|
+
const books = (record.book as unknown[] | undefined)?.length ?? 0;
|
|
260
|
+
return magic === undefined || books >= (magic.books ?? 0)
|
|
261
|
+
? "TOO_MANY_ENTRIES"
|
|
262
|
+
: undefined;
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{ fmt: "book-graphics char glyph sym color", childOf: ["book"], requireParent: true },
|
|
266
|
+
{
|
|
267
|
+
fmt: "book-properties int cost int common str minmax",
|
|
268
|
+
childOf: ["book"],
|
|
269
|
+
requireParent: true,
|
|
270
|
+
/* grab_int_range(..., "to") failures are INVALID_ALLOCATION
|
|
271
|
+
* (init.c:3823-3826). */
|
|
272
|
+
validate: ({ values }) =>
|
|
273
|
+
validIntRange(String(values.minmax))
|
|
274
|
+
? undefined
|
|
275
|
+
: "INVALID_ALLOCATION",
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
fmt: "spell sym name int level int mana int fail int exp",
|
|
279
|
+
childOf: ["book"],
|
|
280
|
+
orphanError: "TOO_MANY_ENTRIES",
|
|
281
|
+
repeat: true,
|
|
282
|
+
/* parse_class_spell uses the current book's declared spell capacity
|
|
283
|
+
* (init.c:3842-3854). */
|
|
284
|
+
validate: ({ target }) => {
|
|
285
|
+
const spells = (target.spell as unknown[] | undefined)?.length ?? 0;
|
|
286
|
+
return spells >= Number(target.spells) ? "TOO_MANY_ENTRIES" : undefined;
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
/* parse_class_effect requires a preceding spell (and therefore a book and
|
|
290
|
+
* magic), while its effect-detail successors intentionally tolerate a
|
|
291
|
+
* missing effect (init.c:3877-3905, 3925-3939). */
|
|
292
|
+
{
|
|
293
|
+
fmt: "effect sym eff ?sym type ?int radius ?int other",
|
|
294
|
+
childOf: ["spell"],
|
|
295
|
+
requireParent: true,
|
|
296
|
+
repeat: true,
|
|
297
|
+
},
|
|
298
|
+
{ fmt: "effect-yx int y int x", childOf: ["effect"] },
|
|
299
|
+
{ fmt: "dice str dice", childOf: ["effect"] },
|
|
300
|
+
{ fmt: "expr sym name sym base str expr", childOf: ["effect"], repeat: true },
|
|
301
|
+
{ fmt: "effect-msg str text", childOf: ["effect"], repeat: true },
|
|
302
|
+
{ fmt: "desc str desc", childOf: ["spell"], requireParent: true, repeat: true },
|
|
303
|
+
],
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export const flavorSpec: FileSpec = {
|
|
307
|
+
name: "flavor",
|
|
308
|
+
upstream: ["src/init.c"],
|
|
309
|
+
recordStart: "kind",
|
|
310
|
+
directives: [
|
|
311
|
+
{ fmt: "kind sym tval char glyph" },
|
|
312
|
+
{ fmt: "flavor uint index sym attr ?str desc", repeat: true },
|
|
313
|
+
{ fmt: "fixed uint index sym sval sym attr ?str desc", repeat: true },
|
|
314
|
+
],
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export const hintsSpec: FileSpec = {
|
|
318
|
+
name: "hints",
|
|
319
|
+
upstream: ["src/init.c"],
|
|
320
|
+
recordStart: "H",
|
|
321
|
+
directives: [{ fmt: "H str text" }],
|
|
322
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specs for gamedata files whose upstream parsers live in single-purpose
|
|
3
|
+
* sources: summon (src/mon-summon.c), chest_trap (src/obj-chest.c), quest
|
|
4
|
+
* (src/player-quest.c), player_timed (src/player-timed.c), store
|
|
5
|
+
* (src/store.c).
|
|
6
|
+
*
|
|
7
|
+
* Format strings are copied verbatim from the parser_reg() calls.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { FileSpec } from "../records.js";
|
|
11
|
+
|
|
12
|
+
export const summonSpec: FileSpec = {
|
|
13
|
+
name: "summon",
|
|
14
|
+
upstream: ["src/mon-summon.c"],
|
|
15
|
+
recordStart: "name",
|
|
16
|
+
directives: [
|
|
17
|
+
{ fmt: "name str name" },
|
|
18
|
+
{ fmt: "msgt sym type" },
|
|
19
|
+
{ fmt: "uniques int allowed" },
|
|
20
|
+
{ fmt: "base sym base", repeat: true },
|
|
21
|
+
{ fmt: "race-flag sym flag" },
|
|
22
|
+
{ fmt: "fallback str fallback" },
|
|
23
|
+
{ fmt: "desc str desc" },
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const chestTrapSpec: FileSpec = {
|
|
28
|
+
name: "chest_trap",
|
|
29
|
+
upstream: ["src/obj-chest.c"],
|
|
30
|
+
recordStart: "name",
|
|
31
|
+
directives: [
|
|
32
|
+
{ fmt: "name str name" },
|
|
33
|
+
{ fmt: "code str code" },
|
|
34
|
+
{ fmt: "level int level" },
|
|
35
|
+
{ fmt: "effect sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
36
|
+
{ fmt: "dice str dice", childOf: ["effect"] },
|
|
37
|
+
{ fmt: "expr sym name sym base str expr", childOf: ["effect"], repeat: true },
|
|
38
|
+
{ fmt: "destroy int val" },
|
|
39
|
+
{ fmt: "magic int val" },
|
|
40
|
+
{ fmt: "msg str text", repeat: true },
|
|
41
|
+
{ fmt: "msg-death str text", repeat: true },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const questSpec: FileSpec = {
|
|
46
|
+
name: "quest",
|
|
47
|
+
upstream: ["src/player-quest.c"],
|
|
48
|
+
recordStart: "name",
|
|
49
|
+
directives: [
|
|
50
|
+
{ fmt: "name str name" },
|
|
51
|
+
{ fmt: "level uint level" },
|
|
52
|
+
{ fmt: "race str race" },
|
|
53
|
+
{ fmt: "number uint number" },
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* player_timed.txt: the effect-* directives attach to whichever of
|
|
59
|
+
* on-begin-effect / on-end-effect was seen most recently, mirroring the
|
|
60
|
+
* upstream parse state.
|
|
61
|
+
*/
|
|
62
|
+
export const playerTimedSpec: FileSpec = {
|
|
63
|
+
name: "player_timed",
|
|
64
|
+
upstream: ["src/player-timed.c"],
|
|
65
|
+
recordStart: "name",
|
|
66
|
+
directives: [
|
|
67
|
+
{ fmt: "name str name" },
|
|
68
|
+
{ fmt: "desc str text", repeat: true },
|
|
69
|
+
{ fmt: "on-end str text", repeat: true },
|
|
70
|
+
{ fmt: "on-increase str text", repeat: true },
|
|
71
|
+
{ fmt: "on-decrease str text", repeat: true },
|
|
72
|
+
{ fmt: "msgt sym type" },
|
|
73
|
+
{ fmt: "fail uint code str flag", repeat: true },
|
|
74
|
+
{ fmt: "grade sym color int max sym name sym up_msg ?sym down_msg", repeat: true },
|
|
75
|
+
{ fmt: "resist sym elem" },
|
|
76
|
+
{ fmt: "brand sym name", repeat: true },
|
|
77
|
+
{ fmt: "slay sym name", repeat: true },
|
|
78
|
+
{ fmt: "flag-synonym sym code int exact", repeat: true },
|
|
79
|
+
{ fmt: "on-begin-effect sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
80
|
+
{ fmt: "on-end-effect sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
81
|
+
/* Unlike class.txt / object.txt / trap.txt, all four of player-timed.c's
|
|
82
|
+
* effect-detail handlers return PARSE_ERROR_MISSING_RECORD_HEADER when
|
|
83
|
+
* ps->e is NULL (player-timed.c L480, L496, L524, L557) instead of
|
|
84
|
+
* tolerating the orphan - hence requireParent (ptimed.c
|
|
85
|
+
* test_missing_effect0). `effect-dice` also dice_free()s any previous
|
|
86
|
+
* dice (L503-505), so a repeat is legal and the last wins
|
|
87
|
+
* (ptimed.c test_effectdice0). */
|
|
88
|
+
{
|
|
89
|
+
fmt: "effect-yx int y int x",
|
|
90
|
+
childOf: ["on-begin-effect", "on-end-effect"],
|
|
91
|
+
requireParent: true,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
fmt: "effect-dice str dice",
|
|
95
|
+
childOf: ["on-begin-effect", "on-end-effect"],
|
|
96
|
+
requireParent: true,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
fmt: "effect-expr sym name sym base str expr",
|
|
100
|
+
childOf: ["on-begin-effect", "on-end-effect"],
|
|
101
|
+
requireParent: true,
|
|
102
|
+
repeat: true,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
fmt: "effect-msg str text",
|
|
106
|
+
childOf: ["on-begin-effect", "on-end-effect"],
|
|
107
|
+
requireParent: true,
|
|
108
|
+
repeat: true,
|
|
109
|
+
},
|
|
110
|
+
{ fmt: "flags ?str flags", repeat: true },
|
|
111
|
+
{ fmt: "lower-bound int bound" },
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* store.txt: the grammar half of parse_store (store.c:132) and its sibling
|
|
117
|
+
* directive handlers. The semantic half - resolving the entrance feature, the
|
|
118
|
+
* owners and the stocking tables - is packages/core/src/store/bind.ts bindStore.
|
|
119
|
+
*/
|
|
120
|
+
export const storeSpec: FileSpec = {
|
|
121
|
+
name: "store",
|
|
122
|
+
upstream: ["src/store.c"],
|
|
123
|
+
recordStart: "store",
|
|
124
|
+
directives: [
|
|
125
|
+
{ fmt: "store str feat" },
|
|
126
|
+
{ fmt: "owner uint purse str name", repeat: true },
|
|
127
|
+
{ fmt: "slots uint min uint max" },
|
|
128
|
+
{ fmt: "turnover uint turnover" },
|
|
129
|
+
{ fmt: "normal sym tval sym sval", repeat: true },
|
|
130
|
+
{ fmt: "always sym tval ?sym sval", repeat: true },
|
|
131
|
+
{ fmt: "buy str base", repeat: true },
|
|
132
|
+
{ fmt: "buy-flag sym flag str base", repeat: true },
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* ui_knowledge.txt: the thematic monster-knowledge categories for the '~' ->
|
|
138
|
+
* Monsters browser (upstream ui-knowledge.c init_ui_knowledge_parser). Each
|
|
139
|
+
* 'monster-category' begins a category; the mcat-include-* directives attach
|
|
140
|
+
* to it. The reserved "***Unclassified***" catch-all is appended by the
|
|
141
|
+
* consumer, not the file (finish_ui_knowledge_parser).
|
|
142
|
+
*/
|
|
143
|
+
export const uiKnowledgeSpec: FileSpec = {
|
|
144
|
+
name: "ui_knowledge",
|
|
145
|
+
upstream: ["src/ui-knowledge.c"],
|
|
146
|
+
recordStart: "monster-category",
|
|
147
|
+
directives: [
|
|
148
|
+
{ fmt: "monster-category str name" },
|
|
149
|
+
{ fmt: "mcat-include-base str name", repeat: true },
|
|
150
|
+
{ fmt: "mcat-include-flag ?str flags", repeat: true },
|
|
151
|
+
{ fmt: "mcat-include-other str name", repeat: true },
|
|
152
|
+
],
|
|
153
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specs for the gamedata files whose upstream parsers live in
|
|
3
|
+
* src/mon-init.c: blow_methods (meth_parser), blow_effects (eff_parser),
|
|
4
|
+
* pain, monster_spell, monster_base, monster, pit.
|
|
5
|
+
*
|
|
6
|
+
* Format strings are copied verbatim from the parser_reg() calls.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { FileSpec } from "../records.js";
|
|
10
|
+
|
|
11
|
+
export const blowMethodsSpec: FileSpec = {
|
|
12
|
+
name: "blow_methods",
|
|
13
|
+
upstream: ["src/mon-init.c"],
|
|
14
|
+
recordStart: "name",
|
|
15
|
+
directives: [
|
|
16
|
+
{ fmt: "name str name" },
|
|
17
|
+
{ fmt: "cut uint cut" },
|
|
18
|
+
{ fmt: "stun uint stun" },
|
|
19
|
+
{ fmt: "miss uint miss" },
|
|
20
|
+
{ fmt: "phys uint phys" },
|
|
21
|
+
{ fmt: "msg ?str msg" },
|
|
22
|
+
{ fmt: "act str act", repeat: true },
|
|
23
|
+
{ fmt: "desc str desc", repeat: true },
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const blowEffectsSpec: FileSpec = {
|
|
28
|
+
name: "blow_effects",
|
|
29
|
+
upstream: ["src/mon-init.c"],
|
|
30
|
+
recordStart: "name",
|
|
31
|
+
directives: [
|
|
32
|
+
{ fmt: "name str name" },
|
|
33
|
+
{ fmt: "power int power" },
|
|
34
|
+
{ fmt: "eval int eval" },
|
|
35
|
+
{ fmt: "desc str desc", repeat: true },
|
|
36
|
+
{ fmt: "lore-color-base sym color" },
|
|
37
|
+
{ fmt: "lore-color-resist sym color" },
|
|
38
|
+
{ fmt: "lore-color-immune sym color" },
|
|
39
|
+
{ fmt: "effect-type str type" },
|
|
40
|
+
{ fmt: "resist str resist" },
|
|
41
|
+
{ fmt: "lash-type str type" },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const painSpec: FileSpec = {
|
|
46
|
+
name: "pain",
|
|
47
|
+
upstream: ["src/mon-init.c"],
|
|
48
|
+
recordStart: "type",
|
|
49
|
+
directives: [
|
|
50
|
+
{ fmt: "type uint index" },
|
|
51
|
+
{ fmt: "message str message", repeat: true },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* monster_spell.txt: each spell has an implicit first "level"; the
|
|
57
|
+
* power-cutoff directive starts another level, and the lore/message
|
|
58
|
+
* directives attach to the most recent level (the record itself until the
|
|
59
|
+
* first power-cutoff appears).
|
|
60
|
+
*/
|
|
61
|
+
export const monsterSpellSpec: FileSpec = {
|
|
62
|
+
name: "monster_spell",
|
|
63
|
+
upstream: ["src/mon-init.c"],
|
|
64
|
+
recordStart: "name",
|
|
65
|
+
directives: [
|
|
66
|
+
{ fmt: "name str name" },
|
|
67
|
+
{ fmt: "msgt sym type" },
|
|
68
|
+
{ fmt: "hit uint hit" },
|
|
69
|
+
{ fmt: "effect sym eff ?sym type ?int radius ?int other", repeat: true },
|
|
70
|
+
{ fmt: "effect-yx int y int x", childOf: ["effect"] },
|
|
71
|
+
{ fmt: "dice str dice", childOf: ["effect"] },
|
|
72
|
+
{ fmt: "expr sym name sym base str expr", childOf: ["effect"], repeat: true },
|
|
73
|
+
{ fmt: "power-cutoff int power", repeat: true },
|
|
74
|
+
{ fmt: "lore str text", childOf: ["power-cutoff"], repeat: true },
|
|
75
|
+
{ fmt: "lore-color-base sym color", childOf: ["power-cutoff"] },
|
|
76
|
+
{ fmt: "lore-color-resist sym color", childOf: ["power-cutoff"] },
|
|
77
|
+
{ fmt: "lore-color-immune sym color", childOf: ["power-cutoff"] },
|
|
78
|
+
{ fmt: "message-vis str text", childOf: ["power-cutoff"], repeat: true },
|
|
79
|
+
{ fmt: "message-invis str text", childOf: ["power-cutoff"], repeat: true },
|
|
80
|
+
{ fmt: "message-miss str text", childOf: ["power-cutoff"], repeat: true },
|
|
81
|
+
{ fmt: "message-save str text", childOf: ["power-cutoff"], repeat: true },
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const monsterBaseSpec: FileSpec = {
|
|
86
|
+
name: "monster_base",
|
|
87
|
+
upstream: ["src/mon-init.c"],
|
|
88
|
+
recordStart: "name",
|
|
89
|
+
directives: [
|
|
90
|
+
{ fmt: "name str name" },
|
|
91
|
+
{ fmt: "glyph char glyph" },
|
|
92
|
+
{ fmt: "pain uint pain" },
|
|
93
|
+
{ fmt: "flags ?str flags", repeat: true },
|
|
94
|
+
{ fmt: "desc str desc", repeat: true },
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const monsterSpec: FileSpec = {
|
|
99
|
+
name: "monster",
|
|
100
|
+
upstream: ["src/mon-init.c"],
|
|
101
|
+
recordStart: "name",
|
|
102
|
+
directives: [
|
|
103
|
+
{ fmt: "name str name" },
|
|
104
|
+
{ fmt: "plural ?str plural" },
|
|
105
|
+
{ fmt: "base sym base" },
|
|
106
|
+
{ fmt: "glyph char glyph" },
|
|
107
|
+
{ fmt: "color sym color" },
|
|
108
|
+
{ fmt: "speed int speed" },
|
|
109
|
+
{ fmt: "hit-points int hp" },
|
|
110
|
+
{ fmt: "light int light" },
|
|
111
|
+
{ fmt: "hearing int hearing" },
|
|
112
|
+
{ fmt: "smell int smell" },
|
|
113
|
+
{ fmt: "armor-class int ac" },
|
|
114
|
+
{ fmt: "sleepiness int sleep" },
|
|
115
|
+
{ fmt: "depth int level" },
|
|
116
|
+
{ fmt: "rarity int rarity" },
|
|
117
|
+
{ fmt: "experience int mexp" },
|
|
118
|
+
{ fmt: "blow sym method ?sym effect ?rand damage", repeat: true },
|
|
119
|
+
{ fmt: "flags ?str flags", repeat: true },
|
|
120
|
+
{ fmt: "flags-off ?str flags", repeat: true },
|
|
121
|
+
{ fmt: "desc str desc", repeat: true },
|
|
122
|
+
{ fmt: "innate-freq int freq" },
|
|
123
|
+
{ fmt: "spell-freq int freq" },
|
|
124
|
+
{ fmt: "spell-power uint power" },
|
|
125
|
+
{ fmt: "spells str spells", repeat: true },
|
|
126
|
+
{ fmt: "message-vis sym spell ?str message", repeat: true },
|
|
127
|
+
{ fmt: "message-invis sym spell ?str message", repeat: true },
|
|
128
|
+
{ fmt: "message-miss sym spell ?str message", repeat: true },
|
|
129
|
+
{
|
|
130
|
+
fmt: "drop sym tval sym sval uint chance uint min uint max",
|
|
131
|
+
repeat: true,
|
|
132
|
+
orderKey: "drop-order",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
fmt: "drop-base sym tval uint chance uint min uint max",
|
|
136
|
+
repeat: true,
|
|
137
|
+
orderKey: "drop-order",
|
|
138
|
+
},
|
|
139
|
+
{ fmt: "friends uint chance rand number sym name ?sym role", repeat: true },
|
|
140
|
+
{ fmt: "friends-base uint chance rand number sym name ?sym role", repeat: true },
|
|
141
|
+
{ fmt: "mimic sym tval sym sval", repeat: true },
|
|
142
|
+
{ fmt: "shape str name", repeat: true },
|
|
143
|
+
{ fmt: "color-cycle sym group sym cycle" },
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const pitSpec: FileSpec = {
|
|
148
|
+
name: "pit",
|
|
149
|
+
upstream: ["src/mon-init.c"],
|
|
150
|
+
recordStart: "name",
|
|
151
|
+
directives: [
|
|
152
|
+
{ fmt: "name str name" },
|
|
153
|
+
{ fmt: "room uint type" },
|
|
154
|
+
{ fmt: "alloc uint rarity uint level" },
|
|
155
|
+
{ fmt: "obj-rarity uint obj_rarity" },
|
|
156
|
+
{ fmt: "mon-base sym base", repeat: true },
|
|
157
|
+
{ fmt: "mon-ban sym race", repeat: true },
|
|
158
|
+
{ fmt: "color sym color", repeat: true },
|
|
159
|
+
{ fmt: "flags-req ?str flags", repeat: true },
|
|
160
|
+
{ fmt: "flags-ban ?str flags", repeat: true },
|
|
161
|
+
{ fmt: "innate-freq int freq" },
|
|
162
|
+
{ fmt: "spell-req ?str spells", repeat: true },
|
|
163
|
+
{ fmt: "spell-ban ?str spells", repeat: true },
|
|
164
|
+
],
|
|
165
|
+
};
|