@spyglassmc/java-edition 0.3.7 → 0.3.9
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/lib/binder/index.d.ts +11 -9
- package/lib/binder/index.js +149 -150
- package/lib/common/index.js +6 -9
- package/lib/dependency/common.d.ts +5 -0
- package/lib/dependency/common.js +8 -0
- package/lib/dependency/index.js +7 -17
- package/lib/dependency/mcmeta.d.ts +6 -12
- package/lib/dependency/mcmeta.js +21 -38
- package/lib/index.d.ts +1 -0
- package/lib/index.js +74 -32
- package/lib/json/checker/index.d.ts +3 -10
- package/lib/json/checker/index.js +36 -244
- package/lib/json/index.d.ts +0 -1
- package/lib/json/index.js +0 -3
- package/lib/mcfunction/checker/index.d.ts +0 -2
- package/lib/mcfunction/checker/index.js +254 -183
- package/lib/mcfunction/common/index.d.ts +4 -2
- package/lib/mcfunction/common/index.js +56 -52
- package/lib/mcfunction/completer/argument.js +112 -57
- package/lib/mcfunction/index.d.ts +3 -2
- package/lib/mcfunction/index.js +18 -19
- package/lib/mcfunction/inlayHintProvider.js +2 -3
- package/lib/mcfunction/mcdocAttributes.d.ts +4 -0
- package/lib/mcfunction/mcdocAttributes.js +71 -0
- package/lib/mcfunction/node/argument.d.ts +115 -12
- package/lib/mcfunction/node/argument.js +131 -63
- package/lib/mcfunction/parser/argument.d.ts +14 -4
- package/lib/mcfunction/parser/argument.js +380 -212
- package/lib/mcfunction/signatureHelpProvider.d.ts +2 -1
- package/lib/mcfunction/signatureHelpProvider.js +10 -18
- package/lib/mcfunction/tree/argument.d.ts +68 -1
- package/lib/mcfunction/tree/patch.js +279 -77
- package/lib/mcfunction/tree/patchValidator.d.ts +7 -0
- package/lib/mcfunction/tree/patchValidator.js +25 -0
- package/package.json +8 -9
|
@@ -5,8 +5,8 @@ import { localeQuote, localize } from '@spyglassmc/locales';
|
|
|
5
5
|
import * as mcf from '@spyglassmc/mcfunction';
|
|
6
6
|
import * as nbt from '@spyglassmc/nbt';
|
|
7
7
|
import { ReleaseVersion } from '../../dependency/index.js';
|
|
8
|
-
import { ColorArgumentValues, EntityAnchorArgumentValues, GamemodeArgumentValues,
|
|
9
|
-
import { BlockStatesNode, EntitySelectorArgumentsNode, EntitySelectorAtVariable,
|
|
8
|
+
import { ColorArgumentValues, EntityAnchorArgumentValues, GamemodeArgumentValues, getItemSlotArgumentValues, getItemSlotsArgumentValues, getScoreboardSlotArgumentValues, HeightmapValues, MirrorValues, OperationArgumentValues, RotationValues, SwizzleArgumentValues, } from '../common/index.js';
|
|
9
|
+
import { BlockStatesNode, ComponentListNode, ComponentTestsNode, EntitySelectorArgumentsNode, EntitySelectorAtVariable, EntitySelectorNode, ObjectiveCriteriaNode, TimeNode, } from '../node/index.js';
|
|
10
10
|
const IntegerPattern = /^-?\d+$/;
|
|
11
11
|
/**
|
|
12
12
|
* A combination of:
|
|
@@ -37,6 +37,10 @@ function shouldValidateLength(ctx) {
|
|
|
37
37
|
const release = ctx.project['loadedVersion'];
|
|
38
38
|
return !release || ReleaseVersion.cmp(release, '1.18') < 0;
|
|
39
39
|
}
|
|
40
|
+
function shouldUseOldItemStackFormat(ctx) {
|
|
41
|
+
const release = ctx.project['loadedVersion'];
|
|
42
|
+
return !release || ReleaseVersion.cmp(release, '1.20.5') < 0;
|
|
43
|
+
}
|
|
40
44
|
/**
|
|
41
45
|
* @returns The parser for the specified argument tree node. All argument parsers used in the `mcfunction` package
|
|
42
46
|
* fail on empty input.
|
|
@@ -83,26 +87,19 @@ export const argument = (rawTreeNode) => {
|
|
|
83
87
|
case 'minecraft:column_pos':
|
|
84
88
|
return wrap(vector({ dimension: 2, integersOnly: true }));
|
|
85
89
|
case 'minecraft:component':
|
|
86
|
-
return wrap(
|
|
90
|
+
return wrap(jsonParser('::java::server::util::text::Text'));
|
|
87
91
|
case 'minecraft:dimension':
|
|
88
|
-
return wrap(core.resourceLocation({
|
|
89
|
-
category: 'dimension',
|
|
90
|
-
}));
|
|
92
|
+
return wrap(core.resourceLocation({ category: 'dimension' }));
|
|
91
93
|
case 'minecraft:entity':
|
|
92
94
|
return wrap(entity(treeNode.properties.amount, treeNode.properties.type));
|
|
93
95
|
case 'minecraft:entity_anchor':
|
|
94
96
|
return wrap(core.literal(...EntityAnchorArgumentValues));
|
|
95
97
|
case 'minecraft:entity_summon':
|
|
96
|
-
return wrap(core.resourceLocation({
|
|
97
|
-
category: 'entity_type',
|
|
98
|
-
}));
|
|
98
|
+
return wrap(core.resourceLocation({ category: 'entity_type' }));
|
|
99
99
|
case 'minecraft:float_range':
|
|
100
100
|
return wrap(range('float'));
|
|
101
101
|
case 'minecraft:function':
|
|
102
|
-
return wrap(core.resourceLocation({
|
|
103
|
-
category: 'function',
|
|
104
|
-
allowTag: true,
|
|
105
|
-
}));
|
|
102
|
+
return wrap(core.resourceLocation({ category: 'function', allowTag: true }));
|
|
106
103
|
case 'minecraft:gamemode':
|
|
107
104
|
return wrap(core.literal(...GamemodeArgumentValues));
|
|
108
105
|
case 'minecraft:game_profile':
|
|
@@ -112,27 +109,31 @@ export const argument = (rawTreeNode) => {
|
|
|
112
109
|
case 'minecraft:int_range':
|
|
113
110
|
return wrap(range('integer'));
|
|
114
111
|
case 'minecraft:item_enchantment':
|
|
115
|
-
return wrap(core.resourceLocation({
|
|
116
|
-
category: 'enchantment',
|
|
117
|
-
}));
|
|
112
|
+
return wrap(core.resourceLocation({ category: 'enchantment' }));
|
|
118
113
|
case 'minecraft:item_predicate':
|
|
119
114
|
return wrap(itemPredicate);
|
|
120
115
|
case 'minecraft:item_slot':
|
|
121
|
-
return wrap(
|
|
116
|
+
return wrap(itemSlot);
|
|
117
|
+
case 'minecraft:item_slots':
|
|
118
|
+
return wrap(itemSlots);
|
|
122
119
|
case 'minecraft:item_stack':
|
|
123
120
|
return wrap(itemStack);
|
|
121
|
+
case 'minecraft:loot_modifier':
|
|
122
|
+
return wrap(resourceOrInline('item_modifier'));
|
|
123
|
+
case 'minecraft:loot_predicate':
|
|
124
|
+
return wrap(resourceOrInline('predicate'));
|
|
125
|
+
case 'minecraft:loot_table':
|
|
126
|
+
return wrap(resourceOrInline('loot_table'));
|
|
124
127
|
case 'minecraft:message':
|
|
125
128
|
return wrap(message);
|
|
126
129
|
case 'minecraft:mob_effect':
|
|
127
|
-
return wrap(core.resourceLocation({
|
|
128
|
-
category: 'mob_effect',
|
|
129
|
-
}));
|
|
130
|
+
return wrap(core.resourceLocation({ category: 'mob_effect' }));
|
|
130
131
|
case 'minecraft:nbt_compound_tag':
|
|
131
|
-
return wrap(nbt.parser.compound);
|
|
132
|
+
return wrap(nbtParser(nbt.parser.compound, treeNode.properties));
|
|
132
133
|
case 'minecraft:nbt_path':
|
|
133
|
-
return wrap(nbt.parser.path);
|
|
134
|
+
return wrap(nbtPathParser(nbt.parser.path, treeNode.properties));
|
|
134
135
|
case 'minecraft:nbt_tag':
|
|
135
|
-
return wrap(nbt.parser.entry);
|
|
136
|
+
return wrap(nbtParser(nbt.parser.entry, treeNode.properties));
|
|
136
137
|
case 'minecraft:objective':
|
|
137
138
|
return wrap(objective(core.SymbolUsageType.is(treeNode.properties?.usageType)
|
|
138
139
|
? treeNode.properties?.usageType
|
|
@@ -140,32 +141,33 @@ export const argument = (rawTreeNode) => {
|
|
|
140
141
|
case 'minecraft:objective_criteria':
|
|
141
142
|
return wrap(objectiveCriteria);
|
|
142
143
|
case 'minecraft:operation':
|
|
143
|
-
return wrap(core.literal({
|
|
144
|
-
pool: OperationArgumentValues,
|
|
145
|
-
colorTokenType: 'operator',
|
|
146
|
-
}));
|
|
144
|
+
return wrap(core.literal({ pool: OperationArgumentValues, colorTokenType: 'operator' }));
|
|
147
145
|
case 'minecraft:particle':
|
|
148
146
|
return wrap(particle);
|
|
149
147
|
case 'minecraft:resource':
|
|
150
148
|
case 'minecraft:resource_key':
|
|
151
149
|
case 'minecraft:resource_or_tag':
|
|
150
|
+
case 'minecraft:resource_or_tag_key':
|
|
151
|
+
const allowTag = treeNode.parser === 'minecraft:resource_or_tag'
|
|
152
|
+
|| treeNode.parser === 'minecraft:resource_or_tag_key';
|
|
152
153
|
return wrap(core.resourceLocation({
|
|
153
154
|
category: core.ResourceLocation.shorten(treeNode.properties.registry),
|
|
154
|
-
allowTag
|
|
155
|
+
allowTag,
|
|
155
156
|
}));
|
|
156
157
|
case 'minecraft:resource_location':
|
|
157
|
-
return wrap(core.resourceLocation(treeNode.properties ?? {
|
|
158
|
-
pool: [],
|
|
159
|
-
allowUnknown: true,
|
|
160
|
-
}));
|
|
158
|
+
return wrap(core.resourceLocation(treeNode.properties ?? { pool: [], allowUnknown: true }));
|
|
161
159
|
case 'minecraft:rotation':
|
|
162
160
|
return wrap(vector({ dimension: 2, noLocal: true }));
|
|
163
161
|
case 'minecraft:score_holder':
|
|
164
|
-
return wrap(scoreHolder(treeNode.properties.amount));
|
|
162
|
+
return wrap(scoreHolder(treeNode.properties.usageType, treeNode.properties.amount));
|
|
165
163
|
case 'minecraft:scoreboard_slot':
|
|
166
164
|
// `BELOWNAME` and `sidebar.team.r--.+++e----__d` are also legal slots.
|
|
167
165
|
// But I do not want to spend time supporting them.
|
|
168
|
-
return wrap(
|
|
166
|
+
return wrap((src, ctx) => {
|
|
167
|
+
return core.literal(...getScoreboardSlotArgumentValues(ctx))(src, ctx);
|
|
168
|
+
});
|
|
169
|
+
case 'minecraft:style':
|
|
170
|
+
return wrap(jsonParser('::java::server::util::text::TextStyle'));
|
|
169
171
|
case 'minecraft:swizzle':
|
|
170
172
|
return wrap(core.literal(...SwizzleArgumentValues));
|
|
171
173
|
case 'minecraft:team':
|
|
@@ -185,7 +187,9 @@ export const argument = (rawTreeNode) => {
|
|
|
185
187
|
case 'minecraft:vec3':
|
|
186
188
|
return wrap(vector({ dimension: 3 }));
|
|
187
189
|
case 'spyglassmc:tag':
|
|
188
|
-
return wrap(tag()
|
|
190
|
+
return wrap(tag(core.SymbolUsageType.is(treeNode.properties?.usageType)
|
|
191
|
+
? treeNode.properties?.usageType
|
|
192
|
+
: undefined));
|
|
189
193
|
default:
|
|
190
194
|
// Unknown parser.
|
|
191
195
|
return undefined;
|
|
@@ -207,10 +211,7 @@ function block(isPredicate) {
|
|
|
207
211
|
trailingEnd: true,
|
|
208
212
|
},
|
|
209
213
|
end: ']',
|
|
210
|
-
})), (res) => ({
|
|
211
|
-
...res,
|
|
212
|
-
type: 'mcfunction:block/states',
|
|
213
|
-
}))),
|
|
214
|
+
})), (res) => ({ ...res, type: 'mcfunction:block/states' }))),
|
|
214
215
|
core.optional(core.failOnEmpty(nbt.parser.compound)),
|
|
215
216
|
]), (res) => {
|
|
216
217
|
const ans = {
|
|
@@ -220,33 +221,21 @@ function block(isPredicate) {
|
|
|
220
221
|
id: res.children.find(core.ResourceLocationNode.is),
|
|
221
222
|
states: res.children.find(BlockStatesNode.is),
|
|
222
223
|
nbt: res.children.find(nbt.NbtCompoundNode.is),
|
|
224
|
+
isPredicate,
|
|
223
225
|
};
|
|
224
226
|
return ans;
|
|
225
227
|
});
|
|
226
228
|
}
|
|
227
229
|
const blockState = block(false);
|
|
228
230
|
export const blockPredicate = block(true);
|
|
229
|
-
export const component = json.parser.entry;
|
|
230
231
|
function double(min = DoubleMin, max = DoubleMax) {
|
|
231
|
-
return core.float({
|
|
232
|
-
pattern: FloatPattern,
|
|
233
|
-
min,
|
|
234
|
-
max,
|
|
235
|
-
});
|
|
232
|
+
return core.float({ pattern: FloatPattern, min, max });
|
|
236
233
|
}
|
|
237
234
|
function float(min = FloatMin, max = FloatMax) {
|
|
238
|
-
return core.float({
|
|
239
|
-
pattern: FloatPattern,
|
|
240
|
-
min,
|
|
241
|
-
max,
|
|
242
|
-
});
|
|
235
|
+
return core.float({ pattern: FloatPattern, min, max });
|
|
243
236
|
}
|
|
244
237
|
function integer(min = IntegerMin, max = IntegerMax) {
|
|
245
|
-
return core.integer({
|
|
246
|
-
pattern: IntegerPattern,
|
|
247
|
-
min,
|
|
248
|
-
max,
|
|
249
|
-
});
|
|
238
|
+
return core.integer({ pattern: IntegerPattern, min, max });
|
|
250
239
|
}
|
|
251
240
|
function long(min, max) {
|
|
252
241
|
return core.long({
|
|
@@ -277,24 +266,14 @@ function coordinate(integerOnly = false) {
|
|
|
277
266
|
return ans;
|
|
278
267
|
};
|
|
279
268
|
}
|
|
280
|
-
function entity(amount, type) {
|
|
281
|
-
return core.map(core.select([
|
|
282
|
-
{
|
|
283
|
-
predicate: (src) => EntitySelectorAtVariable.is(src.peek(2)),
|
|
284
|
-
parser: selector(),
|
|
285
|
-
},
|
|
286
|
-
{
|
|
269
|
+
export function entity(amount, type) {
|
|
270
|
+
return core.map(core.select([{ predicate: (src) => src.peek() === '@', parser: selector() }, {
|
|
287
271
|
parser: core.any([
|
|
272
|
+
core.failOnError(uuid),
|
|
288
273
|
validateLength(core.brigadierString, PlayerNameMaxLength, 'mcfunction.parser.entity-selector.player-name.too-long'),
|
|
289
|
-
uuid,
|
|
290
274
|
]),
|
|
291
|
-
},
|
|
292
|
-
|
|
293
|
-
const ans = {
|
|
294
|
-
type: 'mcfunction:entity',
|
|
295
|
-
range: res.range,
|
|
296
|
-
children: [res],
|
|
297
|
-
};
|
|
275
|
+
}]), (res, _src, ctx) => {
|
|
276
|
+
const ans = { type: 'mcfunction:entity', range: res.range, children: [res] };
|
|
298
277
|
if (core.StringNode.is(res)) {
|
|
299
278
|
ans.playerName = res;
|
|
300
279
|
}
|
|
@@ -307,11 +286,9 @@ function entity(amount, type) {
|
|
|
307
286
|
if (amount === 'single' && ans.selector && !ans.selector.single) {
|
|
308
287
|
ctx.err.report(localize('mcfunction.parser.entity-selector.multiple-disallowed'), ans);
|
|
309
288
|
}
|
|
310
|
-
if (type === 'players'
|
|
311
|
-
(ans.uuid
|
|
312
|
-
(ans.selector &&
|
|
313
|
-
!ans.selector.playersOnly &&
|
|
314
|
-
!ans.selector.currentEntity))) {
|
|
289
|
+
if (type === 'players'
|
|
290
|
+
&& (ans.uuid
|
|
291
|
+
|| (ans.selector && !ans.selector.playersOnly && !ans.selector.currentEntity))) {
|
|
315
292
|
ctx.err.report(localize('mcfunction.parser.entity-selector.entities-disallowed'), ans);
|
|
316
293
|
}
|
|
317
294
|
return ans;
|
|
@@ -320,23 +297,64 @@ function entity(amount, type) {
|
|
|
320
297
|
const greedyString = core.string({
|
|
321
298
|
unquotable: { blockList: new Set(['\n', '\r']) },
|
|
322
299
|
});
|
|
323
|
-
|
|
300
|
+
const itemSlot = (src, ctx) => {
|
|
301
|
+
return core.literal(...getItemSlotArgumentValues(ctx))(src, ctx);
|
|
302
|
+
};
|
|
303
|
+
export const itemSlots = (src, ctx) => {
|
|
304
|
+
return core.literal(...getItemSlotsArgumentValues(ctx))(src, ctx);
|
|
305
|
+
};
|
|
306
|
+
const itemStack = (src, ctx) => {
|
|
307
|
+
const oldFormat = shouldUseOldItemStackFormat(ctx);
|
|
324
308
|
return core.map(core.sequence([
|
|
325
|
-
core.resourceLocation({ category: 'item'
|
|
326
|
-
|
|
309
|
+
core.resourceLocation({ category: 'item' }),
|
|
310
|
+
oldFormat
|
|
311
|
+
? core.optional(core.failOnEmpty(nbt.parser.compound))
|
|
312
|
+
: core.optional(core.failOnEmpty(components)),
|
|
327
313
|
]), (res) => {
|
|
328
314
|
const ans = {
|
|
329
|
-
type: 'mcfunction:
|
|
315
|
+
type: 'mcfunction:item_stack',
|
|
330
316
|
range: res.range,
|
|
331
317
|
children: res.children,
|
|
332
318
|
id: res.children.find(core.ResourceLocationNode.is),
|
|
319
|
+
components: res.children.find(ComponentListNode.is),
|
|
333
320
|
nbt: res.children.find(nbt.NbtCompoundNode.is),
|
|
334
321
|
};
|
|
335
322
|
return ans;
|
|
336
|
-
});
|
|
323
|
+
})(src, ctx);
|
|
324
|
+
};
|
|
325
|
+
const itemPredicate = (src, ctx) => {
|
|
326
|
+
const oldFormat = shouldUseOldItemStackFormat(ctx);
|
|
327
|
+
return core.map(core.sequence([
|
|
328
|
+
oldFormat
|
|
329
|
+
? core.resourceLocation({ category: 'item', allowTag: true })
|
|
330
|
+
: core.any([
|
|
331
|
+
core.resourceLocation({ category: 'item', allowTag: true }),
|
|
332
|
+
core.literal('*'),
|
|
333
|
+
]),
|
|
334
|
+
oldFormat
|
|
335
|
+
? core.optional(core.failOnEmpty(nbt.parser.compound))
|
|
336
|
+
: core.optional(componentTests),
|
|
337
|
+
]), (res) => {
|
|
338
|
+
const ans = {
|
|
339
|
+
type: 'mcfunction:item_predicate',
|
|
340
|
+
range: res.range,
|
|
341
|
+
children: res.children,
|
|
342
|
+
id: (res.children.find(core.ResourceLocationNode.is)
|
|
343
|
+
|| res.children.find(core.LiteralNode.is)),
|
|
344
|
+
tests: res.children.find(ComponentTestsNode.is),
|
|
345
|
+
nbt: res.children.find(nbt.NbtCompoundNode.is),
|
|
346
|
+
};
|
|
347
|
+
return ans;
|
|
348
|
+
})(src, ctx);
|
|
349
|
+
};
|
|
350
|
+
export function jsonParser(typeRef) {
|
|
351
|
+
return core.map(json.parser.entry, (res) => ({
|
|
352
|
+
type: 'json:typed',
|
|
353
|
+
range: res.range,
|
|
354
|
+
children: [res],
|
|
355
|
+
targetType: { kind: 'reference', path: typeRef },
|
|
356
|
+
}));
|
|
337
357
|
}
|
|
338
|
-
const itemStack = item(false);
|
|
339
|
-
const itemPredicate = item(true);
|
|
340
358
|
const message = (src, ctx) => {
|
|
341
359
|
const ans = {
|
|
342
360
|
type: 'mcfunction:message',
|
|
@@ -345,15 +363,47 @@ const message = (src, ctx) => {
|
|
|
345
363
|
};
|
|
346
364
|
while (src.canReadInLine()) {
|
|
347
365
|
if (EntitySelectorAtVariable.is(src.peek(2))) {
|
|
348
|
-
ans.children.push(selector()(src, ctx));
|
|
366
|
+
ans.children.push(selector(true)(src, ctx));
|
|
349
367
|
}
|
|
350
368
|
else {
|
|
351
|
-
ans.children.push(core.stopBefore(greedyString, ...
|
|
369
|
+
ans.children.push(core.stopBefore(greedyString, ...EntitySelectorAtVariable.filterAvailable(ctx))(src, ctx));
|
|
352
370
|
}
|
|
353
371
|
}
|
|
354
372
|
return ans;
|
|
355
373
|
};
|
|
356
|
-
|
|
374
|
+
function nbtParser(parser, properties) {
|
|
375
|
+
return core.map(parser, (res) => {
|
|
376
|
+
const ans = { type: 'mcfunction:nbt', range: res.range, children: [res], properties };
|
|
377
|
+
return ans;
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
function nbtPathParser(parser, properties) {
|
|
381
|
+
return core.map(parser, (res) => {
|
|
382
|
+
const ans = {
|
|
383
|
+
type: 'mcfunction:nbt_path',
|
|
384
|
+
range: res.range,
|
|
385
|
+
children: [res],
|
|
386
|
+
properties,
|
|
387
|
+
};
|
|
388
|
+
return ans;
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
export const particle = (src, ctx) => {
|
|
392
|
+
const release = ctx.project['loadedVersion'];
|
|
393
|
+
if (!release || ReleaseVersion.cmp(release, '1.20.5') >= 0) {
|
|
394
|
+
return core.map(sequence([
|
|
395
|
+
core.resourceLocation({ category: 'particle_type' }),
|
|
396
|
+
core.optional(core.failOnEmpty(nbt.parser.compound)),
|
|
397
|
+
]), (res) => {
|
|
398
|
+
const ans = {
|
|
399
|
+
type: 'mcfunction:particle',
|
|
400
|
+
range: res.range,
|
|
401
|
+
children: res.children,
|
|
402
|
+
id: res.children.find(core.ResourceLocationNode.is),
|
|
403
|
+
};
|
|
404
|
+
return ans;
|
|
405
|
+
})(src, ctx);
|
|
406
|
+
}
|
|
357
407
|
const sep = core.map(mcf.sep, () => []);
|
|
358
408
|
const vec = vector({ dimension: 3 });
|
|
359
409
|
const color = core.map(vec, (res) => ({
|
|
@@ -376,14 +426,11 @@ export const particle = (() => {
|
|
|
376
426
|
shriek: integer(),
|
|
377
427
|
vibration: sequence([vec, integer()], sep),
|
|
378
428
|
};
|
|
379
|
-
return core.map(sequence([
|
|
380
|
-
core.resourceLocation({ category: 'particle_type' }),
|
|
381
|
-
{
|
|
429
|
+
return core.map(sequence([core.resourceLocation({ category: 'particle_type' }), {
|
|
382
430
|
get: (res) => {
|
|
383
431
|
return map[core.ResourceLocationNode.toString(res.children[0], 'short')];
|
|
384
432
|
},
|
|
385
|
-
},
|
|
386
|
-
], sep), (res) => {
|
|
433
|
+
}], sep), (res) => {
|
|
387
434
|
const ans = {
|
|
388
435
|
type: 'mcfunction:particle',
|
|
389
436
|
range: res.range,
|
|
@@ -391,10 +438,12 @@ export const particle = (() => {
|
|
|
391
438
|
id: res.children.find(core.ResourceLocationNode.is),
|
|
392
439
|
};
|
|
393
440
|
return ans;
|
|
394
|
-
});
|
|
395
|
-
}
|
|
441
|
+
})(src, ctx);
|
|
442
|
+
};
|
|
396
443
|
function range(type, min, max, cycleable) {
|
|
397
|
-
const number = type === 'float'
|
|
444
|
+
const number = type === 'float'
|
|
445
|
+
? float(min, max)
|
|
446
|
+
: integer(min, max);
|
|
398
447
|
const low = core.failOnEmpty(core.stopBefore(number, '..'));
|
|
399
448
|
const sep = core.failOnEmpty(core.literal({ pool: ['..'], colorTokenType: 'keyword' }));
|
|
400
449
|
const high = core.failOnEmpty(number);
|
|
@@ -409,9 +458,7 @@ function range(type, min, max, cycleable) {
|
|
|
409
458
|
: res.children.filter(core.IntegerNode.is);
|
|
410
459
|
const sepNode = res.children.find(core.LiteralNode.is);
|
|
411
460
|
const ans = {
|
|
412
|
-
type: type === 'float'
|
|
413
|
-
? 'mcfunction:float_range'
|
|
414
|
-
: 'mcfunction:int_range',
|
|
461
|
+
type: type === 'float' ? 'mcfunction:float_range' : 'mcfunction:int_range',
|
|
415
462
|
range: res.range,
|
|
416
463
|
children: res.children,
|
|
417
464
|
value: sepNode
|
|
@@ -422,19 +469,59 @@ function range(type, min, max, cycleable) {
|
|
|
422
469
|
: [undefined, valueNodes[0].value]
|
|
423
470
|
: [valueNodes[0].value, valueNodes[0].value],
|
|
424
471
|
};
|
|
425
|
-
if (!cycleable
|
|
426
|
-
ans.value[0] !== undefined
|
|
427
|
-
ans.value[1] !== undefined
|
|
428
|
-
ans.value[0] > ans.value[1]) {
|
|
472
|
+
if (!cycleable
|
|
473
|
+
&& ans.value[0] !== undefined
|
|
474
|
+
&& ans.value[1] !== undefined
|
|
475
|
+
&& ans.value[0] > ans.value[1]) {
|
|
429
476
|
ctx.err.report(localize('mcfunction.parser.range.min>max', ans.value[0], ans.value[1]), res);
|
|
430
477
|
}
|
|
431
478
|
return ans;
|
|
432
479
|
});
|
|
433
480
|
}
|
|
481
|
+
function resourceOrInline(category) {
|
|
482
|
+
return core.select([{
|
|
483
|
+
predicate: (src) => core.LegalResourceLocationCharacters.has(src.peek()),
|
|
484
|
+
parser: core.resourceLocation({ category }),
|
|
485
|
+
}, {
|
|
486
|
+
parser: core.map(nbt.parser.entry, (res) => {
|
|
487
|
+
const ans = {
|
|
488
|
+
type: 'mcfunction:nbt_resource',
|
|
489
|
+
range: res.range,
|
|
490
|
+
children: [res],
|
|
491
|
+
category,
|
|
492
|
+
};
|
|
493
|
+
return ans;
|
|
494
|
+
}),
|
|
495
|
+
}]);
|
|
496
|
+
}
|
|
497
|
+
function selectorPrefix(ignoreInvalidPrefix) {
|
|
498
|
+
return (src, ctx) => {
|
|
499
|
+
const start = src.cursor;
|
|
500
|
+
let value;
|
|
501
|
+
if (ignoreInvalidPrefix) {
|
|
502
|
+
value = src.peek(2);
|
|
503
|
+
src.skip(2);
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
value = src.readUntil(' ', '\r', '\n', '[');
|
|
507
|
+
}
|
|
508
|
+
const allowedVariables = EntitySelectorAtVariable.filterAvailable(ctx);
|
|
509
|
+
const ans = {
|
|
510
|
+
type: 'literal',
|
|
511
|
+
range: core.Range.create(start, src),
|
|
512
|
+
options: { pool: allowedVariables },
|
|
513
|
+
value,
|
|
514
|
+
};
|
|
515
|
+
if (!allowedVariables.includes(value) && !ignoreInvalidPrefix) {
|
|
516
|
+
ctx.err.report(localize('mcfunction.parser.entity-selector.invalid', ans.value), ans);
|
|
517
|
+
}
|
|
518
|
+
return ans;
|
|
519
|
+
};
|
|
520
|
+
}
|
|
434
521
|
/**
|
|
435
522
|
* Failure when not beginning with `@[parse]`
|
|
436
523
|
*/
|
|
437
|
-
function selector() {
|
|
524
|
+
export function selector(ignoreInvalidPrefix = false) {
|
|
438
525
|
let chunkLimited;
|
|
439
526
|
let currentEntity;
|
|
440
527
|
let dimensionLimited;
|
|
@@ -442,12 +529,7 @@ function selector() {
|
|
|
442
529
|
let predicates;
|
|
443
530
|
let single;
|
|
444
531
|
let typeLimited;
|
|
445
|
-
return core.map(core.sequence([
|
|
446
|
-
core.failOnEmpty(core.literal({
|
|
447
|
-
pool: EntitySelectorAtVariables,
|
|
448
|
-
colorTokenType: 'keyword',
|
|
449
|
-
})),
|
|
450
|
-
{
|
|
532
|
+
return core.map(core.sequence([core.failOnEmpty(selectorPrefix(ignoreInvalidPrefix)), {
|
|
451
533
|
get: (res) => {
|
|
452
534
|
const variable = core.LiteralNode.is(res.children?.[0])
|
|
453
535
|
? res.children[0].value
|
|
@@ -457,16 +539,11 @@ function selector() {
|
|
|
457
539
|
? variable === '@p' || variable === '@a' || variable === '@r'
|
|
458
540
|
: undefined;
|
|
459
541
|
predicates = variable === '@e' ? ['Entity::isAlive'] : undefined;
|
|
460
|
-
single = variable
|
|
461
|
-
? variable === '@p' || variable === '@r' || variable === '@s'
|
|
462
|
-
: undefined;
|
|
542
|
+
single = variable ? ['@p', '@r', '@s', '@n'].includes(variable) : undefined;
|
|
463
543
|
typeLimited = playersOnly;
|
|
464
544
|
function invertable(parser) {
|
|
465
545
|
return core.map(core.sequence([
|
|
466
|
-
core.optional(core.failOnEmpty(core.literal({
|
|
467
|
-
pool: ['!'],
|
|
468
|
-
colorTokenType: 'keyword',
|
|
469
|
-
}))),
|
|
546
|
+
core.optional(core.failOnEmpty(core.literal({ pool: ['!'], colorTokenType: 'keyword' }))),
|
|
470
547
|
(src) => {
|
|
471
548
|
src.skipSpace();
|
|
472
549
|
return undefined;
|
|
@@ -490,9 +567,7 @@ function selector() {
|
|
|
490
567
|
...core.BrigadierStringOptions,
|
|
491
568
|
value: {
|
|
492
569
|
parser: core.literal({
|
|
493
|
-
pool: [
|
|
494
|
-
...EntitySelectorNode.ArgumentKeys,
|
|
495
|
-
],
|
|
570
|
+
pool: [...EntitySelectorNode.ArgumentKeys],
|
|
496
571
|
colorTokenType: 'property',
|
|
497
572
|
}),
|
|
498
573
|
type: 'literal',
|
|
@@ -502,8 +577,8 @@ function selector() {
|
|
|
502
577
|
value: {
|
|
503
578
|
get: (record, key) => {
|
|
504
579
|
const hasKey = (key) => !!record.children.find((p) => p.key?.value === key);
|
|
505
|
-
const hasNonInvertedKey = (key) => !!record.children.find((p) => p.key?.value === key
|
|
506
|
-
!p.value?.inverted);
|
|
580
|
+
const hasNonInvertedKey = (key) => !!record.children.find((p) => p.key?.value === key
|
|
581
|
+
&& !p.value?.inverted);
|
|
507
582
|
switch (key?.value) {
|
|
508
583
|
case 'advancements':
|
|
509
584
|
return core.map(core.record({
|
|
@@ -513,16 +588,14 @@ function selector() {
|
|
|
513
588
|
category: 'advancement',
|
|
514
589
|
}),
|
|
515
590
|
sep: '=',
|
|
516
|
-
value: core.select([
|
|
517
|
-
{
|
|
591
|
+
value: core.select([{
|
|
518
592
|
predicate: (src) => src.peek() === '{',
|
|
519
593
|
parser: core.map(core.record({
|
|
520
594
|
start: '{',
|
|
521
595
|
pair: {
|
|
522
596
|
key: unquotedString,
|
|
523
597
|
sep: '=',
|
|
524
|
-
value: core
|
|
525
|
-
.boolean,
|
|
598
|
+
value: core.boolean,
|
|
526
599
|
end: ',',
|
|
527
600
|
trailingEnd: true,
|
|
528
601
|
},
|
|
@@ -534,11 +607,7 @@ function selector() {
|
|
|
534
607
|
};
|
|
535
608
|
return ans;
|
|
536
609
|
}),
|
|
537
|
-
},
|
|
538
|
-
{
|
|
539
|
-
parser: core.boolean,
|
|
540
|
-
},
|
|
541
|
-
]),
|
|
610
|
+
}, { parser: core.boolean }]),
|
|
542
611
|
end: ',',
|
|
543
612
|
trailingEnd: true,
|
|
544
613
|
},
|
|
@@ -557,8 +626,8 @@ function selector() {
|
|
|
557
626
|
return core.map(range('float', 0), (res, _, ctx) => {
|
|
558
627
|
dimensionLimited = true;
|
|
559
628
|
// x, y, z, dx, dy, dz take precedence over distance, so we use ??= instead of = to ensure it won't override the result.
|
|
560
|
-
chunkLimited ??= !playersOnly
|
|
561
|
-
res.value[1] !== undefined;
|
|
629
|
+
chunkLimited ??= !playersOnly
|
|
630
|
+
&& res.value[1] !== undefined;
|
|
562
631
|
if (hasKey(key.value)) {
|
|
563
632
|
ctx.err.report(localize('duplicate-key', localeQuote(key.value)), key);
|
|
564
633
|
}
|
|
@@ -566,8 +635,7 @@ function selector() {
|
|
|
566
635
|
});
|
|
567
636
|
case 'gamemode':
|
|
568
637
|
return core.map(invertable(core.string({
|
|
569
|
-
unquotable: core
|
|
570
|
-
.BrigadierUnquotableOption,
|
|
638
|
+
unquotable: core.BrigadierUnquotableOption,
|
|
571
639
|
value: {
|
|
572
640
|
type: 'literal',
|
|
573
641
|
parser: core.literal(...GamemodeArgumentValues),
|
|
@@ -612,9 +680,7 @@ function selector() {
|
|
|
612
680
|
case 'nbt':
|
|
613
681
|
return invertable(nbt.parser.compound);
|
|
614
682
|
case 'predicate':
|
|
615
|
-
return invertable(core.resourceLocation({
|
|
616
|
-
category: 'predicate',
|
|
617
|
-
}));
|
|
683
|
+
return invertable(core.resourceLocation({ category: 'predicate' }));
|
|
618
684
|
case 'scores':
|
|
619
685
|
return core.map(core.record({
|
|
620
686
|
start: '{',
|
|
@@ -645,8 +711,7 @@ function selector() {
|
|
|
645
711
|
});
|
|
646
712
|
case 'sort':
|
|
647
713
|
return core.map(core.string({
|
|
648
|
-
unquotable: core
|
|
649
|
-
.BrigadierUnquotableOption,
|
|
714
|
+
unquotable: core.BrigadierUnquotableOption,
|
|
650
715
|
value: {
|
|
651
716
|
type: 'literal',
|
|
652
717
|
parser: core.literal('arbitrary', 'furthest', 'nearest', 'random'),
|
|
@@ -661,23 +726,9 @@ function selector() {
|
|
|
661
726
|
return res;
|
|
662
727
|
});
|
|
663
728
|
case 'tag':
|
|
664
|
-
return invertable(tag([
|
|
665
|
-
'[',
|
|
666
|
-
'=',
|
|
667
|
-
',',
|
|
668
|
-
']',
|
|
669
|
-
'{',
|
|
670
|
-
'}',
|
|
671
|
-
]));
|
|
729
|
+
return invertable(tag('reference', ['[', '=', ',', ']', '{', '}']));
|
|
672
730
|
case 'team':
|
|
673
|
-
return core.map(invertable(team('reference', [
|
|
674
|
-
'[',
|
|
675
|
-
'=',
|
|
676
|
-
',',
|
|
677
|
-
']',
|
|
678
|
-
'{',
|
|
679
|
-
'}',
|
|
680
|
-
])), (res, _, ctx) => {
|
|
731
|
+
return core.map(invertable(team('reference', ['[', '=', ',', ']', '{', '}'])), (res, _, ctx) => {
|
|
681
732
|
if (res.inverted
|
|
682
733
|
? hasNonInvertedKey(key.value)
|
|
683
734
|
: hasKey(key.value)) {
|
|
@@ -698,11 +749,9 @@ function selector() {
|
|
|
698
749
|
ctx.err.report(localize('mcfunction.parser.entity-selector.arguments.not-applicable', localeQuote(key.value)), key);
|
|
699
750
|
}
|
|
700
751
|
}
|
|
701
|
-
else if (!res.inverted &&
|
|
702
|
-
!res.value.isTag) {
|
|
752
|
+
else if (!res.inverted && !res.value.isTag) {
|
|
703
753
|
typeLimited = true;
|
|
704
|
-
if (core.ResourceLocationNode
|
|
705
|
-
.toString(res.value, 'short') === 'player') {
|
|
754
|
+
if (core.ResourceLocationNode.toString(res.value, 'short') === 'player') {
|
|
706
755
|
playersOnly = true;
|
|
707
756
|
}
|
|
708
757
|
}
|
|
@@ -761,15 +810,12 @@ function selector() {
|
|
|
761
810
|
return ans;
|
|
762
811
|
}));
|
|
763
812
|
},
|
|
764
|
-
},
|
|
765
|
-
]), (res) => {
|
|
813
|
+
}]), (res) => {
|
|
766
814
|
const ans = {
|
|
767
815
|
type: 'mcfunction:entity_selector',
|
|
768
816
|
range: res.range,
|
|
769
817
|
children: res.children,
|
|
770
|
-
variable: res.children
|
|
771
|
-
.find(core.LiteralNode.is)
|
|
772
|
-
.value.slice(1),
|
|
818
|
+
variable: res.children.find(core.LiteralNode.is).value.slice(1),
|
|
773
819
|
arguments: res.children.find(EntitySelectorArgumentsNode.is),
|
|
774
820
|
chunkLimited,
|
|
775
821
|
currentEntity,
|
|
@@ -799,17 +845,12 @@ function getEntitySelectorHover(node) {
|
|
|
799
845
|
- \`currentEntity\`: \`${node.currentEntity}\``;
|
|
800
846
|
}
|
|
801
847
|
else {
|
|
802
|
-
const amountOfTrue = [
|
|
803
|
-
node.chunkLimited,
|
|
804
|
-
node.dimensionLimited,
|
|
805
|
-
node.playersOnly,
|
|
806
|
-
node.typeLimited,
|
|
807
|
-
].filter((v) => v).length;
|
|
848
|
+
const amountOfTrue = [node.chunkLimited, node.dimensionLimited, node.playersOnly, node.typeLimited].filter((v) => v).length;
|
|
808
849
|
ans = `**Performance**: ${grades.get(amountOfTrue)}
|
|
809
850
|
- \`chunkLimited\`: \`${!!node.chunkLimited}\`
|
|
810
851
|
- \`dimensionLimited\`: \`${!!node.dimensionLimited}\`
|
|
811
852
|
- \`playersOnly\`: \`${!!node.playersOnly}\`
|
|
812
|
-
- \`typeLimited\`: \`${!!node.
|
|
853
|
+
- \`typeLimited\`: \`${!!node.typeLimited}\``;
|
|
813
854
|
}
|
|
814
855
|
if (node.predicates?.length) {
|
|
815
856
|
ans += `
|
|
@@ -820,17 +861,13 @@ ${node.predicates.map((p) => `- \`${p}\``).join('\n')}`;
|
|
|
820
861
|
}
|
|
821
862
|
return ans;
|
|
822
863
|
}
|
|
823
|
-
export
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
parser:
|
|
829
|
-
},
|
|
830
|
-
{
|
|
831
|
-
parser: scoreHolderFakeName,
|
|
832
|
-
},
|
|
833
|
-
]), (res, _src, ctx) => {
|
|
864
|
+
export function scoreHolderFakeName(usageType) {
|
|
865
|
+
return validateLength(symbol({ category: 'score_holder', usageType }), FakeNameMaxLength, 'mcfunction.parser.score_holder.fake-name.too-long');
|
|
866
|
+
}
|
|
867
|
+
export function scoreHolder(usageType, amount) {
|
|
868
|
+
return core.map(core.select([{ predicate: (src) => src.peek() === '@', parser: selector() }, {
|
|
869
|
+
parser: scoreHolderFakeName(usageType),
|
|
870
|
+
}]), (res, _src, ctx) => {
|
|
834
871
|
const ans = {
|
|
835
872
|
type: 'mcfunction:score_holder',
|
|
836
873
|
range: res.range,
|
|
@@ -851,43 +888,28 @@ function scoreHolder(amount) {
|
|
|
851
888
|
function symbol(options, terminators = []) {
|
|
852
889
|
return core.stopBefore(core.symbol(options), core.Whitespaces, terminators);
|
|
853
890
|
}
|
|
854
|
-
function objective(usageType, terminators = []) {
|
|
891
|
+
export function objective(usageType, terminators = []) {
|
|
855
892
|
return validateLength(unquotableSymbol({ category: 'objective', usageType }, terminators), ObjectiveMaxLength, 'mcfunction.parser.objective.too-long');
|
|
856
893
|
}
|
|
857
|
-
const objectiveCriteria = core
|
|
858
|
-
.map(core.any([
|
|
894
|
+
const objectiveCriteria = core.map(core.any([
|
|
859
895
|
core.sequence([
|
|
860
|
-
core.stopBefore(core.resourceLocation({
|
|
861
|
-
category: 'stat_type',
|
|
862
|
-
namespacePathSep: '.',
|
|
863
|
-
}), ':'),
|
|
896
|
+
core.stopBefore(core.resourceLocation({ category: 'stat_type', namespacePathSep: '.' }), ':'),
|
|
864
897
|
core.failOnEmpty(core.literal(':')),
|
|
865
898
|
{
|
|
866
899
|
get: (res) => {
|
|
867
900
|
if (core.ResourceLocationNode.is(res.children[0])) {
|
|
868
|
-
const category = ObjectiveCriteriaNode.ComplexCategories
|
|
869
|
-
.get(core.ResourceLocationNode.toString(res.children[0], 'short'));
|
|
901
|
+
const category = ObjectiveCriteriaNode.ComplexCategories.get(core.ResourceLocationNode.toString(res.children[0], 'short'));
|
|
870
902
|
if (category) {
|
|
871
|
-
return core.resourceLocation({
|
|
872
|
-
category,
|
|
873
|
-
namespacePathSep: '.',
|
|
874
|
-
});
|
|
903
|
+
return core.resourceLocation({ category, namespacePathSep: '.' });
|
|
875
904
|
}
|
|
876
905
|
}
|
|
877
|
-
return core.resourceLocation({
|
|
878
|
-
pool: [],
|
|
879
|
-
allowUnknown: true,
|
|
880
|
-
namespacePathSep: '.',
|
|
881
|
-
});
|
|
906
|
+
return core.resourceLocation({ pool: [], allowUnknown: true, namespacePathSep: '.' });
|
|
882
907
|
},
|
|
883
908
|
},
|
|
884
909
|
]),
|
|
885
910
|
core.literal(...ObjectiveCriteriaNode.SimpleValues),
|
|
886
911
|
]), (res) => {
|
|
887
|
-
const ans = {
|
|
888
|
-
type: 'mcfunction:objective_criteria',
|
|
889
|
-
range: res.range,
|
|
890
|
-
};
|
|
912
|
+
const ans = { type: 'mcfunction:objective_criteria', range: res.range };
|
|
891
913
|
if (core.LiteralNode.is(res)) {
|
|
892
914
|
ans.simpleValue = res.value;
|
|
893
915
|
}
|
|
@@ -896,8 +918,8 @@ const objectiveCriteria = core
|
|
|
896
918
|
}
|
|
897
919
|
return ans;
|
|
898
920
|
});
|
|
899
|
-
export function tag(terminators = []) {
|
|
900
|
-
return unquotableSymbol('tag', terminators);
|
|
921
|
+
export function tag(usageType, terminators = []) {
|
|
922
|
+
return unquotableSymbol({ category: 'tag', usageType }, terminators);
|
|
901
923
|
}
|
|
902
924
|
export function team(usageType, terminators = []) {
|
|
903
925
|
return unquotableSymbol({ category: 'team', usageType }, terminators);
|
|
@@ -924,12 +946,8 @@ const unquotedString = core.string({
|
|
|
924
946
|
unquotable: core.BrigadierUnquotableOption,
|
|
925
947
|
});
|
|
926
948
|
const UuidPattern = /^[0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+$/i;
|
|
927
|
-
const uuid = (src, ctx) => {
|
|
928
|
-
const ans = {
|
|
929
|
-
type: 'mcfunction:uuid',
|
|
930
|
-
range: core.Range.create(src),
|
|
931
|
-
bits: [0n, 0n],
|
|
932
|
-
};
|
|
949
|
+
export const uuid = (src, ctx) => {
|
|
950
|
+
const ans = { type: 'mcfunction:uuid', range: core.Range.create(src), bits: [0n, 0n] };
|
|
933
951
|
const raw = src.readUntil(' ', '\r', '\n', '\r');
|
|
934
952
|
/**
|
|
935
953
|
* According to the implementation of Minecraft's UUID parser and Java's `UUID#fromString` method,
|
|
@@ -999,8 +1017,7 @@ function vector(options) {
|
|
|
999
1017
|
? coordinate(options.integersOnly)(src, ctx)
|
|
1000
1018
|
: coordinate(options.integersOnly)(src, ctx);
|
|
1001
1019
|
ans.children.push(coord);
|
|
1002
|
-
if ((ans.system === 1 /* CoordinateSystem.Local */) !==
|
|
1003
|
-
(coord.notation === '^')) {
|
|
1020
|
+
if ((ans.system === 1 /* CoordinateSystem.Local */) !== (coord.notation === '^')) {
|
|
1004
1021
|
ctx.err.report(localize('mcfunction.parser.vector.mixed'), coord);
|
|
1005
1022
|
}
|
|
1006
1023
|
}
|
|
@@ -1011,4 +1028,155 @@ function vector(options) {
|
|
|
1011
1028
|
return ans;
|
|
1012
1029
|
};
|
|
1013
1030
|
}
|
|
1031
|
+
const components = core.map(core.record({
|
|
1032
|
+
start: '[',
|
|
1033
|
+
pair: {
|
|
1034
|
+
key: core.resourceLocation({ category: 'data_component_type' }),
|
|
1035
|
+
sep: '=',
|
|
1036
|
+
value: nbt.parser.entry,
|
|
1037
|
+
end: ',',
|
|
1038
|
+
trailingEnd: true,
|
|
1039
|
+
},
|
|
1040
|
+
end: ']',
|
|
1041
|
+
}), (res) => {
|
|
1042
|
+
const ans = {
|
|
1043
|
+
type: 'mcfunction:component_list',
|
|
1044
|
+
range: res.range,
|
|
1045
|
+
children: res.children,
|
|
1046
|
+
};
|
|
1047
|
+
return ans;
|
|
1048
|
+
});
|
|
1049
|
+
const componentTest = (src, ctx) => {
|
|
1050
|
+
const start = src.cursor;
|
|
1051
|
+
src.skipWhitespace();
|
|
1052
|
+
const negated = src.trySkip('!');
|
|
1053
|
+
src.skipWhitespace();
|
|
1054
|
+
const key = core.resourceLocation({ category: 'data_component_type' })(src, ctx);
|
|
1055
|
+
src.skipWhitespace();
|
|
1056
|
+
if (core.ResourceLocationNode.toString(key, 'full') === 'minecraft:count') {
|
|
1057
|
+
key.options.category = undefined;
|
|
1058
|
+
key.options.pool = ['minecraft:count'];
|
|
1059
|
+
}
|
|
1060
|
+
if (src.trySkip('=')) {
|
|
1061
|
+
const ans = {
|
|
1062
|
+
type: 'mcfunction:component_test_exact',
|
|
1063
|
+
range: core.Range.create(start, src),
|
|
1064
|
+
children: [key],
|
|
1065
|
+
key,
|
|
1066
|
+
negated,
|
|
1067
|
+
};
|
|
1068
|
+
const value = nbt.parser.entry(src, ctx);
|
|
1069
|
+
if (value == core.Failure) {
|
|
1070
|
+
ctx.err.report(localize('expected', localize('nbt.node')), src);
|
|
1071
|
+
src.skipUntilOrEnd(',', '|', ']');
|
|
1072
|
+
}
|
|
1073
|
+
else {
|
|
1074
|
+
ans.children.push(value);
|
|
1075
|
+
ans.value = value;
|
|
1076
|
+
}
|
|
1077
|
+
src.skipWhitespace();
|
|
1078
|
+
ans.range.end = src.cursor;
|
|
1079
|
+
return ans;
|
|
1080
|
+
}
|
|
1081
|
+
if (src.trySkip('~')) {
|
|
1082
|
+
if (key.options.category !== undefined) {
|
|
1083
|
+
key.options.category = 'item_sub_predicate_type';
|
|
1084
|
+
}
|
|
1085
|
+
const ans = {
|
|
1086
|
+
type: 'mcfunction:component_test_sub_predicate',
|
|
1087
|
+
range: core.Range.create(start, src),
|
|
1088
|
+
children: [key],
|
|
1089
|
+
key,
|
|
1090
|
+
negated,
|
|
1091
|
+
};
|
|
1092
|
+
const predicate = nbt.parser.entry(src, ctx);
|
|
1093
|
+
if (predicate == core.Failure) {
|
|
1094
|
+
ctx.err.report(localize('expected', localize('nbt.node')), src);
|
|
1095
|
+
src.skipUntilOrEnd(',', '|', ']');
|
|
1096
|
+
}
|
|
1097
|
+
else {
|
|
1098
|
+
ans.children.push(predicate);
|
|
1099
|
+
ans.value = predicate;
|
|
1100
|
+
}
|
|
1101
|
+
src.skipWhitespace();
|
|
1102
|
+
ans.range.end = src.cursor;
|
|
1103
|
+
return ans;
|
|
1104
|
+
}
|
|
1105
|
+
const ans = {
|
|
1106
|
+
type: 'mcfunction:component_test_exists',
|
|
1107
|
+
range: core.Range.create(start, src),
|
|
1108
|
+
children: [key],
|
|
1109
|
+
key,
|
|
1110
|
+
negated,
|
|
1111
|
+
};
|
|
1112
|
+
return ans;
|
|
1113
|
+
};
|
|
1114
|
+
const componentTestsAllOf = (src, ctx) => {
|
|
1115
|
+
const ans = {
|
|
1116
|
+
type: 'mcfunction:component_tests_all_of',
|
|
1117
|
+
range: core.Range.create(src),
|
|
1118
|
+
children: [],
|
|
1119
|
+
};
|
|
1120
|
+
while (src.canRead()) {
|
|
1121
|
+
src.skipWhitespace();
|
|
1122
|
+
const testNode = componentTest(src, ctx);
|
|
1123
|
+
ans.children.push(testNode);
|
|
1124
|
+
src.skipWhitespace();
|
|
1125
|
+
if (src.peek() === ',') {
|
|
1126
|
+
src.skip();
|
|
1127
|
+
}
|
|
1128
|
+
else if (src.peek() === '|' || src.peek() === ']') {
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
else {
|
|
1132
|
+
ctx.err.report(localize('expected', localeQuote(']')), src);
|
|
1133
|
+
src.skipUntilOrEnd(',', '|', ']');
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
ans.range.end = src.cursor;
|
|
1137
|
+
return ans;
|
|
1138
|
+
};
|
|
1139
|
+
const componentTestsAnyOf = (src, ctx) => {
|
|
1140
|
+
const ans = {
|
|
1141
|
+
type: 'mcfunction:component_tests_any_of',
|
|
1142
|
+
range: core.Range.create(src),
|
|
1143
|
+
children: [],
|
|
1144
|
+
};
|
|
1145
|
+
while (src.canRead()) {
|
|
1146
|
+
src.skipWhitespace();
|
|
1147
|
+
const allOfNode = componentTestsAllOf(src, ctx);
|
|
1148
|
+
ans.children.push(allOfNode);
|
|
1149
|
+
src.skipWhitespace();
|
|
1150
|
+
if (src.peek() === '|') {
|
|
1151
|
+
src.skip();
|
|
1152
|
+
}
|
|
1153
|
+
else if (src.peek() === ']') {
|
|
1154
|
+
break;
|
|
1155
|
+
}
|
|
1156
|
+
else {
|
|
1157
|
+
ctx.err.report(localize('expected', localeQuote(']')), src);
|
|
1158
|
+
src.skipUntilOrEnd('|', ']');
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
ans.range.end = src.cursor;
|
|
1162
|
+
return ans;
|
|
1163
|
+
};
|
|
1164
|
+
const componentTests = (src, ctx) => {
|
|
1165
|
+
const ans = {
|
|
1166
|
+
type: 'mcfunction:component_tests',
|
|
1167
|
+
range: core.Range.create(src),
|
|
1168
|
+
};
|
|
1169
|
+
if (!src.trySkip('[')) {
|
|
1170
|
+
return core.Failure;
|
|
1171
|
+
}
|
|
1172
|
+
src.skipWhitespace();
|
|
1173
|
+
const tests = core.optional(core.failOnEmpty(componentTestsAnyOf))(src, ctx);
|
|
1174
|
+
if (tests) {
|
|
1175
|
+
ans.children = [tests];
|
|
1176
|
+
}
|
|
1177
|
+
src.skipWhitespace();
|
|
1178
|
+
core.literal(']')(src, ctx);
|
|
1179
|
+
ans.range.end = src.cursor;
|
|
1180
|
+
return ans;
|
|
1181
|
+
};
|
|
1014
1182
|
//# sourceMappingURL=argument.js.map
|