Skip to content

Commit fff1b16

Browse files
committed
Fix #596 support item tag and loot table references in loot preview
1 parent 95f7ca7 commit fff1b16

File tree

3 files changed

+46
-32
lines changed

3 files changed

+46
-32
lines changed

src/app/components/previews/LootTable.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ interface LootOptions {
2727
daytime: number,
2828
weather: string,
2929
stackMixer: StackMixer,
30+
getItemTag(id: string): string[],
31+
getLootTable(id: string): any,
32+
getPredicate(id: string): any,
3033
getBaseComponents(id: string): Map<string, NbtTag>,
3134
}
3235

@@ -35,9 +38,6 @@ interface LootContext extends LootOptions {
3538
luck: number
3639
weather: string,
3740
dayTime: number,
38-
getItemTag(id: string): string[],
39-
getLootTable(id: string): any,
40-
getPredicate(id: string): any,
4141
}
4242

4343
export function generateLootTable(lootTable: any, options: LootOptions) {
@@ -133,10 +133,6 @@ function createLootContext(options: LootOptions): LootContext {
133133
luck: options.luck,
134134
weather: options.weather,
135135
dayTime: options.daytime,
136-
// TODO
137-
getItemTag: () => [],
138-
getLootTable: () => ({ pools: [] }),
139-
getPredicate: () => [],
140136
}
141137
}
142138

