@terrafirmagreg-team/dump 0.0.0-stage → 1.2.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/package.json +28 -3
- package/src/lib/dump/assets/atlas/dto.ts +51 -0
- package/src/lib/dump/assets/atlas/lookup.ts +207 -0
- package/src/lib/dump/assets/atlas/sprites.ts +132 -0
- package/src/lib/dump/assets/lang/load.ts +19 -0
- package/src/lib/dump/assets/lang/names.ts +244 -0
- package/src/lib/dump/assets/urls.ts +145 -0
- package/src/lib/dump/client/atlases.ts +85 -0
- package/src/lib/dump/client/dump.ts +132 -0
- package/src/lib/dump/client/groups.ts +27 -0
- package/src/lib/dump/client/keybinds.ts +16 -0
- package/src/lib/dump/client/mods.ts +18 -0
- package/src/lib/dump/client/registry.ts +121 -0
- package/src/lib/dump/client/tabs.ts +23 -0
- package/src/lib/dump/client/tags.ts +59 -0
- package/src/lib/dump/contract/kind.ts +62 -0
- package/src/lib/dump/contract/read.ts +76 -0
- package/src/lib/dump/contract/ref.ts +260 -0
- package/src/lib/dump/contract/text.ts +101 -0
- package/src/lib/dump/data/registry/dto.ts +57 -0
- package/src/lib/dump/data/registry/parse.ts +291 -0
- package/src/lib/dump/data/tab/dto.ts +14 -0
- package/src/lib/dump/data/tab/parse.ts +27 -0
- package/src/lib/dump/data/tag/dto.ts +8 -0
- package/src/lib/dump/data/tag/parse.ts +58 -0
- package/src/lib/dump/gen/data/guides/book.ts +57 -0
- package/src/lib/dump/gen/data/guides/category.ts +31 -0
- package/src/lib/dump/gen/data/guides/entry.ts +49 -0
- package/src/lib/dump/gen/data/models/model.ts +4 -0
- package/src/lib/dump/gen/data/quests/chapter.ts +127 -0
- package/src/lib/dump/gen/data/quests/chapter_groups.ts +12 -0
- package/src/lib/dump/gen/data/quests/data.ts +41 -0
- package/src/lib/dump/gen/data/recipes/recipe.ts +79 -0
- package/src/lib/dump/gen/index.ts +21 -0
- package/src/lib/dump/gen/keybinds.ts +4 -0
- package/src/lib/dump/gen/lang.ts +4 -0
- package/src/lib/dump/gen/manifest.ts +60 -0
- package/src/lib/dump/gen/registry/blocks.ts +61 -0
- package/src/lib/dump/gen/registry/entities.ts +50 -0
- package/src/lib/dump/gen/registry/fluids.ts +49 -0
- package/src/lib/dump/gen/registry/groups.ts +15 -0
- package/src/lib/dump/gen/registry/items.ts +52 -0
- package/src/lib/dump/gen/registry/recipe_categories.ts +65 -0
- package/src/lib/dump/gen/registry/recipes.ts +4 -0
- package/src/lib/dump/gen/registry/tabs.ts +47 -0
- package/src/lib/dump/gen/registry/tags.ts +12 -0
- package/src/lib/dump/json-reader.ts +254 -0
- package/src/lib/dump/manifest/dto.ts +12 -0
- package/src/lib/dump/manifest/parse.ts +168 -0
- package/src/lib/dump/mods/dto.ts +31 -0
- package/src/lib/dump/mods/index.ts +97 -0
- package/src/lib/dump/mods/load.ts +60 -0
- package/src/lib/dump/paths.ts +172 -0
- package/src/lib/dump/reader.ts +31 -0
- package/src/lib/dump-search.ts +125 -0
- package/src/lib/snbt.ts +247 -0
- package/README.md +0 -3
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
2
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
|
|
3
|
+
return value as Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function asString(value: unknown): string | undefined {
|
|
7
|
+
return typeof value === 'string' && value ? value : undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function asNumber(value: unknown): number | undefined {
|
|
11
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function asBool(value: unknown): boolean | undefined {
|
|
15
|
+
if (typeof value === 'boolean') return value;
|
|
16
|
+
if (value === 1) return true;
|
|
17
|
+
if (value === 0) return false;
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function asStringList(value: unknown): string[] {
|
|
22
|
+
if (!Array.isArray(value)) return [];
|
|
23
|
+
return value.filter((item): item is string => typeof item === 'string' && Boolean(item));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const EDGE_TABLE_FIELD = '$ids';
|
|
27
|
+
|
|
28
|
+
export function asIdTable(file: unknown): string[] | undefined {
|
|
29
|
+
const ids = asStringList(asRecord(file)?.[EDGE_TABLE_FIELD]);
|
|
30
|
+
return ids.length ? ids : undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function asEdgeList(value: unknown, ids?: string[]): string[] {
|
|
34
|
+
if (!Array.isArray(value)) return [];
|
|
35
|
+
const out: string[] = [];
|
|
36
|
+
for (const item of value) {
|
|
37
|
+
if (typeof item === 'string') {
|
|
38
|
+
if (item) out.push(item);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (typeof item === 'number' && Number.isInteger(item)) {
|
|
42
|
+
const ref = ids?.[item];
|
|
43
|
+
if (ref) out.push(ref);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function resolveEdgeRows(
|
|
50
|
+
map: Record<string, unknown>,
|
|
51
|
+
): Record<string, Record<string, unknown>> {
|
|
52
|
+
const ids = asIdTable(map);
|
|
53
|
+
const out: Record<string, Record<string, unknown>> = {};
|
|
54
|
+
for (const [key, value] of Object.entries(map)) {
|
|
55
|
+
if (key === EDGE_TABLE_FIELD) continue;
|
|
56
|
+
const row = asRecord(value);
|
|
57
|
+
if (!row) continue;
|
|
58
|
+
if (ids) {
|
|
59
|
+
if (Array.isArray(row.usedBy)) row.usedBy = asEdgeList(row.usedBy, ids);
|
|
60
|
+
if (Array.isArray(row.producedBy)) row.producedBy = asEdgeList(row.producedBy, ids);
|
|
61
|
+
}
|
|
62
|
+
out[key] = row;
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function asStringMap(value: unknown): Record<string, string> | undefined {
|
|
68
|
+
const row = asRecord(value);
|
|
69
|
+
if (!row) return undefined;
|
|
70
|
+
const out: Record<string, string> = {};
|
|
71
|
+
for (const [key, item] of Object.entries(row)) {
|
|
72
|
+
if (typeof item === 'string') out[key] = item;
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { formatNbt, parseSnbt } from '@terrafirmagreg-team/dump/lib/snbt';
|
|
2
|
+
import { asRecord, asString } from '@terrafirmagreg-team/dump/lib/dump/contract/read';
|
|
3
|
+
|
|
4
|
+
const REFERENCE_KINDS = [
|
|
5
|
+
'item',
|
|
6
|
+
'block',
|
|
7
|
+
'fluid',
|
|
8
|
+
'entity',
|
|
9
|
+
'itemTag',
|
|
10
|
+
'blockTag',
|
|
11
|
+
'fluidTag',
|
|
12
|
+
'entityTag',
|
|
13
|
+
'texture',
|
|
14
|
+
'model',
|
|
15
|
+
'recipe',
|
|
16
|
+
'guide',
|
|
17
|
+
'quest',
|
|
18
|
+
'chapter',
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
export type ReferenceKind = (typeof REFERENCE_KINDS)[number];
|
|
22
|
+
|
|
23
|
+
const TAG_KINDS = ['itemTag', 'blockTag', 'fluidTag', 'entityTag'] as const;
|
|
24
|
+
|
|
25
|
+
const ICON_KINDS: readonly ReferenceKind[] = [
|
|
26
|
+
'item',
|
|
27
|
+
'block',
|
|
28
|
+
'fluid',
|
|
29
|
+
'entity',
|
|
30
|
+
...TAG_KINDS,
|
|
31
|
+
'texture',
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
export type DumpNbt =
|
|
35
|
+
| string
|
|
36
|
+
| number
|
|
37
|
+
| boolean
|
|
38
|
+
| null
|
|
39
|
+
| DumpNbt[]
|
|
40
|
+
| { [key: string]: DumpNbt };
|
|
41
|
+
|
|
42
|
+
export type TaggedReference = {
|
|
43
|
+
kind: ReferenceKind;
|
|
44
|
+
id: string;
|
|
45
|
+
tag?: DumpNbt;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type ParsedStackId = {
|
|
49
|
+
id: string;
|
|
50
|
+
nbt?: DumpNbt;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function asReferenceKind(value: unknown): ReferenceKind | undefined {
|
|
54
|
+
if (typeof value !== 'string') return undefined;
|
|
55
|
+
return (REFERENCE_KINDS as readonly string[]).includes(value)
|
|
56
|
+
? (value as ReferenceKind)
|
|
57
|
+
: undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function asNbt(value: unknown): DumpNbt | undefined {
|
|
61
|
+
if (value === null) return null;
|
|
62
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(value)) return value as DumpNbt[];
|
|
66
|
+
const row = asRecord(value);
|
|
67
|
+
if (!row || Object.keys(row).length === 0) return undefined;
|
|
68
|
+
return row as { [key: string]: DumpNbt };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function nbtAt(
|
|
72
|
+
tag: DumpNbt | undefined,
|
|
73
|
+
...path: (string | number)[]
|
|
74
|
+
): DumpNbt | undefined {
|
|
75
|
+
let cur: DumpNbt | undefined = tag;
|
|
76
|
+
for (const key of path) {
|
|
77
|
+
if (cur === undefined || cur === null) return undefined;
|
|
78
|
+
if (typeof key === 'number') {
|
|
79
|
+
if (!Array.isArray(cur)) return undefined;
|
|
80
|
+
cur = cur[key];
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (typeof cur !== 'object' || Array.isArray(cur)) return undefined;
|
|
84
|
+
cur = cur[key];
|
|
85
|
+
}
|
|
86
|
+
return cur;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function parseStackId(compact: string): ParsedStackId {
|
|
90
|
+
const brace = compact.indexOf('{');
|
|
91
|
+
if (brace <= 0) return { id: compact };
|
|
92
|
+
const id = compact.slice(0, brace);
|
|
93
|
+
if (!id) return { id: compact };
|
|
94
|
+
try {
|
|
95
|
+
const nbt = asNbt(parseSnbt(compact.slice(brace)));
|
|
96
|
+
return nbt !== undefined ? { id, nbt } : { id };
|
|
97
|
+
} catch {
|
|
98
|
+
return { id };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function stackIdBase(compact: string): string {
|
|
103
|
+
const brace = compact.indexOf('{');
|
|
104
|
+
return brace > 0 ? compact.slice(0, brace) : compact;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function canonicalStackId(compact: string): string {
|
|
108
|
+
const brace = compact.indexOf('{');
|
|
109
|
+
if (brace <= 0) return compact;
|
|
110
|
+
const parsed = parseStackId(compact);
|
|
111
|
+
const nbt = formatNbt(parsed.nbt);
|
|
112
|
+
return nbt !== undefined && nbt.startsWith('{')
|
|
113
|
+
? `${parsed.id}${nbt}`
|
|
114
|
+
: compact;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function asTaggedReference(value: unknown): TaggedReference | undefined {
|
|
118
|
+
const row = asRecord(value);
|
|
119
|
+
if (!row) return undefined;
|
|
120
|
+
const kind = asReferenceKind(row.kind);
|
|
121
|
+
const id = asString(row.id);
|
|
122
|
+
if (!kind || !id) return undefined;
|
|
123
|
+
const tag = asNbt(row.tag);
|
|
124
|
+
return { kind, id, ...(tag !== undefined ? { tag } : {}) };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function isTagKind(
|
|
128
|
+
kind: ReferenceKind | undefined,
|
|
129
|
+
): kind is (typeof TAG_KINDS)[number] {
|
|
130
|
+
return kind !== undefined && (TAG_KINDS as readonly string[]).includes(kind);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function tagKindOf(
|
|
134
|
+
kind: ReferenceKind | undefined,
|
|
135
|
+
): 'item' | 'block' | 'fluid' | 'entity' | undefined {
|
|
136
|
+
switch (kind) {
|
|
137
|
+
case 'itemTag':
|
|
138
|
+
return 'item';
|
|
139
|
+
case 'blockTag':
|
|
140
|
+
return 'block';
|
|
141
|
+
case 'fluidTag':
|
|
142
|
+
return 'fluid';
|
|
143
|
+
case 'entityTag':
|
|
144
|
+
return 'entity';
|
|
145
|
+
default:
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function isIconKind(kind: ReferenceKind | undefined): boolean {
|
|
151
|
+
return kind !== undefined && ICON_KINDS.includes(kind);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function classifyRefId(
|
|
155
|
+
id: string,
|
|
156
|
+
kind?: ReferenceKind,
|
|
157
|
+
): TaggedReference | undefined {
|
|
158
|
+
const trimmed = id.trim();
|
|
159
|
+
if (!trimmed) return undefined;
|
|
160
|
+
const parsed = parseStackId(
|
|
161
|
+
trimmed.startsWith('#') ? trimmed.slice(1) : trimmed,
|
|
162
|
+
);
|
|
163
|
+
const resolved = trimmed.startsWith('#')
|
|
164
|
+
? (isTagKind(kind) ? kind : 'itemTag')
|
|
165
|
+
: (kind ?? 'item');
|
|
166
|
+
return {
|
|
167
|
+
kind: resolved,
|
|
168
|
+
id: parsed.id,
|
|
169
|
+
...(parsed.nbt !== undefined ? { tag: parsed.nbt } : {}),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function refId(ref: TaggedReference): string {
|
|
174
|
+
return stackIdFromRef(ref);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function compactRefId(value: unknown): string | undefined {
|
|
178
|
+
if (typeof value === 'string' && value) return value;
|
|
179
|
+
const tagged = asTaggedReference(value);
|
|
180
|
+
return tagged ? stackIdFromRef(tagged) : undefined;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function nbtEquals(left: DumpNbt | undefined, right: DumpNbt | undefined): boolean {
|
|
184
|
+
if (left === right) return true;
|
|
185
|
+
if (left === undefined || right === undefined) return false;
|
|
186
|
+
if (left === null || right === null) return left === right;
|
|
187
|
+
if (typeof left !== typeof right) return false;
|
|
188
|
+
if (typeof left !== 'object') return left === right;
|
|
189
|
+
if (Array.isArray(left)) {
|
|
190
|
+
return (
|
|
191
|
+
Array.isArray(right) &&
|
|
192
|
+
left.length === right.length &&
|
|
193
|
+
left.every((value, index) => nbtEquals(value, right[index]))
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
if (Array.isArray(right)) return false;
|
|
197
|
+
const leftRow = left as { [key: string]: DumpNbt };
|
|
198
|
+
const rightRow = right as { [key: string]: DumpNbt };
|
|
199
|
+
const leftKeys = Object.keys(leftRow).sort();
|
|
200
|
+
const rightKeys = Object.keys(rightRow).sort();
|
|
201
|
+
if (leftKeys.length !== rightKeys.length) return false;
|
|
202
|
+
return leftKeys.every(
|
|
203
|
+
(key, index) => key === rightKeys[index] && nbtEquals(leftRow[key], rightRow[key]),
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function nbtMatches(pattern: DumpNbt | undefined, actual: DumpNbt | undefined): boolean {
|
|
208
|
+
if (pattern === undefined) return actual === undefined;
|
|
209
|
+
if (actual === undefined || actual === null) return pattern === actual;
|
|
210
|
+
if (pattern === null) return actual === null;
|
|
211
|
+
if (typeof pattern !== 'object') return pattern === actual;
|
|
212
|
+
if (Array.isArray(pattern)) {
|
|
213
|
+
if (!Array.isArray(actual) || pattern.length !== actual.length) return false;
|
|
214
|
+
return pattern.every((item, index) => nbtMatches(item, actual[index]));
|
|
215
|
+
}
|
|
216
|
+
if (typeof actual !== 'object' || Array.isArray(actual) || actual === null) return false;
|
|
217
|
+
const actualRow = actual as { [key: string]: DumpNbt };
|
|
218
|
+
return Object.entries(pattern).every(([key, value]) => nbtMatches(value, actualRow[key]));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function nbtKeyCount(tag: DumpNbt | undefined): number {
|
|
222
|
+
return tag !== null && typeof tag === 'object' && !Array.isArray(tag)
|
|
223
|
+
? Object.keys(tag ?? {}).length
|
|
224
|
+
: 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function nbtSharedKeys(left: DumpNbt | undefined, right: DumpNbt | undefined): number {
|
|
228
|
+
if (!left || !right) return 0;
|
|
229
|
+
if (typeof left !== 'object' || Array.isArray(left)) return 0;
|
|
230
|
+
if (typeof right !== 'object' || Array.isArray(right)) return 0;
|
|
231
|
+
const rightRow = right as { [key: string]: DumpNbt };
|
|
232
|
+
let shared = 0;
|
|
233
|
+
for (const [key, value] of Object.entries(left)) {
|
|
234
|
+
if (key in rightRow && nbtEquals(value, rightRow[key])) shared++;
|
|
235
|
+
}
|
|
236
|
+
return shared;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function nbtSpecificity(candidate: DumpNbt, query: DumpNbt): number {
|
|
240
|
+
if (nbtEquals(candidate, query)) return 500;
|
|
241
|
+
if (nbtMatches(candidate, query)) return 400 + nbtKeyCount(candidate);
|
|
242
|
+
if (nbtMatches(query, candidate)) return 300 - nbtKeyCount(candidate);
|
|
243
|
+
const shared = nbtSharedKeys(candidate, query);
|
|
244
|
+
return shared > 0 ? 200 + shared : -1;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function stackIdFromRef(ref: TaggedReference): string {
|
|
248
|
+
switch (ref.kind) {
|
|
249
|
+
case 'itemTag':
|
|
250
|
+
case 'blockTag':
|
|
251
|
+
case 'fluidTag':
|
|
252
|
+
case 'entityTag':
|
|
253
|
+
return `#${ref.id.replace(/^#+/, '')}`;
|
|
254
|
+
default: {
|
|
255
|
+
const tag = formatNbt(ref.tag);
|
|
256
|
+
return tag !== undefined && tag.startsWith('{') ? `${ref.id}${tag}` : ref.id;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { asRecord, asString } from '@terrafirmagreg-team/dump/lib/dump/contract/read';
|
|
2
|
+
|
|
3
|
+
export const MC_FORMAT_COLORS: Record<string, string> = {
|
|
4
|
+
'0': '#000000',
|
|
5
|
+
'1': '#0000aa',
|
|
6
|
+
'2': '#00aa00',
|
|
7
|
+
'3': '#00aaaa',
|
|
8
|
+
'4': '#aa0000',
|
|
9
|
+
'5': '#aa00aa',
|
|
10
|
+
'6': '#ffaa00',
|
|
11
|
+
'7': '#aaaaaa',
|
|
12
|
+
'8': '#555555',
|
|
13
|
+
'9': '#5555ff',
|
|
14
|
+
a: '#55ff55',
|
|
15
|
+
b: '#55ffff',
|
|
16
|
+
c: '#ff5555',
|
|
17
|
+
d: '#ff55ff',
|
|
18
|
+
e: '#ffff55',
|
|
19
|
+
f: '#ffffff',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const MC_FORMAT = {
|
|
23
|
+
marker: '§',
|
|
24
|
+
colors: MC_FORMAT_COLORS,
|
|
25
|
+
styles: {
|
|
26
|
+
l: { fontWeight: 600 },
|
|
27
|
+
o: { fontStyle: 'italic' },
|
|
28
|
+
n: { textDecoration: 'underline' },
|
|
29
|
+
m: { textDecoration: 'line-through' },
|
|
30
|
+
},
|
|
31
|
+
reset: 'r',
|
|
32
|
+
hex: 'x',
|
|
33
|
+
ignore: ['k'],
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
36
|
+
export type DumpText = {
|
|
37
|
+
translate?: string;
|
|
38
|
+
text?: string;
|
|
39
|
+
keybind?: string;
|
|
40
|
+
with?: DumpText[];
|
|
41
|
+
extra?: DumpText[];
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type DumpDisplay = {
|
|
45
|
+
name?: string;
|
|
46
|
+
tooltip?: DumpText[];
|
|
47
|
+
|
|
48
|
+
tooltipMods?: Record<string, DumpText[]>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export function asDumpText(value: unknown): DumpText | undefined {
|
|
52
|
+
const row = asRecord(value);
|
|
53
|
+
if (!row) return undefined;
|
|
54
|
+
const translate = asString(row.translate);
|
|
55
|
+
const text = typeof row.text === 'string' ? row.text : undefined;
|
|
56
|
+
const keybind = asString(row.keybind);
|
|
57
|
+
const withParts = asDumpTextList(row.with);
|
|
58
|
+
const extra = asDumpTextList(row.extra);
|
|
59
|
+
if (!translate && text === undefined && !keybind && !withParts && !extra) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
...(translate ? { translate } : {}),
|
|
64
|
+
...(text !== undefined ? { text } : {}),
|
|
65
|
+
...(keybind ? { keybind } : {}),
|
|
66
|
+
...(withParts ? { with: withParts } : {}),
|
|
67
|
+
...(extra ? { extra } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function asDumpTextList(value: unknown): DumpText[] | undefined {
|
|
72
|
+
if (!Array.isArray(value)) return undefined;
|
|
73
|
+
const out = value.flatMap((item) => {
|
|
74
|
+
const text = asDumpText(item);
|
|
75
|
+
return text ? [text] : [];
|
|
76
|
+
});
|
|
77
|
+
return out.length ? out : undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function asDisplay(value: unknown): DumpDisplay | undefined {
|
|
81
|
+
const row = asRecord(value);
|
|
82
|
+
if (!row) return undefined;
|
|
83
|
+
const name = asString(row.name);
|
|
84
|
+
const tooltip = asDumpTextList(row.tooltip);
|
|
85
|
+
const modsRow = asRecord(row.tooltipMods);
|
|
86
|
+
const tooltipMods = modsRow
|
|
87
|
+
? Object.fromEntries(
|
|
88
|
+
Object.entries(modsRow).flatMap(([mod, lines]) => {
|
|
89
|
+
const list = asDumpTextList(lines);
|
|
90
|
+
return list ? [[mod, list] as const] : [];
|
|
91
|
+
}),
|
|
92
|
+
)
|
|
93
|
+
: undefined;
|
|
94
|
+
if (!name && !tooltip && !tooltipMods) return undefined;
|
|
95
|
+
return {
|
|
96
|
+
...(name ? { name } : {}),
|
|
97
|
+
...(tooltip ? { tooltip } : {}),
|
|
98
|
+
...(tooltipMods && Object.keys(tooltipMods).length ? { tooltipMods } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { DumpNbt, TaggedReference } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
2
|
+
import type { DumpDisplay } from '@terrafirmagreg-team/dump/lib/dump/contract/text';
|
|
3
|
+
import type {
|
|
4
|
+
BlockEntry,
|
|
5
|
+
EntityEntry,
|
|
6
|
+
FluidEntry,
|
|
7
|
+
ItemEntry,
|
|
8
|
+
SpriteEntry,
|
|
9
|
+
VariantEntry,
|
|
10
|
+
} from '@terrafirmagreg-team/dump/lib/dump/gen';
|
|
11
|
+
|
|
12
|
+
export type { SpriteEntry };
|
|
13
|
+
|
|
14
|
+
export type DumpEntryVariant = Omit<VariantEntry, 'display' | 'tag'> & {
|
|
15
|
+
tag: DumpNbt;
|
|
16
|
+
display?: DumpDisplay;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type DumpItemEntry = Omit<
|
|
20
|
+
ItemEntry,
|
|
21
|
+
'block' | 'display' | 'maxCount' | 'rarity' | 'variants'
|
|
22
|
+
> & {
|
|
23
|
+
maxCount?: number;
|
|
24
|
+
rarity?: string;
|
|
25
|
+
block?: string;
|
|
26
|
+
display?: DumpDisplay;
|
|
27
|
+
variants?: DumpEntryVariant[];
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type DumpBlockEntry = Omit<BlockEntry, 'display' | 'item'> & {
|
|
31
|
+
item?: TaggedReference;
|
|
32
|
+
display?: DumpDisplay;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type DumpFluidEntry = Omit<FluidEntry, 'display' | 'variants'> & {
|
|
36
|
+
display?: DumpDisplay;
|
|
37
|
+
variants?: DumpEntryVariant[];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type DumpEntityEntry = Omit<
|
|
41
|
+
EntityEntry,
|
|
42
|
+
'display' | 'model' | 'texture' | 'variants'
|
|
43
|
+
> & {
|
|
44
|
+
display?: DumpDisplay;
|
|
45
|
+
texture?: string;
|
|
46
|
+
model?: string;
|
|
47
|
+
variants?: DumpEntryVariant[];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type DumpRegistryKind = 'items' | 'blocks' | 'fluids' | 'entities';
|
|
51
|
+
|
|
52
|
+
export type DumpRegistryEntry =
|
|
53
|
+
| DumpItemEntry
|
|
54
|
+
| DumpBlockEntry
|
|
55
|
+
| DumpFluidEntry
|
|
56
|
+
| DumpEntityEntry;
|
|
57
|
+
|