Skip to content

Commit

Permalink
add finally a way to get entities metadata by key
Browse files Browse the repository at this point in the history
  • Loading branch information
zardoy committed Nov 21, 2024
1 parent 4dac577 commit c44ad90
Show file tree
Hide file tree
Showing 3 changed files with 4,378 additions and 8 deletions.
26 changes: 23 additions & 3 deletions prismarine-viewer/viewer/lib/entities.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ts-check
import EventEmitter from 'events'
import { UnionToIntersection } from 'type-fest'
import nbt from 'prismarine-nbt'
import * as TWEEN from '@tweenjs/tween.js'
import * as THREE from 'three'
Expand All @@ -11,6 +12,7 @@ import { NameTagObject } from 'skinview3d/libs/nametag'
import { flat, fromFormattedString } from '@xmcl/text-component'
import mojangson from 'mojangson'
import { snakeCase } from 'change-case'
import { EntityMetadataVersions } from '../../../src/mcDataTypes'
import * as Entity from './entity/EntityMesh'
import { WalkingGeneralSwing } from './entity/animations'
import externalTexturesJson from './entity/externalTextures.json'
Expand Down Expand Up @@ -352,7 +354,7 @@ export class Entities extends EventEmitter {
}
}

update (entity: import('prismarine-entity').Entity & { delete?; pos }, overrides) {
update (entity: import('prismarine-entity').Entity & { delete?; pos, name }, overrides) {
const isPlayerModel = entity.name === 'player'
if (entity.name === 'zombie' || entity.name === 'zombie_villager' || entity.name === 'husk') {
overrides.texture = `textures/1.16.4/entity/${entity.name === 'zombie_villager' ? 'zombie_villager/zombie_villager.png' : `zombie/${entity.name}.png`}`
Expand Down Expand Up @@ -453,6 +455,8 @@ export class Entities extends EventEmitter {
this.setRendering(this.rendering, group)
}

const meta = getGeneralEntitiesMetadata(entity)

//@ts-expect-error
// set visibility
const isInvisible = entity.metadata?.[0] & 0x20
Expand All @@ -463,8 +467,8 @@ export class Entities extends EventEmitter {
}
// ---
// not player
const displayText = entity.metadata?.[3] && this.parseEntityLabel(entity.metadata[2])
|| entity.metadata?.[23] && this.parseEntityLabel(entity.metadata[23]) // text displays
const displayTextRaw = meta.custom_name_visible || getSpecificEntityMetadata('text_display', entity)?.text
const displayText = displayTextRaw && this.parseEntityLabel(displayTextRaw)
if (entity.name !== 'player' && displayText) {
addNametag({ ...entity, username: displayText }, this.entitiesOptions, this.entities[entity.id].children.find(c => c.name === 'mesh'))
}
Expand Down Expand Up @@ -547,3 +551,19 @@ export class Entities extends EventEmitter {
}
}
}

function getGeneralEntitiesMetadata (entity: { name; metadata }): Partial<UnionToIntersection<EntityMetadataVersions[keyof EntityMetadataVersions]>> {
const entityData = loadedData.entitiesByName[entity.name]
return new Proxy({}, {
get (target, p, receiver) {
if (typeof p !== 'string') return
const index = entityData.metadataKeys?.indexOf(p)
return entity.metadata[index ?? -1]
},
})
}

function getSpecificEntityMetadata<T extends keyof EntityMetadataVersions> (name: T, entity): EntityMetadataVersions[T] | undefined {
if (entity.name !== name) return
return getGeneralEntitiesMetadata(entity) as any
}
38 changes: 38 additions & 0 deletions scripts/genMcDataTypes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import minecraftData from 'minecraft-data'
import fs from 'fs'
import supportedVersions from '../src/supportedVersions.mjs'

const data = minecraftData('1.20.1')

Expand All @@ -10,4 +11,41 @@ types += `\nexport type EntityNames = ${Object.keys(data.entitiesByName).map(blo
types += `\nexport type BiomesNames = ${Object.keys(data.biomesByName).map(blockName => `'${blockName}'`).join(' | ')};`
types += `\nexport type EnchantmentNames = ${Object.keys(data.enchantmentsByName).map(blockName => `'${blockName}'`).join(' | ')};`

type Version = string
const allVersionsEntitiesMetadata = {} as Record<string, Record<string, {
version: Version,
firstKey: number
}>>
for (const version of supportedVersions) {
const data = minecraftData(version)
for (const { name, metadataKeys } of data.entitiesArray) {
allVersionsEntitiesMetadata[name] ??= {}
if (!metadataKeys) {
// console.warn('Entity has no metadata', name, version)
}
for (const [i, key] of (metadataKeys ?? []).entries()) {
allVersionsEntitiesMetadata[name][key] ??= {
version: version,
firstKey: i,
}
}
}
}

types += '\n\nexport type EntityMetadataVersions = {\n'
for (const [name, versions] of Object.entries(allVersionsEntitiesMetadata)) {
types += `'${name}': {`
for (const [key, v] of Object.entries(versions)) {
types += `\n/** ${v.version}+ (${v.firstKey}) */\n`
types += `'${key}': string;`
}
types += '},'
}
types += '\n}'

const minify = false
if (minify) {
types = types.replaceAll(/[\t]/g, '')
}

fs.writeFileSync('./src/mcDataTypes.ts', types, 'utf8')
Loading

0 comments on commit c44ad90

Please sign in to comment.