@@ -207,7 +203,7 @@ function expandEntry(entry: any, ctx: LootContext, consumer: (entry: any) => voi
207203
return true
208204
case 'tag':
209205
if (entry.expand) {
210-
ctx.getItemTag(entry.tag ?? '').forEach(tagEntry => {
206+
ctx.getItemTag(entry.name ?? '').forEach(tagEntry => {
211207
consumer({ type: 'item', name: tagEntry })
212208
})
213209
} else {
@@ -243,7 +239,10 @@ function createItem(entry: any, consumer: ItemConsumer, ctx: LootContext) {
243239
})
244240
break
245241
case 'loot_table':
246-
generateTable(ctx.getLootTable(entry.name), entryConsumer, ctx)
242+
const lootTable = typeof entry.value === 'string' ? ctx.getLootTable(entry.value) : entry.value
243+
if (lootTable !== undefined) {
244+
generateTable(lootTable, entryConsumer, ctx)
245+
}
247246
break
248247
case 'dynamic':
249248
// not relevant for this simulation
@@ -365,7 +364,7 @@ const LootFunctions: Record<string, (params: any) => LootFunction> = {
365364
},
366365
set_count: ({ count, add }) => (item, ctx) => {
367366
const oldCount = add ? (item.count) : 0
368-
item.count = clamp(oldCount + computeInt(count, ctx), 0, 64)
367+
item.count = oldCount + computeInt(count, ctx)
369368
},
370369
set_custom_data: ({ tag }) => (item) => {
371370
try {
@@ -638,7 +637,6 @@ function testItemPredicate(predicate: any, item: ResolvedItem, ctx: LootContext)
638637
}
639638
if (predicate.count !== undefined) {
640639
const { min, max } = prepareIntRange(predicate.count, ctx)
641-
console.log(min, max, item.count)
642640
if (min > item.count || item.count > max) {
643641
return false
644642
}

src/app/components/previews/LootTable1204.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ interface LootOptions {
2525
daytime: number,
2626
weather: string,
2727
stackMixer: StackMixer,
28+
getItemTag(id: string): string[],
29+
getLootTable(id: string): any,
30+
getPredicate(id: string): any,
2831
}
2932

3033
interface LootContext extends LootOptions {
3134
random: Random,
3235
luck: number
3336
weather: string,
3437
dayTime: number,
35-
getItemTag(id: string): string[],
36-
getLootTable(id: string): any,
37-
getPredicate(id: string): any,
3838
}
3939

4040
export function generateLootTable(lootTable: any, options: LootOptions) {
@@ -130,9 +130,6 @@ function createLootContext(options: LootOptions): LootContext {
130130
luck: options.luck,
131131
weather: options.weather,
132132
dayTime: options.daytime,
133-
getItemTag: () => [],
134-
getLootTable: () => ({ pools: [] }),
135-
getPredicate: () => [],
136133
}
137134
}
138135

@@ -203,7 +200,7 @@ function expandEntry(entry: any, ctx: LootContext, consumer: (entry: any) => voi
203200
return true
204201
case 'tag':
205202
if (entry.expand) {
206-
ctx.getItemTag(entry.tag ?? '').forEach(tagEntry => {
203+
ctx.getItemTag(entry.name ?? '').forEach(tagEntry => {
207204
consumer({ type: 'item', name: tagEntry })
208205
})
209206
} else {
@@ -241,7 +238,10 @@ function createItem(entry: any, consumer: ItemConsumer, ctx: LootContext) {
241238
})
242239
break
243240
case 'loot_table':
244-
generateTable(ctx.getLootTable(entry.name), entryConsumer, ctx)
241+
const lootTable = ctx.getLootTable(entry.name)
242+
if (lootTable !== undefined) {
243+
generateTable(lootTable, entryConsumer, ctx)
244+
}
245245
break
246246
case 'dynamic':
247247
// not relevant for this simulation
@@ -659,7 +659,6 @@ const AlwaysHasGlint = new Set([
659659
])
660660

661661
export function itemHasGlint(item: ItemStack) {
662-
console.log(item)
663662
if (AlwaysHasGlint.has(item.id.toString())) {
664663
return true
665664
}

src/app/components/previews/LootTablePreview.tsx

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { DataModel } from '@mcschema/core'
22
import { useMemo, useRef, useState } from 'preact/hooks'
33
import { useLocale, useVersion } from '../../contexts/index.js'
44
import { useAsync } from '../../hooks/useAsync.js'
5-
import { checkVersion, fetchItemComponents } from '../../services/index.js'
5+
import { checkVersion, fetchAllPresets, fetchItemComponents } from '../../services/index.js'
66
import { clamp, jsonToNbt, randomSeed } from '../../Utils.js'
77
import { Btn, BtnMenu, NumberInput } from '../index.js'
88
import { ItemDisplay } from '../ItemDisplay.jsx'
@@ -14,7 +14,7 @@ import { generateLootTable as generateLootTable1204 } from './LootTable1204.js'
1414
export const LootTablePreview = ({ data }: PreviewProps) => {
1515
const { locale } = useLocale()
1616
const { version } = useVersion()
17-
const use1204 = checkVersion(version, undefined, '1.20.4')
17+
const use1204 = !checkVersion(version, '1.20.5')
1818

1919
const [seed, setSeed] = useState(randomSeed())
2020
const [luck, setLuck] = useState(0)
@@ -24,22 +24,39 @@ export const LootTablePreview = ({ data }: PreviewProps) => {
2424
const [advancedTooltips, setAdvancedTooltips] = useState(true)
2525
const overlay = useRef<HTMLDivElement>(null)
2626

27-
const { value: itemComponents } = useAsync(() => {
28-
return use1204 ? Promise.resolve(undefined) : fetchItemComponents(version)
29-
}, [use1204, version])
27+
const { value: dependencies, loading } = useAsync(() => {
28+
return Promise.all([
29+
fetchAllPresets(version, 'tag/item'),
30+
fetchAllPresets(version, 'loot_table'),
31+
use1204 ? Promise.resolve(undefined) : fetchItemComponents(version),
32+
])
33+
}, [version])
3034

3135
const table = DataModel.unwrapLists(data)
3236
const state = JSON.stringify(table)
3337
const items = useMemo(() => {
38+
if (dependencies === undefined || loading) {
39+
return []
40+
}
41+
const [itemTags, lootTables, itemComponents] = dependencies
3442
if (use1204) {
35-
return generateLootTable1204(table, { version, seed, luck, daytime, weather, stackMixer: mixItems ? 'container' : 'default' })
36-
} else {
37-
if (itemComponents === undefined) {
38-
return []
39-
}
40-
return generateLootTable(table, { version, seed, luck, daytime, weather, stackMixer: mixItems ? 'container' : 'default', getBaseComponents: (id) => new Map([...(itemComponents.get(id) ?? new Map()).entries()].map(([k, v]) => [k, jsonToNbt(v)])) })
43+
return generateLootTable1204(table, {
44+
version, seed, luck, daytime, weather,
45+
stackMixer: mixItems ? 'container' : 'default',
46+
getItemTag: (id) => (itemTags.get(id.replace(/^minecraft:/, '')) as any)?.values ?? [],
47+
getLootTable: (id) => lootTables.get(id.replace(/^minecraft:/, '')),
48+
getPredicate: () => undefined,
49+
})
4150
}
42-
}, [version, seed, luck, daytime, weather, mixItems, state, itemComponents])
51+
return generateLootTable(table, {
52+
version, seed, luck, daytime, weather,
53+
stackMixer: mixItems ? 'container' : 'default',
54+
getItemTag: (id) => (itemTags.get(id.replace(/^minecraft:/, '')) as any)?.values ?? [],
55+
getLootTable: (id) => lootTables.get(id.replace(/^minecraft:/, '')),
56+
getPredicate: () => undefined,
57+
getBaseComponents: (id) => new Map([...(itemComponents?.get(id) ?? new Map()).entries()].map(([k, v]) => [k, jsonToNbt(v)])),
58+
})
59+
}, [version, seed, luck, daytime, weather, mixItems, state, dependencies, loading])
4360

4461
return <>
4562
<div ref={overlay} class="preview-overlay">

0 commit comments

Comments
 (0)