diff --git a/src/app/components/ItemTooltip.tsx b/src/app/components/ItemTooltip.tsx index 2342ca2f..f327073e 100644 --- a/src/app/components/ItemTooltip.tsx +++ b/src/app/components/ItemTooltip.tsx @@ -1,6 +1,7 @@ import type { MobEffectInstance, NbtTag } from 'deepslate' import { ItemStack, NbtCompound, NbtList, PotionContents } from 'deepslate' import { Identifier } from 'deepslate/core' +import { useVersion } from '../contexts/Version.jsx' import type { ResolvedItem } from '../services/ResolvedItem.js' import { intToDisplayHexRgb, makeDescriptionId, mergeTextComponentStyles } from '../Utils.js' import { TextComponent } from './TextComponent.jsx' @@ -11,8 +12,9 @@ interface Props { resolver: (item: ItemStack) => ResolvedItem, } export function ItemTooltip({ item, advanced, resolver }: Props) { + const { version } = useVersion() return <> - + {!advanced && !item.has('custom_name') && item.is('filled_map') && item.has('map_id') && ( tag.getAsNumber())], color: 'gray' }} /> )} @@ -25,7 +27,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) { )} {item.is('crossbow') && item.getChargedProjectile() && ( - + )} {item.is('disc_fragment_5') && ( @@ -63,7 +65,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) { {item.is('decorated_pot') && item.has('pot_decorations') && <> {item.get('pot_decorations', tag => tag.isList() ? tag.map(e => - + ) : undefined)} } {item.id.path.endsWith('_shulker_box') && <> @@ -72,7 +74,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) { )} {(item.get('container', tag => tag.isList() ? tag.getItems() : []) ?? []).slice(0, 5).map(e => { const subItem = resolver(ItemStack.fromNbt(e.isCompound() ? e.getCompound('item') : new NbtCompound())) - return + return })} {(item.get('container', tag => tag.isList() ? tag.length : 0) ?? 0) > 5 && ( tag.isList() ? tag.length : 0) ?? 0) - 5], italic: true }} /> @@ -110,7 +112,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) { ? tag.isCompound() ? tag.getNumber('rgb') : tag.getAsNumber()))], color: 'gray' }} /> : )} - {item.getLore().map((component) => + {item.getLore(version).map((component) => )} {item.showInTooltip('attribute_modifiers') && ( diff --git a/src/app/components/previews/LootTable.ts b/src/app/components/previews/LootTable.ts index 18fa9811..775c8bc5 100644 --- a/src/app/components/previews/LootTable.ts +++ b/src/app/components/previews/LootTable.ts @@ -5,6 +5,7 @@ import { Identifier, ItemStack, LegacyRandom } from 'deepslate/core' import { NbtCompound, NbtInt, NbtList, NbtString, NbtTag } from 'deepslate/nbt' import { ResolvedItem } from '../../services/ResolvedItem.js' import type { VersionId } from '../../services/Versions.js' +import { checkVersion } from '../../services/Versions.js' import { clamp, getWeightedRandom, isObject, jsonToNbt } from '../../Utils.js' export interface SlottedItem { @@ -470,16 +471,22 @@ const LootFunctions: Record LootFunction> = { .set('loot_table', new NbtString(Identifier.parse(typeof name === 'string' ? name : '').toString())) .set('seed', new NbtLong(typeof seed === 'number' ? BigInt(seed) : BigInt(0)))) }, - set_lore: ({ lore }) => (item) => { + set_lore: ({ lore }) => (item, ctx) => { if (!Array.isArray(lore)) return - const lines: string[] = lore.flatMap((line: any) => line !== undefined ? [JSON.stringify(line)] : []) + const lines: NbtTag[] = lore.flatMap((line: any) => line !== undefined ? [ + !checkVersion(ctx.version, '1.21.5') + ? new NbtString(JSON.stringify(line)) + : jsonToNbt(line), + ] : []) // TODO: account for mode - item.set('lore', new NbtList(lines.map(l => new NbtString(l)))) + item.set('lore', new NbtList(lines)) }, - set_name: ({ name, target }) => (item) => { + set_name: ({ name, target }) => (item, ctx) => { if (name !== undefined) { - const newName = JSON.stringify(name) - item.set(target ?? 'custom_name', new NbtString(newName)) + const newName = !checkVersion(ctx.version, '1.21.5') + ? new NbtString(JSON.stringify(name)) + : jsonToNbt(name) + item.set(target ?? 'custom_name', newName) } }, set_ominous_bottle_amplifier: ({ amplifier }) => (item, ctx) => { diff --git a/src/app/services/ResolvedItem.ts b/src/app/services/ResolvedItem.ts index 9299477d..300c16f1 100644 --- a/src/app/services/ResolvedItem.ts +++ b/src/app/services/ResolvedItem.ts @@ -1,6 +1,8 @@ import type { NbtTag } from 'deepslate' import { Identifier, ItemStack } from 'deepslate' import { safeJsonParse } from '../Utils.js' +import type { VersionId } from './Versions.js' +import { checkVersion } from './Versions.js' export class ResolvedItem extends ItemStack { @@ -86,10 +88,10 @@ export class ResolvedItem extends ItemStack { return this.has('enchantment_glint_override') || this.isEnchanted() } - public getLore() { + public getLore(version: VersionId) { return this.get('lore', tag => { return tag.isList() ? tag.map(e => { - return safeJsonParse(e.getAsString()) ?? { text: '(invalid lore line)' } + return ResolvedItem.getTextComponent(e, version) }) : [] }) ?? [] } @@ -127,10 +129,10 @@ export class ResolvedItem extends ItemStack { } } - public getHoverName() { - const customName = this.get('custom_name', tag => tag.isString() ? tag.getAsString() : undefined) + public getHoverName(version: VersionId) { + const customName = this.get('custom_name', tag => ResolvedItem.getTextComponent(tag, version)) if (customName) { - return safeJsonParse(customName) ?? '(invalid custom name)' + return customName } const bookTitle = this.get('written_book_content', tag => tag.isCompound() ? (tag.hasCompound('title') ? tag.getCompound('title').getString('raw') : tag.getString('title')) : undefined) @@ -138,9 +140,9 @@ export class ResolvedItem extends ItemStack { return { text: bookTitle } } - const itemName = this.get('item_name', tag => tag.isString() ? tag.getAsString() : undefined) + const itemName = this.get('item_name', tag => ResolvedItem.getTextComponent(tag, version)) if (itemName) { - return safeJsonParse(itemName) ?? { text: '(invalid item name)' } + return itemName } const guess = this.id.path @@ -151,13 +153,13 @@ export class ResolvedItem extends ItemStack { return { text: guess } } - public getStyledHoverName() { - return { text: '', extra: [this.getHoverName()], color: this.getRarityColor(), italic: this.has('custom_name') } + public getStyledHoverName(version: VersionId) { + return { text: '', extra: [this.getHoverName(version)], color: this.getRarityColor(), italic: this.has('custom_name') } } - public getDisplayName() { + public getDisplayName(version: VersionId) { // Does not use translation key "chat.square_brackets" due to limitations of TextComponent - return { text: '[', extra: [this.getStyledHoverName(), ']'], color: this.getRarityColor() } + return { text: '[', extra: [this.getStyledHoverName(version), ']'], color: this.getRarityColor() } } public getChargedProjectile() { @@ -168,4 +170,11 @@ export class ResolvedItem extends ItemStack { return ItemStack.fromNbt(tag.getCompound(0)) }) } + + private static getTextComponent(tag: NbtTag, version: VersionId) { + if (!checkVersion(version, '1.21.5')) { + return safeJsonParse(tag.getAsString()) ?? { text: '(invalid text component)' } + } + return tag.toSimplifiedJson() + } }