import { Identifier } from 'deepslate' import { useMemo, useRef, useState } from 'preact/hooks' import { useLocale, useVersion } from '../../contexts/index.js' import { useAsync } from '../../hooks/useAsync.js' import { checkVersion, fetchAllPresets, fetchItemComponents } from '../../services/index.js' import { clamp, jsonToNbt, randomSeed, safeJsonParse } from '../../Utils.js' import { Btn, BtnMenu, NumberInput } from '../index.js' import { ItemDisplay } from '../ItemDisplay.jsx' import { ItemDisplay1204 } from '../ItemDisplay1204.jsx' import type { PreviewProps } from './index.js' import { generateLootTable } from './LootTable.js' import { generateLootTable as generateLootTable1204 } from './LootTable1204.js' export const LootTablePreview = ({ docAndNode }: PreviewProps) => { const { locale } = useLocale() const { version } = useVersion() const use1204 = !checkVersion(version, '1.20.5') const [seed, setSeed] = useState(randomSeed()) const [luck, setLuck] = useState(0) const [daytime, setDaytime] = useState(0) const [weather, setWeather] = useState('clear') const [mixItems, setMixItems] = useState(true) const [advancedTooltips, setAdvancedTooltips] = useState(true) const overlay = useRef(null) const { value: dependencies, loading } = useAsync(() => { return Promise.all([ fetchAllPresets(version, 'tag/item'), fetchAllPresets(version, 'loot_table'), use1204 ? Promise.resolve(undefined) : fetchItemComponents(version), checkVersion(version, '1.21') ? fetchAllPresets(version, 'enchantment') : Promise.resolve(undefined), checkVersion(version, '1.21') ? fetchAllPresets(version, 'tag/enchantment') : Promise.resolve(undefined), ]) }, [version]) const text = docAndNode.doc.getText() const items = useMemo(() => { if (dependencies === undefined || loading) { return [] } const [itemTags, lootTables, itemComponents, enchantments, enchantmentTags] = dependencies const table = safeJsonParse(text) ?? {} if (use1204) { return generateLootTable1204(table, { version, seed, luck, daytime, weather, stackMixer: mixItems ? 'container' : 'default', getItemTag: (id) => (itemTags.get(id.replace(/^minecraft:/, '')) as any)?.values ?? [], getLootTable: (id) => lootTables.get(id.replace(/^minecraft:/, '')), getPredicate: () => undefined, }) } return generateLootTable(table, { version, seed, luck, daytime, weather, stackMixer: mixItems ? 'container' : 'default', getItemTag: (id) => (itemTags.get(id.replace(/^minecraft:/, '')) as any)?.values ?? [], getLootTable: (id) => lootTables.get(id.replace(/^minecraft:/, '')), getPredicate: () => undefined, getEnchantments: () => enchantments ?? new Map(), getEnchantmentTag: (id) => (enchantmentTags?.get(id.replace(/^minecraft:/, '')) as any)?.values ?? [], getBaseComponents: (id) => new Map([...(itemComponents?.get(Identifier.parse(id).toString()) ?? new Map()).entries()].map(([k, v]) => [k, jsonToNbt(v)])), }) }, [version, seed, luck, daytime, weather, mixItems, text, dependencies, loading]) return <>
Container background {items.map(({ slot, item }) =>
{use1204 ? : }
)}
e.stopPropagation()}> {locale('preview.luck')}
e.stopPropagation()}> {locale('preview.daytime')}
e.stopPropagation()}> {locale('preview.weather')}
{setMixItems(!mixItems); e.stopPropagation()}} /> {setAdvancedTooltips(!advancedTooltips); e.stopPropagation()}} />
setSeed(randomSeed())} />
} const GUI_WIDTH = 176 const GUI_HEIGHT = 81 const SLOT_SIZE = 18 function slotStyle(slot: number) { slot = clamp(slot, 0, 26) const x = (slot % 9) * SLOT_SIZE + 7 const y = (Math.floor(slot / 9)) * SLOT_SIZE + 20 return { left: `${x*100/GUI_WIDTH}%`, top: `${y*100/GUI_HEIGHT}%`, width: `${SLOT_SIZE*100/GUI_WIDTH}%`, height: `${SLOT_SIZE*100/GUI_HEIGHT}%`, } }