Skip to content

Commit 05d061d

Browse files
committed
Fix 1.21.5 text component handling in loot table preview
1 parent df0c963 commit 05d061d

File tree

3 files changed

+40
-22
lines changed

3 files changed

+40
-22
lines changed

src/app/components/ItemTooltip.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { MobEffectInstance, NbtTag } from 'deepslate'
22
import { ItemStack, NbtCompound, NbtList, PotionContents } from 'deepslate'
33
import { Identifier } from 'deepslate/core'
4+
import { useVersion } from '../contexts/Version.jsx'
45
import type { ResolvedItem } from '../services/ResolvedItem.js'
56
import { intToDisplayHexRgb, makeDescriptionId, mergeTextComponentStyles } from '../Utils.js'
67
import { TextComponent } from './TextComponent.jsx'
@@ -11,8 +12,9 @@ interface Props {
1112
resolver: (item: ItemStack) => ResolvedItem,
1213
}
1314
export function ItemTooltip({ item, advanced, resolver }: Props) {
15+
const { version } = useVersion()
1416
return <>
15-
<TextComponent component={item.getStyledHoverName()} />
17+
<TextComponent component={item.getStyledHoverName(version)} />
1618
{!advanced && !item.has('custom_name') && item.is('filled_map') && item.has('map_id') && (
1719
<TextComponent component={{ translate: 'filled_map.id', with: [item.get('map_id', tag => tag.getAsNumber())], color: 'gray' }} />
1820
)}
@@ -25,7 +27,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) {
2527
<TextComponent component={{ translate: `${layer.isCompound() ? (layer.hasCompound('pattern') ? layer.getString('translation_key') : `block.minecraft.banner.${layer.getString('pattern').replace(/^minecraft:/, '')}`) : ''}.${layer.isCompound() ? layer.getString('color') : ''}`, color: 'gray' }} />
2628
)}
2729
{item.is('crossbow') && item.getChargedProjectile() && (
28-
<TextComponent component={{ translate: 'item.minecraft.crossbow.projectile', extra: [' ', resolver(item.getChargedProjectile()!).getDisplayName()] }}/>
30+
<TextComponent component={{ translate: 'item.minecraft.crossbow.projectile', extra: [' ', resolver(item.getChargedProjectile()!).getDisplayName(version)] }}/>
2931
)}
3032
{item.is('disc_fragment_5') && (
3133
<TextComponent component={{ translate: `${makeDescriptionId('item', item.id)}.desc`, color: 'gray' }} />
@@ -63,7 +65,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) {
6365
{item.is('decorated_pot') && item.has('pot_decorations') && <>
6466
<TextComponent component={''} />
6567
{item.get('pot_decorations', tag => tag.isList() ? tag.map(e =>
66-
<TextComponent component={mergeTextComponentStyles(resolver(new ItemStack(Identifier.parse(e.getAsString()), 1)).getHoverName(), { color: 'gray' })} />
68+
<TextComponent component={mergeTextComponentStyles(resolver(new ItemStack(Identifier.parse(e.getAsString()), 1)).getHoverName(version), { color: 'gray' })} />
6769
) : undefined)}
6870
</>}
6971
{item.id.path.endsWith('_shulker_box') && <>
@@ -72,7 +74,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) {
7274
)}
7375
{(item.get('container', tag => tag.isList() ? tag.getItems() : []) ?? []).slice(0, 5).map(e => {
7476
const subItem = resolver(ItemStack.fromNbt(e.isCompound() ? e.getCompound('item') : new NbtCompound()))
75-
return <TextComponent component={{ translate: 'container.shulkerBox.itemCount', with: [subItem.getHoverName(), subItem.count] }} />
77+
return <TextComponent component={{ translate: 'container.shulkerBox.itemCount', with: [subItem.getHoverName(version), subItem.count] }} />
7678
})}
7779
{(item.get('container', tag => tag.isList() ? tag.length : 0) ?? 0) > 5 && (
7880
<TextComponent component={{ translate: 'container.shulkerBox.more', with: [(item.get('container', tag => tag.isList() ? tag.length : 0) ?? 0) - 5], italic: true }} />
@@ -110,7 +112,7 @@ export function ItemTooltip({ item, advanced, resolver }: Props) {
110112
? <TextComponent component={{ translate: 'item.color', with: [intToDisplayHexRgb(item.get('dyed_color', tag => tag.isCompound() ? tag.getNumber('rgb') : tag.getAsNumber()))], color: 'gray' }} />
111113
: <TextComponent component={{ translate: 'item.dyed', color: 'gray' }} />
112114
)}
113-
{item.getLore().map((component) =>
115+
{item.getLore(version).map((component) =>
114116
<TextComponent component={component} base={{ color: 'dark_purple', italic: true }} />
115117
)}
116118
{item.showInTooltip('attribute_modifiers') && (

src/app/components/previews/LootTable.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Identifier, ItemStack, LegacyRandom } from 'deepslate/core'
55
import { NbtCompound, NbtInt, NbtList, NbtString, NbtTag } from 'deepslate/nbt'
66
import { ResolvedItem } from '../../services/ResolvedItem.js'
77
import type { VersionId } from '../../services/Versions.js'
8+
import { checkVersion } from '../../services/Versions.js'
89
import { clamp, getWeightedRandom, isObject, jsonToNbt } from '../../Utils.js'
910

1011
export interface SlottedItem {
@@ -470,16 +471,22 @@ const LootFunctions: Record<string, (params: any) => LootFunction> = {
470471
.set('loot_table', new NbtString(Identifier.parse(typeof name === 'string' ? name : '').toString()))
471472
.set('seed', new NbtLong(typeof seed === 'number' ? BigInt(seed) : BigInt(0))))
472473
},
473-
set_lore: ({ lore }) => (item) => {
474+
set_lore: ({ lore }) => (item, ctx) => {
474475
if (!Array.isArray(lore)) return
475-
const lines: string[] = lore.flatMap((line: any) => line !== undefined ? [JSON.stringify(line)] : [])
476+
const lines: NbtTag[] = lore.flatMap((line: any) => line !== undefined ? [
477+
!checkVersion(ctx.version, '1.21.5')
478+
? new NbtString(JSON.stringify(line))
479+
: jsonToNbt(line),
480+
] : [])
476481
// TODO: account for mode
477-
item.set('lore', new NbtList(lines.map(l => new NbtString(l))))
482+
item.set('lore', new NbtList(lines))
478483
},
479-
set_name: ({ name, target }) => (item) => {
484+
set_name: ({ name, target }) => (item, ctx) => {
480485
if (name !== undefined) {
481-
const newName = JSON.stringify(name)
482-
item.set(target ?? 'custom_name', new NbtString(newName))
486+
const newName = !checkVersion(ctx.version, '1.21.5')
487+
? new NbtString(JSON.stringify(name))
488+
: jsonToNbt(name)
489+
item.set(target ?? 'custom_name', newName)
483490
}
484491
},
485492
set_ominous_bottle_amplifier: ({ amplifier }) => (item, ctx) => {

src/app/services/ResolvedItem.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { NbtTag } from 'deepslate'
22
import { Identifier, ItemStack } from 'deepslate'
33
import { safeJsonParse } from '../Utils.js'
4+
import type { VersionId } from './Versions.js'
5+
import { checkVersion } from './Versions.js'
46

57
export class ResolvedItem extends ItemStack {
68

@@ -86,10 +88,10 @@ export class ResolvedItem extends ItemStack {
8688
return this.has('enchantment_glint_override') || this.isEnchanted()
8789
}
8890

89-
public getLore() {
91+
public getLore(version: VersionId) {
9092
return this.get('lore', tag => {
9193
return tag.isList() ? tag.map(e => {
92-
return safeJsonParse(e.getAsString()) ?? { text: '(invalid lore line)' }
94+
return ResolvedItem.getTextComponent(e, version)
9395
}) : []
9496
}) ?? []
9597
}
@@ -127,20 +129,20 @@ export class ResolvedItem extends ItemStack {
127129
}
128130
}
129131

130-
public getHoverName() {
131-
const customName = this.get('custom_name', tag => tag.isString() ? tag.getAsString() : undefined)
132+
public getHoverName(version: VersionId) {
133+
const customName = this.get('custom_name', tag => ResolvedItem.getTextComponent(tag, version))
132134
if (customName) {
133-
return safeJsonParse(customName) ?? '(invalid custom name)'
135+
return customName
134136
}
135137

136138
const bookTitle = this.get('written_book_content', tag => tag.isCompound() ? (tag.hasCompound('title') ? tag.getCompound('title').getString('raw') : tag.getString('title')) : undefined)
137139
if (bookTitle && bookTitle.length > 0) {
138140
return { text: bookTitle }
139141
}
140142

141-
const itemName = this.get('item_name', tag => tag.isString() ? tag.getAsString() : undefined)
143+
const itemName = this.get('item_name', tag => ResolvedItem.getTextComponent(tag, version))
142144
if (itemName) {
143-
return safeJsonParse(itemName) ?? { text: '(invalid item name)' }
145+
return itemName
144146
}
145147

146148
const guess = this.id.path
@@ -151,13 +153,13 @@ export class ResolvedItem extends ItemStack {
151153
return { text: guess }
152154
}
153155

154-
public getStyledHoverName() {
155-
return { text: '', extra: [this.getHoverName()], color: this.getRarityColor(), italic: this.has('custom_name') }
156+
public getStyledHoverName(version: VersionId) {
157+
return { text: '', extra: [this.getHoverName(version)], color: this.getRarityColor(), italic: this.has('custom_name') }
156158
}
157159

158-
public getDisplayName() {
160+
public getDisplayName(version: VersionId) {
159161
// Does not use translation key "chat.square_brackets" due to limitations of TextComponent
160-
return { text: '[', extra: [this.getStyledHoverName(), ']'], color: this.getRarityColor() }
162+
return { text: '[', extra: [this.getStyledHoverName(version), ']'], color: this.getRarityColor() }
161163
}
162164

163165
public getChargedProjectile() {
@@ -168,4 +170,11 @@ export class ResolvedItem extends ItemStack {
168170
return ItemStack.fromNbt(tag.getCompound(0))
169171
})
170172
}
173+
174+
private static getTextComponent(tag: NbtTag, version: VersionId) {
175+
if (!checkVersion(version, '1.21.5')) {
176+
return safeJsonParse(tag.getAsString()) ?? { text: '(invalid text component)' }
177+
}
178+
return tag.toSimplifiedJson()
179+
}
171180
}

0 commit comments

Comments
 (0)