Add loot table preview (#293)

* Initial loot table preview + item display counts

* Add loot functions without NBT

* Add loot conditions

* Render item tooltips with name and lore components

* Remove debug text component

* Disable advanced tooltips in the tree

* Minor style fixes

* Add item slot overlay and tweak tooltip offset

* Fix some items not rendering

* Translate item names and text components

* Translate params + more functions and tooltips

* Add durability bar

* Configurable stack mixing

* Correct tooltip background and border

* Add enchanting

* Enchantment glint

* Configurable luck, daytime and weather

* Improve tooltip spacing

* More tooltip spacing improvements

* Remove debug logging
This commit is contained in:
Misode
2022-10-13 02:05:33 +02:00
committed by GitHub
parent 86687ea6b9
commit ac259bb83e
24 changed files with 1630 additions and 56 deletions

View File

@@ -1,7 +1,7 @@
import type { BlockModelProvider, TextureAtlasProvider, UV } from 'deepslate/render'
import { BlockModel, Identifier, ItemRenderer, TextureAtlas, upperPowerOfTwo } from 'deepslate/render'
import { message } from '../Utils.js'
import { fetchResources } from './DataFetcher.js'
import { fetchLanguage, fetchResources } from './DataFetcher.js'
import type { VersionId } from './Schemas.js'
const Resources: Record<string, ResourceManager | Promise<ResourceManager>> = {}
@@ -99,3 +99,83 @@ export class ResourceManager implements BlockModelProvider, TextureAtlasProvider
this.textureAtlas = new TextureAtlas(imageData, idMap)
}
}
const Languages: Record<string, Record<string, string> | Promise<Record<string, string>>> = {}
export async function getLanguage(version: VersionId) {
if (!Languages[version]) {
Languages[version] = (async () => {
try {
Languages[version] = await fetchLanguage(version)
return Languages[version]
} catch (e) {
console.error('Error: ', e)
throw new Error(`Cannot get language for version ${version}: ${message(e)}`)
}
})()
return Languages[version]
}
return Languages[version]
}
export async function getTranslation(version: VersionId, key: string, params?: string[]) {
const lang = await getLanguage(version)
const str = lang[key]
if (!str) return null
return replaceTranslation(str, params)
}
export function replaceTranslation(src: string, params?: string[]) {
let out = ''
let i = 0
let p = 0
while (i < src.length) {
const c0 = src[i++]
if (c0 === '%') { // percent character
if (i >= src.length) { // INVALID: %<end>
out += c0
break
}
let c1 = src[i++]
if (c1 === '%') { // escape
out += '%'
} else if (c1 === 's' || c1 === 'd') { // short form %s
out += params?.[p++] ?? ''
} else if (c1 >= '0' && c1 <= '9') {
if (i >= src.length) { // INVALID: %2<end>
out += c0 + c1
break
}
let num = ''
do {
num += c1
c1 = src[i++]
} while (i < src.length && c1 >= '0' && c1 <= '9')
if (c1 === '$') {
if (i >= src.length) { // INVALID: %2$<end>
out += c0 + num + c1
break
}
const c2 = src[i++]
if (c2 === 's' || c2 === 'd') { // long form %2$s
const pos = parseInt(num) - 1
if (!params || isNaN(pos) || pos < 0 || pos >= params.length) {
out += ''
} else {
out += params[pos]
}
} else { // INVALID: %2$...
out += c0 + num + c1
}
} else { // INVALID: %2...
out += c0 + num
}
} else { // INVALID: %...
out += c0
}
} else { // normal character
out += c0
}
}
return out
}