@spyglassmc/java-edition 0.3.0 → 0.3.2
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 +1 -1
- package/lib/binder/index.js +94 -19
- package/lib/common/index.js +10 -7
- package/lib/dependency/index.d.ts +1 -3
- package/lib/dependency/index.js +29 -21
- package/lib/dependency/mcmeta.d.ts +1 -1
- package/lib/dependency/mcmeta.js +27 -13
- package/lib/index.js +16 -7
- package/lib/json/checker/data/advancement.js +24 -13
- package/lib/json/checker/data/biome.js +3 -3
- package/lib/json/checker/data/common.js +15 -27
- package/lib/json/checker/data/dimension.js +7 -18
- package/lib/json/checker/data/feature.js +41 -27
- package/lib/json/checker/data/index.d.ts +1 -1
- package/lib/json/checker/data/index.js +3 -3
- package/lib/json/checker/data/loot_table.js +16 -17
- package/lib/json/checker/data/recipe.js +1 -1
- package/lib/json/checker/data/structure.js +20 -12
- package/lib/json/checker/data/tag.js +2 -2
- package/lib/json/checker/data/text_component.js +21 -12
- package/lib/json/checker/index.d.ts +10 -3
- package/lib/json/checker/index.js +230 -3
- package/lib/json/checker/util/advancement.js +3 -3
- package/lib/json/checker/util/block_states.d.ts +2 -2
- package/lib/json/checker/util/block_states.js +7 -5
- package/lib/json/checker/util/color.js +8 -2
- package/lib/json/checker/util/nbt.js +3 -2
- package/lib/json/checker/util/recipe.js +7 -6
- package/lib/json/checker/util/version.js +2 -2
- package/lib/mcfunction/checker/index.js +10 -7
- package/lib/mcfunction/colorizer/index.js +2 -4
- package/lib/mcfunction/common/index.js +46 -15
- package/lib/mcfunction/completer/argument.js +53 -24
- package/lib/mcfunction/inlayHintProvider.js +8 -3
- package/lib/mcfunction/node/argument.d.ts +3 -3
- package/lib/mcfunction/node/argument.js +57 -17
- package/lib/mcfunction/parser/argument.js +124 -52
- package/lib/mcfunction/signatureHelpProvider.js +6 -3
- package/lib/mcfunction/tree/patch.js +132 -126
- package/package.json +7 -7
|
@@ -1,12 +1,62 @@
|
|
|
1
|
+
import * as core from '@spyglassmc/core';
|
|
2
|
+
import { JsonObjectNode } from '@spyglassmc/json';
|
|
3
|
+
import { localeQuote, localize } from '@spyglassmc/locales';
|
|
4
|
+
import * as mcdoc from '@spyglassmc/mcdoc';
|
|
1
5
|
import { dissectUri } from '../../binder/index.js';
|
|
2
|
-
|
|
6
|
+
const Checkers = new Map([
|
|
7
|
+
['advancement', '::java::data::advancement::Advancement'],
|
|
8
|
+
['dimension', '::java::data::worldgen::dimension::Dimension'],
|
|
9
|
+
['dimension_type', '::java::data::worldgen::dimension::DimensionType'],
|
|
10
|
+
['item_modifier', '::java::data::item_modifier::ItemModifier'],
|
|
11
|
+
['loot_table', '::java::data::loot::LootTable'],
|
|
12
|
+
['predicate', '::java::data::predicate::Predicate'],
|
|
13
|
+
['recipe', '::java::data::recipe::Recipe'],
|
|
14
|
+
['worldgen/biome', '::java::data::worldgen::biome::Biome'],
|
|
15
|
+
[
|
|
16
|
+
'worldgen/configured_carver',
|
|
17
|
+
'::java::data::worldgen::carver::ConfiguredCarver',
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
'worldgen/configured_surface_builder',
|
|
21
|
+
'::java::data::worldgen::surface_builder::ConfiguredSurfaceBuilder',
|
|
22
|
+
],
|
|
23
|
+
['worldgen/configured_feature', '::java::data::feature::ConfiguredFeature'],
|
|
24
|
+
[
|
|
25
|
+
'worldgen/configured_structure_feature',
|
|
26
|
+
'::java::data::worldgen::structure::Structure',
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
'worldgen/density_function',
|
|
30
|
+
'::java::data::worldgen::density_function::DensityFunction',
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
'worldgen/noise',
|
|
34
|
+
'::java::data::worldgen::dimension::biome_source::NoiseParameters',
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
'worldgen/noise_settings',
|
|
38
|
+
'::java::data::worldgen::noise_settings::NoiseGeneratorSettings',
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
'worldgen/processor_list',
|
|
42
|
+
'::java::data::worldgen::processor_list::ProcessorList',
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
'worldgen/template_pool',
|
|
46
|
+
'::java::data::worldgen::template_pool::TemplatePool',
|
|
47
|
+
],
|
|
48
|
+
]);
|
|
3
49
|
export const entry = (node, ctx) => {
|
|
4
50
|
const parts = dissectUri(ctx.doc.uri, ctx);
|
|
5
51
|
if (parts && Checkers.has(parts.category)) {
|
|
6
|
-
Checkers.get(parts.category)
|
|
52
|
+
const identifier = Checkers.get(parts.category);
|
|
53
|
+
return definition(identifier)(node, ctx);
|
|
54
|
+
}
|
|
55
|
+
else if (parts?.category.startsWith('tag/')) {
|
|
56
|
+
// TODO
|
|
7
57
|
}
|
|
8
58
|
else if (ctx.doc.uri.endsWith('/pack.mcmeta')) {
|
|
9
|
-
|
|
59
|
+
return definition('::java::Pack')(node, ctx);
|
|
10
60
|
}
|
|
11
61
|
else {
|
|
12
62
|
return;
|
|
@@ -20,4 +70,181 @@ export function register(meta) {
|
|
|
20
70
|
meta.registerChecker('json:object', entry);
|
|
21
71
|
meta.registerChecker('json:string', entry);
|
|
22
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* @param identifier An identifier of mcdoc compound definition. e.g. `::minecraft::util::invitem::InventoryItem`
|
|
75
|
+
*/
|
|
76
|
+
export function definition(identifier) {
|
|
77
|
+
return (node, ctx) => {
|
|
78
|
+
const symbol = ctx.symbols.query(ctx.doc, 'mcdoc', identifier);
|
|
79
|
+
const typeDef = symbol.getData(mcdoc.binder.TypeDefSymbolData.is)?.typeDef;
|
|
80
|
+
if (!typeDef) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
switch (typeDef.kind) {
|
|
84
|
+
case 'struct':
|
|
85
|
+
object(typeDef)(node, ctx);
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
ctx.logger.error(`[json.checker.definition] Expected a struct type, but got ${typeDef.kind}`);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function object(typeDef) {
|
|
93
|
+
return (node, ctx) => {
|
|
94
|
+
if (!JsonObjectNode.is(node)) {
|
|
95
|
+
// TODO
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
for (const { key: keyNode, value: valueNode } of node.children) {
|
|
99
|
+
if (!keyNode || !valueNode) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const key = keyNode.value;
|
|
103
|
+
// TODO: handle spread types
|
|
104
|
+
const fieldDef = typeDef.fields.find((p) => p.kind === 'pair' && p.key === key);
|
|
105
|
+
if (fieldDef) {
|
|
106
|
+
// TODO: enter a reference to the mcdoc key
|
|
107
|
+
fieldValue(fieldDef.type)(valueNode, ctx);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
ctx.err.report(localize('unknown-key', localeQuote(key)), keyNode, 2 /* core.ErrorSeverity.Warning */);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// TODO: check for required fields
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function fieldValue(type) {
|
|
117
|
+
const isInRange = (value, { kind, min = -Infinity, max = Infinity }) => {
|
|
118
|
+
const comparator = (a, b, exclusive) => exclusive ? a < b : a <= b;
|
|
119
|
+
return (comparator(min, value, kind & 0b10) && comparator(value, max, kind & 0b01));
|
|
120
|
+
};
|
|
121
|
+
const ExpectedTypes = {
|
|
122
|
+
boolean: 'json:boolean',
|
|
123
|
+
byte: 'json:number',
|
|
124
|
+
byte_array: 'json:array',
|
|
125
|
+
double: 'json:number',
|
|
126
|
+
float: 'json:number',
|
|
127
|
+
int: 'json:number',
|
|
128
|
+
int_array: 'json:array',
|
|
129
|
+
list: 'json:array',
|
|
130
|
+
long: 'json:number',
|
|
131
|
+
long_array: 'json:array',
|
|
132
|
+
short: 'json:number',
|
|
133
|
+
string: 'json:string',
|
|
134
|
+
struct: 'json:object',
|
|
135
|
+
tuple: 'json:array',
|
|
136
|
+
};
|
|
137
|
+
return (node, ctx) => {
|
|
138
|
+
// Rough type check.
|
|
139
|
+
if (type.kind !== 'any' &&
|
|
140
|
+
type.kind !== 'dispatcher' &&
|
|
141
|
+
type.kind !== 'enum' &&
|
|
142
|
+
type.kind !== 'literal' &&
|
|
143
|
+
type.kind !== 'reference' &&
|
|
144
|
+
type.kind !== 'union' &&
|
|
145
|
+
type.kind !== 'attributed' &&
|
|
146
|
+
type.kind !== 'unsafe' &&
|
|
147
|
+
type.kind !== 'concrete' &&
|
|
148
|
+
type.kind !== 'indexed' &&
|
|
149
|
+
type.kind !== 'template' &&
|
|
150
|
+
node.type !== ExpectedTypes[type.kind]) {
|
|
151
|
+
ctx.err.report(localize('expected', localizeTag(ExpectedTypes[type.kind])), node, 2 /* core.ErrorSeverity.Warning */);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
switch (type.kind) {
|
|
155
|
+
case 'boolean':
|
|
156
|
+
break;
|
|
157
|
+
case 'byte_array':
|
|
158
|
+
case 'int_array':
|
|
159
|
+
case 'long_array':
|
|
160
|
+
node = node;
|
|
161
|
+
if (type.lengthRange &&
|
|
162
|
+
!isInRange(node.children.length, type.lengthRange)) {
|
|
163
|
+
ctx.err.report(localize('expected', localize('json.checker.array.length-between', localizeTag(node.type), type.lengthRange.min ?? '-∞', type.lengthRange.max ?? '+∞')), node, 2 /* core.ErrorSeverity.Warning */);
|
|
164
|
+
}
|
|
165
|
+
if (type.valueRange) {
|
|
166
|
+
for (const { value: childNode } of node.children) {
|
|
167
|
+
if (childNode?.type !== 'json:number') {
|
|
168
|
+
ctx.err.report(localize('expected', localizeTag('json:number')), node, 2 /* core.ErrorSeverity.Warning */);
|
|
169
|
+
}
|
|
170
|
+
else if (childNode &&
|
|
171
|
+
!isInRange(Number(childNode.value), type.valueRange)) {
|
|
172
|
+
ctx.err.report(localize('number.between', type.valueRange.min ?? '-∞', type.valueRange.max ?? '+∞'), node, 2 /* core.ErrorSeverity.Warning */);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
case 'byte':
|
|
178
|
+
case 'short':
|
|
179
|
+
case 'int':
|
|
180
|
+
case 'long':
|
|
181
|
+
case 'float':
|
|
182
|
+
case 'double':
|
|
183
|
+
node = node;
|
|
184
|
+
if (type.valueRange &&
|
|
185
|
+
!isInRange(Number(node.value), type.valueRange)) {
|
|
186
|
+
ctx.err.report(localize('number.between', type.valueRange.min ?? '-∞', type.valueRange.max ?? '+∞'), node, 2 /* core.ErrorSeverity.Warning */);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
case 'dispatcher':
|
|
190
|
+
node = node;
|
|
191
|
+
// const id = resolveFieldPath(node.parent?.parent, type.index.path)
|
|
192
|
+
// if (type.index.registry) {
|
|
193
|
+
// if (ExtendableRootRegistry.is(type.index.registry)) {
|
|
194
|
+
// index(type.index.registry, id ? core.ResourceLocation.lengthen(id) : undefined, options)(node, ctx)
|
|
195
|
+
// } else if (id) {
|
|
196
|
+
// index(type.index.registry, core.ResourceLocation.lengthen(id), options)(node, ctx)
|
|
197
|
+
// }
|
|
198
|
+
// }
|
|
199
|
+
break;
|
|
200
|
+
case 'list':
|
|
201
|
+
node = node;
|
|
202
|
+
type = mcdoc.simplifyListType(type);
|
|
203
|
+
if (type.lengthRange &&
|
|
204
|
+
!isInRange(node.children.length, type.lengthRange)) {
|
|
205
|
+
ctx.err.report(localize('expected', localize('json.checker.collection.length-between', localizeTag(node.type), type.lengthRange.min ?? '-∞', type.lengthRange.max ?? '+∞')), node, 2 /* core.ErrorSeverity.Warning */);
|
|
206
|
+
}
|
|
207
|
+
for (const { value: childNode } of node.children) {
|
|
208
|
+
if (childNode) {
|
|
209
|
+
fieldValue(type.item)(childNode, ctx);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
case 'struct':
|
|
214
|
+
node = node;
|
|
215
|
+
object(type)(node, ctx);
|
|
216
|
+
break;
|
|
217
|
+
case 'string':
|
|
218
|
+
break;
|
|
219
|
+
case 'reference':
|
|
220
|
+
// node = node as JsonObjectNode
|
|
221
|
+
// if (type.symbol) {
|
|
222
|
+
// const { allowUnknownKey, value } = resolveSymbolPaths([type.symbol], ctx, node)
|
|
223
|
+
// compound(value, { ...options, allowUnknownKey: options.allowUnknownKey || allowUnknownKey })(node, ctx)
|
|
224
|
+
// }
|
|
225
|
+
break;
|
|
226
|
+
case 'union':
|
|
227
|
+
type = mcdoc.flattenUnionType(type);
|
|
228
|
+
if (type.members.length === 0) {
|
|
229
|
+
ctx.err.report(localize('json.checker.object.field.union-empty-members'), core.PairNode.is(node.parent)
|
|
230
|
+
? node.parent.key ?? node.parent
|
|
231
|
+
: node, 2 /* core.ErrorSeverity.Warning */);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
;
|
|
235
|
+
core.checker.any(type.members.map((t) => fieldValue(t)))(node, ctx);
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
case 'attributed':
|
|
239
|
+
// TODO: don't just ignore the attribute
|
|
240
|
+
fieldValue(type.child)(node, ctx);
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function localizeTag(type) {
|
|
246
|
+
const key = `json.node.${type.replace(/^json:/, '')}`;
|
|
247
|
+
const res = localize(key);
|
|
248
|
+
return res;
|
|
249
|
+
}
|
|
23
250
|
//# sourceMappingURL=index.js.map
|
|
@@ -6,10 +6,10 @@ export function criterionReference(advancement) {
|
|
|
6
6
|
simpleString(node, ctx);
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
|
-
const criteria = Object.values(ctx.symbols.query(ctx.doc, 'advancement', advancement).symbol
|
|
10
|
-
|
|
9
|
+
const criteria = Object.values(ctx.symbols.query(ctx.doc, 'advancement', advancement).symbol?.members ??
|
|
10
|
+
{})
|
|
11
11
|
.filter((m) => m?.subcategory === 'criterion')
|
|
12
|
-
.map(s => s.identifier);
|
|
12
|
+
.map((s) => s.identifier);
|
|
13
13
|
literal(criteria)(node, ctx);
|
|
14
14
|
};
|
|
15
15
|
}
|
|
@@ -7,7 +7,7 @@ interface Options {
|
|
|
7
7
|
mixedTypes?: boolean;
|
|
8
8
|
requireAll?: boolean;
|
|
9
9
|
}
|
|
10
|
-
export declare function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }: Options): JsonChecker;
|
|
11
|
-
export declare function blockStateList({ category, id, ids, tag }: Options): JsonChecker;
|
|
10
|
+
export declare function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll, }: Options): JsonChecker;
|
|
11
|
+
export declare function blockStateList({ category, id, ids, tag, }: Options): JsonChecker;
|
|
12
12
|
export {};
|
|
13
13
|
//# sourceMappingURL=block_states.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
|
-
import { any, boolean, intRange, listOf, literal, object, opt, record, simpleString } from '@spyglassmc/json/lib/checker/index.js';
|
|
2
|
+
import { any, boolean, intRange, listOf, literal, object, opt, record, simpleString, } from '@spyglassmc/json/lib/checker/index.js';
|
|
3
3
|
import { getTagValues } from '../../../common/index.js';
|
|
4
|
-
export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }) {
|
|
4
|
+
export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll, }) {
|
|
5
5
|
return (node, ctx) => {
|
|
6
6
|
if (tag) {
|
|
7
7
|
ids = getTagValues(`tag/${category ?? 'block'}`, tag, ctx);
|
|
@@ -11,8 +11,10 @@ export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }
|
|
|
11
11
|
}
|
|
12
12
|
// FIXME: Temporary solution to make tests pass when ensureBindingStarted is not given.
|
|
13
13
|
if (!ids?.length || !ctx.ensureBindingStarted) {
|
|
14
|
-
const values = mixedTypes
|
|
15
|
-
|
|
14
|
+
const values = mixedTypes
|
|
15
|
+
? any([boolean, simpleString, intBounds()])
|
|
16
|
+
: simpleString;
|
|
17
|
+
object(simpleString, () => (requireAll ? values : opt(values)))(node, ctx);
|
|
16
18
|
return;
|
|
17
19
|
}
|
|
18
20
|
const states = core.getStates(category ?? 'block', ids, ctx);
|
|
@@ -32,7 +34,7 @@ export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }
|
|
|
32
34
|
})(node, ctx);
|
|
33
35
|
};
|
|
34
36
|
}
|
|
35
|
-
export function blockStateList({ category, id, ids, tag }) {
|
|
37
|
+
export function blockStateList({ category, id, ids, tag, }) {
|
|
36
38
|
return (node, ctx) => {
|
|
37
39
|
if (tag) {
|
|
38
40
|
ids = getTagValues(`tag/${category ?? 'block'}`, tag, ctx);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Color, ColorFormat, Failure, parseStringValue, Range } from '@spyglassmc/core';
|
|
1
|
+
import { Color, ColorFormat, Failure, parseStringValue, Range, } from '@spyglassmc/core';
|
|
2
2
|
import { JsonNumberNode, JsonStringNode } from '@spyglassmc/json';
|
|
3
3
|
import { localize } from '@spyglassmc/locales';
|
|
4
4
|
export function stringColor() {
|
|
@@ -27,7 +27,13 @@ export function stringColor() {
|
|
|
27
27
|
return Color.fromCompositeInt(value);
|
|
28
28
|
};
|
|
29
29
|
return (node, ctx) => {
|
|
30
|
-
node.expectation = [
|
|
30
|
+
node.expectation = [
|
|
31
|
+
{
|
|
32
|
+
type: 'json:string',
|
|
33
|
+
typedoc: 'String("Color")',
|
|
34
|
+
pool: Color.ColorNames,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
31
37
|
if (!JsonStringNode.is(node)) {
|
|
32
38
|
ctx.err.report(localize('expected', localize('string')), node);
|
|
33
39
|
}
|
|
@@ -53,9 +53,10 @@ export function nbtPath(options) {
|
|
|
53
53
|
}
|
|
54
54
|
function getIds({ registry, id, idOrTag, ids, tag }, ctx) {
|
|
55
55
|
if (idOrTag) {
|
|
56
|
-
idOrTag.startsWith('#') ? tag = idOrTag.slice(1) : id = idOrTag;
|
|
56
|
+
idOrTag.startsWith('#') ? (tag = idOrTag.slice(1)) : (id = idOrTag);
|
|
57
57
|
}
|
|
58
|
-
if (tag &&
|
|
58
|
+
if (tag &&
|
|
59
|
+
(registry === 'block' || registry === 'item' || registry === 'entity_type')) {
|
|
59
60
|
ids = getTagValues(`tag/${registry}`, tag, ctx);
|
|
60
61
|
}
|
|
61
62
|
else if (id) {
|
|
@@ -2,11 +2,12 @@ import { symbol } from '@spyglassmc/core';
|
|
|
2
2
|
import { string } from '@spyglassmc/json/lib/checker/index.js';
|
|
3
3
|
export const recipeGroup = string('recipe_group', symbol('recipe_group'));
|
|
4
4
|
export function patternKeys(props) {
|
|
5
|
-
return [
|
|
6
|
-
|
|
7
|
-
.map(n => n.value)
|
|
8
|
-
.filter(n => n && n.type === 'json:string')
|
|
9
|
-
.flatMap(n => [...n.value])
|
|
10
|
-
.filter(v => v !== ' '))
|
|
5
|
+
return [
|
|
6
|
+
...new Set((props.find((p) => p.key?.value === 'pattern' && p.value?.type === 'json:array')?.value?.children ?? [])
|
|
7
|
+
.map((n) => n.value)
|
|
8
|
+
.filter((n) => n && n.type === 'json:string')
|
|
9
|
+
.flatMap((n) => [...n.value])
|
|
10
|
+
.filter((v) => v !== ' ')),
|
|
11
|
+
];
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=recipe.js.map
|
|
@@ -25,10 +25,10 @@ export function versioned(ctx, arg1, arg2, arg3) {
|
|
|
25
25
|
return arg1;
|
|
26
26
|
}
|
|
27
27
|
else if (Array.isArray(arg1)) {
|
|
28
|
-
return check ? arg1 :
|
|
28
|
+
return check ? arg1 : arg3 ?? [];
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
return check ? arg1 :
|
|
31
|
+
return check ? arg1 : arg3 ?? undefined;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -19,7 +19,7 @@ const getNode = (nodes, index) => {
|
|
|
19
19
|
return nodes[index]?.children[0];
|
|
20
20
|
};
|
|
21
21
|
const rootCommand = (nodes, index, ctx) => {
|
|
22
|
-
for (const { children: [node] } of nodes) {
|
|
22
|
+
for (const { children: [node], } of nodes) {
|
|
23
23
|
if (BlockNode.is(node)) {
|
|
24
24
|
block(node, ctx);
|
|
25
25
|
}
|
|
@@ -108,7 +108,8 @@ const rootCommand = (nodes, index, ctx) => {
|
|
|
108
108
|
}
|
|
109
109
|
else if (getName(nodes, index) === 'execute') {
|
|
110
110
|
for (let i = index + 1; i < nodes.length; i++) {
|
|
111
|
-
if ((getName(nodes, i) === 'if' || getName(nodes, i) === 'unless') &&
|
|
111
|
+
if ((getName(nodes, i) === 'if' || getName(nodes, i) === 'unless') &&
|
|
112
|
+
getName(nodes, i + 1) === 'data') {
|
|
112
113
|
// `if|unless data <$nbtPath$>`
|
|
113
114
|
nbtPath(nodes, i + 2, ctx);
|
|
114
115
|
i += 2;
|
|
@@ -131,7 +132,7 @@ const block = (node, ctx) => {
|
|
|
131
132
|
nbt.checker.index('block', core.ResourceLocationNode.toString(node.id, 'full'))(node.nbt, ctx);
|
|
132
133
|
};
|
|
133
134
|
const entity = (node, ctx) => {
|
|
134
|
-
const nbtPair = node.selector?.arguments?.children.find(pair => pair.key?.value === 'nbt');
|
|
135
|
+
const nbtPair = node.selector?.arguments?.children.find((pair) => pair.key?.value === 'nbt');
|
|
135
136
|
if (!nbtPair) {
|
|
136
137
|
return;
|
|
137
138
|
}
|
|
@@ -177,7 +178,8 @@ const dataMergeTarget = (nodes, index, ctx) => {
|
|
|
177
178
|
case 'storage': {
|
|
178
179
|
const idNode = getNode(nodes, index + 1);
|
|
179
180
|
const nbtNode = getNode(nodes, index + 2);
|
|
180
|
-
if (core.ResourceLocationNode.is(idNode) &&
|
|
181
|
+
if (core.ResourceLocationNode.is(idNode) &&
|
|
182
|
+
nbt.NbtCompoundNode.is(nbtNode)) {
|
|
181
183
|
nbt.checker.index('storage', core.ResourceLocationNode.toString(idNode, 'full'))(nbtNode, ctx);
|
|
182
184
|
}
|
|
183
185
|
break;
|
|
@@ -224,7 +226,8 @@ const nbtPath = (nodes, index, ctx) => {
|
|
|
224
226
|
const summonNbt = (nodes, index, ctx) => {
|
|
225
227
|
const typeNode = getNode(nodes, index);
|
|
226
228
|
const nbtNode = getNode(nodes, index + 2);
|
|
227
|
-
if (core.ResourceLocationNode.is(typeNode) &&
|
|
229
|
+
if (core.ResourceLocationNode.is(typeNode) &&
|
|
230
|
+
nbt.NbtCompoundNode.is(nbtNode)) {
|
|
228
231
|
nbt.checker.index('entity_type', core.ResourceLocationNode.toString(typeNode, 'full'))(nbtNode, ctx);
|
|
229
232
|
}
|
|
230
233
|
};
|
|
@@ -247,10 +250,10 @@ export const getTypesFromEntity = (entity, ctx) => {
|
|
|
247
250
|
if (!valueNode || valueNode.inverted) {
|
|
248
251
|
continue;
|
|
249
252
|
}
|
|
250
|
-
const value = core.ResourceLocationNode.toString(valueNode.value, 'full');
|
|
253
|
+
const value = core.ResourceLocationNode.toString(valueNode.value, 'full', true);
|
|
251
254
|
if (value.startsWith(core.ResourceLocation.TagPrefix)) {
|
|
252
255
|
const tagValues = getTagValues('tag/entity_type', value.slice(1), ctx);
|
|
253
|
-
types = types.filter(t => tagValues.includes(t));
|
|
256
|
+
types = types.filter((t) => tagValues.includes(t));
|
|
254
257
|
}
|
|
255
258
|
else {
|
|
256
259
|
types = [value];
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
|
-
export const objectiveCriterion = node => [
|
|
3
|
-
|
|
4
|
-
];
|
|
5
|
-
export const vector = node => {
|
|
2
|
+
export const objectiveCriterion = (node) => [core.ColorToken.create(node, 'type')];
|
|
3
|
+
export const vector = (node) => {
|
|
6
4
|
return [core.ColorToken.create(node, 'vector')];
|
|
7
5
|
};
|
|
8
6
|
export function register(meta) {
|
|
@@ -2,24 +2,55 @@ import * as core from '@spyglassmc/core';
|
|
|
2
2
|
export const ColorArgumentValues = [...core.Color.ColorNames, 'reset'];
|
|
3
3
|
export const EntityAnchorArgumentValues = ['feet', 'eyes'];
|
|
4
4
|
export const ItemSlotArgumentValues = [
|
|
5
|
-
...[...Array(54).keys()].map(n => `container.${n}`),
|
|
6
|
-
...[...Array(27).keys()].map(n => `enderchest.${n}`),
|
|
7
|
-
...[...Array(15).keys()].map(n => `horse.${n}`),
|
|
8
|
-
...[...Array(9).keys()].map(n => `hotbar.${n}`),
|
|
9
|
-
...[...Array(27).keys()].map(n => `inventory.${n}`),
|
|
10
|
-
...[...Array(8).keys()].map(n => `villager.${n}`),
|
|
11
|
-
'armor.chest',
|
|
12
|
-
'
|
|
13
|
-
'
|
|
5
|
+
...[...Array(54).keys()].map((n) => `container.${n}`),
|
|
6
|
+
...[...Array(27).keys()].map((n) => `enderchest.${n}`),
|
|
7
|
+
...[...Array(15).keys()].map((n) => `horse.${n}`),
|
|
8
|
+
...[...Array(9).keys()].map((n) => `hotbar.${n}`),
|
|
9
|
+
...[...Array(27).keys()].map((n) => `inventory.${n}`),
|
|
10
|
+
...[...Array(8).keys()].map((n) => `villager.${n}`),
|
|
11
|
+
'armor.chest',
|
|
12
|
+
'armor.feet',
|
|
13
|
+
'armor.head',
|
|
14
|
+
'armor.legs',
|
|
15
|
+
'horse.armor',
|
|
16
|
+
'horse.chest',
|
|
17
|
+
'horse.saddle',
|
|
18
|
+
'weapon',
|
|
19
|
+
'weapon.mainhand',
|
|
20
|
+
'weapon.offhand',
|
|
21
|
+
];
|
|
22
|
+
export const OperationArgumentValues = [
|
|
23
|
+
'=',
|
|
24
|
+
'+=',
|
|
25
|
+
'-=',
|
|
26
|
+
'*=',
|
|
27
|
+
'/=',
|
|
28
|
+
'%=',
|
|
29
|
+
'<',
|
|
30
|
+
'>',
|
|
31
|
+
'><',
|
|
14
32
|
];
|
|
15
|
-
export const OperationArgumentValues = ['=', '+=', '-=', '*=', '/=', '%=', '<', '>', '><'];
|
|
16
33
|
export const ScoreboardSlotArgumentValues = [
|
|
17
|
-
'belowName',
|
|
18
|
-
|
|
34
|
+
'belowName',
|
|
35
|
+
'list',
|
|
36
|
+
'sidebar',
|
|
37
|
+
...core.Color.ColorNames.map((n) => `sidebar.team.${n}`),
|
|
19
38
|
];
|
|
20
39
|
export const SwizzleArgumentValues = [
|
|
21
|
-
'x',
|
|
22
|
-
'
|
|
23
|
-
'
|
|
40
|
+
'x',
|
|
41
|
+
'xy',
|
|
42
|
+
'xz',
|
|
43
|
+
'xyz',
|
|
44
|
+
'xzy',
|
|
45
|
+
'y',
|
|
46
|
+
'yx',
|
|
47
|
+
'yz',
|
|
48
|
+
'yxz',
|
|
49
|
+
'yzx',
|
|
50
|
+
'z',
|
|
51
|
+
'zx',
|
|
52
|
+
'zy',
|
|
53
|
+
'zxy',
|
|
54
|
+
'zyx',
|
|
24
55
|
];
|
|
25
56
|
//# sourceMappingURL=index.js.map
|