minecraft-renderer 0.1.79 → 0.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -25
- package/dist/mesher.js +36 -36
- package/dist/mesher.js.map +4 -4
- package/dist/mesherWasm.js +217 -217
- package/dist/minecraft-renderer.js +27 -27
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +133 -133
- package/package.json +5 -2
- package/src/bundler/bundlePrepare.ts +3 -8
- package/src/graphicsBackend/appViewer.ts +10 -7
- package/src/graphicsBackend/config.ts +1 -5
- package/src/graphicsBackend/playerState.ts +35 -34
- package/src/graphicsBackend/preloadWorkers.ts +43 -41
- package/src/graphicsBackend/rendererDefaultOptions.ts +68 -70
- package/src/graphicsBackend/rendererOptionsSync.ts +24 -50
- package/src/graphicsBackend/types.ts +2 -2
- package/src/index.ts +6 -27
- package/src/lib/DebugGui.ts +34 -31
- package/src/lib/animationController.ts +9 -9
- package/src/lib/bakeLegacyLight.ts +1 -6
- package/src/lib/bindAbortableListener.test.ts +32 -12
- package/src/lib/bindAbortableListener.ts +14 -6
- package/src/lib/blockEntityLightRegistry.ts +11 -20
- package/src/lib/blockEntityLighting.test.ts +1 -6
- package/src/lib/blockEntityLighting.ts +5 -5
- package/src/lib/buildSharedConfig.mjs +4 -4
- package/src/lib/buildWorkerMcDataIndexes.test.ts +4 -4
- package/src/lib/buildWorkerMcDataIndexes.ts +11 -19
- package/src/lib/cameraBobbing.ts +1 -1
- package/src/lib/canvas2DOverlay.example.ts +13 -33
- package/src/lib/canvas2DOverlay.quickstart.ts +24 -54
- package/src/lib/canvas2DOverlay.ts +28 -47
- package/src/lib/cleanupDecorator.ts +2 -2
- package/src/lib/createPlayerObject.test.ts +2 -7
- package/src/lib/createPlayerObject.ts +18 -25
- package/src/lib/frameTimingCollector.ts +2 -5
- package/src/lib/guiRenderer.ts +57 -42
- package/src/lib/items.ts +15 -9
- package/src/lib/mesherlogReader.ts +5 -6
- package/src/lib/simpleUtils.ts +5 -5
- package/src/lib/skyLight.ts +3 -3
- package/src/lib/smoothSwitcher.ts +11 -18
- package/src/lib/ui/newStats.ts +10 -12
- package/src/lib/utils/proxy.ts +7 -1
- package/src/lib/utils/skins.ts +4 -4
- package/src/lib/utils.ts +1 -1
- package/src/lib/workerMessageSanitize.ts +5 -12
- package/src/lib/workerProxy.ts +52 -42
- package/src/lib/workerSyncOps.test.ts +58 -41
- package/src/lib/worldrendererCommon.reconfigure.test.ts +24 -21
- package/src/lib/worldrendererCommon.removeColumn.test.ts +11 -13
- package/src/lib/worldrendererCommon.ts +338 -211
- package/src/mesher-legacy/mesher.ts +9 -4
- package/src/mesher-legacy/test/a.ts +1 -1
- package/src/mesher-legacy/test/mesherTester.ts +2 -2
- package/src/mesher-legacy/test/playground.ts +1 -1
- package/src/mesher-legacy/test/run/test-js.ts +1 -1
- package/src/mesher-legacy/test/snapshotUtils.ts +3 -8
- package/src/mesher-legacy/test/test-perf.ts +1 -1
- package/src/mesher-legacy/test/tests.test.ts +2 -2
- package/src/mesher-shared/blockEntityMetadata.test.ts +7 -5
- package/src/mesher-shared/blockEntityMetadata.ts +28 -19
- package/src/mesher-shared/blockPropertiesForMeshing.ts +2 -2
- package/src/mesher-shared/computeHeightmap.ts +2 -4
- package/src/mesher-shared/exportedGeometryTypes.ts +3 -3
- package/src/mesher-shared/faceOcclusion.ts +324 -0
- package/src/mesher-shared/models.ts +80 -131
- package/src/mesher-shared/modelsGeometryCommon.ts +30 -15
- package/src/mesher-shared/shared.ts +46 -46
- package/src/mesher-shared/standaloneRenderer.ts +40 -44
- package/src/mesher-shared/tests/faceOcclusion.test.ts +179 -0
- package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +12 -8
- package/src/mesher-shared/vertexShading.ts +2 -11
- package/src/mesher-shared/world.ts +19 -19
- package/src/mesher-shared/worldLighting.test.ts +2 -2
- package/src/performanceMonitor/PerformanceMonitor.ts +4 -13
- package/src/performanceMonitor/formatPerformanceFactorsDebug.ts +2 -2
- package/src/performanceMonitor/index.ts +1 -5
- package/src/performanceMonitor/types.ts +1 -1
- package/src/playerState/playerState.ts +55 -50
- package/src/playerState/types.ts +2 -8
- package/src/playground/allEntitiesDebug.ts +19 -16
- package/src/playground/baseScene.ts +29 -32
- package/src/playground/mobileControls.tsx +133 -129
- package/src/playground/playground.html +76 -73
- package/src/playground/playground.ts +14 -1
- package/src/playground/playgroundUi.tsx +100 -74
- package/src/playground/reactUtils.ts +3 -7
- package/src/playground/scenes/entities.ts +10 -7
- package/src/playground/scenes/frequentUpdates.ts +5 -5
- package/src/playground/scenes/geometryExport.ts +6 -20
- package/src/playground/scenes/highPosEntityUpdates.ts +2 -10
- package/src/playground/scenes/index.ts +1 -1
- package/src/playground/scenes/lightingStarfield.ts +18 -12
- package/src/playground/scenes/main.ts +15 -11
- package/src/playground/scenes/partialBlockCulling.ts +31 -0
- package/src/playground/scenes/railsCobweb.ts +1 -1
- package/src/playground/scenes/rotationIssue.ts +1 -1
- package/src/playground/scenes/slabsOptimization.ts +1 -2
- package/src/playground/scenes/transparencyIssue.ts +1 -1
- package/src/playground/shared.ts +2 -2
- package/src/resourcesManager/resourcesManager.ts +29 -54
- package/src/resourcesManager/resourcesManager.worker.test.ts +6 -10
- package/src/shims/minecraftData.ts +70 -24
- package/src/sign-renderer/index.html +10 -12
- package/src/sign-renderer/index.ts +29 -29
- package/src/sign-renderer/playground.ts +22 -15
- package/src/sign-renderer/tests.test.ts +16 -13
- package/src/sign-renderer/vite.config.ts +2 -2
- package/src/three/appShared.ts +46 -25
- package/src/three/bannerRenderer.ts +33 -61
- package/src/three/cameraShake.ts +15 -6
- package/src/three/chunkMeshManager.ts +239 -282
- package/src/three/cinimaticScript.ts +26 -15
- package/src/three/cubeDrawSpans.ts +27 -37
- package/src/three/cubeMultiDraw.ts +9 -22
- package/src/three/documentRenderer.ts +15 -18
- package/src/three/entities.ts +175 -150
- package/src/three/entity/EntityMesh.ts +114 -108
- package/src/three/entity/animations.js +3 -3
- package/src/three/entity/armorModels.ts +15 -15
- package/src/three/entity/gltfAnimationUtils.ts +2 -5
- package/src/three/fireworks.ts +34 -32
- package/src/three/fireworksRenderer.ts +32 -29
- package/src/three/globalBlockBuffer.ts +167 -100
- package/src/three/globalLegacyBuffer.ts +257 -166
- package/src/three/graphicsBackendBase.ts +19 -25
- package/src/three/graphicsBackendOffThread.ts +12 -15
- package/src/three/hand.ts +21 -21
- package/src/three/handLegacy.ts +3 -13
- package/src/three/holdingBlock.ts +116 -79
- package/src/three/holdingBlockFactory.ts +1 -4
- package/src/three/holdingBlockItemIdentity.test.ts +25 -17
- package/src/three/holdingBlockItemIdentity.ts +9 -6
- package/src/three/holdingBlockLegacy.ts +113 -132
- package/src/three/itemMesh.ts +20 -29
- package/src/three/legacyMultiDraw.ts +10 -16
- package/src/three/legacySectionCull.ts +8 -14
- package/src/three/menuBackground/activeView.ts +1 -4
- package/src/three/menuBackground/assetUrl.ts +1 -1
- package/src/three/menuBackground/classic.ts +4 -12
- package/src/three/menuBackground/gpuPreference.ts +1 -3
- package/src/three/menuBackground/index.ts +2 -11
- package/src/three/menuBackground/renderer.ts +1 -5
- package/src/three/menuBackground/types.ts +1 -4
- package/src/three/menuBackground/v2.ts +196 -96
- package/src/three/menuBackground/v2Meta.ts +3 -3
- package/src/three/menuBackground/worldBlocks.ts +37 -35
- package/src/three/modules/blockBreakParticles.ts +59 -28
- package/src/three/modules/cameraBobbing.ts +3 -6
- package/src/three/modules/index.ts +1 -1
- package/src/three/modules/rain.ts +10 -23
- package/src/three/modules/sciFiWorldReveal.ts +11 -25
- package/src/three/modules/starfield.ts +7 -13
- package/src/three/renderSlot.ts +28 -16
- package/src/three/rendererModuleSystem.ts +1 -3
- package/src/three/sceneOrigin.ts +96 -33
- package/src/three/sectionRaycastAabb.ts +30 -18
- package/src/three/shaderCubeMesh.ts +6 -17
- package/src/three/shaders/cubeBlockShader.ts +85 -96
- package/src/three/shaders/legacyBlockShader.ts +21 -43
- package/src/three/shaders/textureIndexMapping.ts +89 -95
- package/src/three/shaders/tintPalette.ts +156 -170
- package/src/three/signTextureCache.ts +9 -12
- package/src/three/skyboxRenderer.ts +62 -70
- package/src/three/tests/chunkMeshManagerLegacy.test.ts +34 -34
- package/src/three/tests/cubeDrawSpans.test.ts +55 -25
- package/src/three/tests/globalBlockBuffer.test.ts +217 -0
- package/src/three/tests/globalLegacyBuffer.test.ts +300 -41
- package/src/three/tests/legacyMultiDraw.test.ts +8 -29
- package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
- package/src/three/tests/signTextureCache.test.ts +4 -4
- package/src/three/threeJsMedia.ts +55 -72
- package/src/three/threeJsParticles.ts +32 -41
- package/src/three/threeJsSound.ts +3 -3
- package/src/three/threeJsUtils.ts +3 -3
- package/src/three/threeWorker.ts +2 -2
- package/src/three/waypointSprite.ts +55 -82
- package/src/three/waypoints.ts +20 -23
- package/src/three/world/cursorBlock.ts +25 -12
- package/src/three/world/vr.ts +11 -17
- package/src/three/worldGeometryExport.ts +15 -34
- package/src/three/worldRendererThree.ts +117 -129
- package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
- package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
- package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
- package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
- package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
- package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
- package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +17 -4
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
- package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
- package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
- package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
- package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
- package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
- package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
- package/src/worldView/worldView.spiral.test.ts +1 -1
- package/src/worldView/worldView.ts +34 -39
- package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
package/src/three/entities.ts
CHANGED
|
@@ -47,7 +47,7 @@ const degreesToRadians = (degrees: number) => degrees * (Math.PI / 180)
|
|
|
47
47
|
|
|
48
48
|
function convert2sComplementToHex(complement: number) {
|
|
49
49
|
if (complement < 0) {
|
|
50
|
-
complement = (
|
|
50
|
+
complement = (0xff_ff_ff_ff + complement + 1) >>> 0
|
|
51
51
|
}
|
|
52
52
|
return complement.toString(16)
|
|
53
53
|
}
|
|
@@ -104,15 +104,15 @@ const TAU_YAW = Math.PI * 2
|
|
|
104
104
|
|
|
105
105
|
/** Prismarine yaw in radians → shortest delta from→to in (-π, π]. */
|
|
106
106
|
function shortestYawRadians(fromYawRad: number, toYawRad: number): number {
|
|
107
|
-
const norm = ((toYawRad - fromYawRad) % TAU_YAW + TAU_YAW) % TAU_YAW
|
|
107
|
+
const norm = (((toYawRad - fromYawRad) % TAU_YAW) + TAU_YAW) % TAU_YAW
|
|
108
108
|
return norm > Math.PI ? norm - TAU_YAW : norm
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
function getUsernameTexture(
|
|
112
|
-
username,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
function getUsernameTexture(
|
|
112
|
+
{ username, nameTagBackgroundColor = 'rgba(0, 0, 0, 0.3)', nameTagTextOpacity = 255 }: any,
|
|
113
|
+
{ fontFamily = 'mojangles' }: any,
|
|
114
|
+
version: string
|
|
115
|
+
) {
|
|
116
116
|
const canvas = createCanvas(64, 64)
|
|
117
117
|
|
|
118
118
|
const PrismarineChat = PrismarineChatLoader(version)
|
|
@@ -157,10 +157,7 @@ const addNametag = (entity, options: { fontFamily: string }, mesh, version: stri
|
|
|
157
157
|
}
|
|
158
158
|
if (entity.username === undefined || entity.username === null) return
|
|
159
159
|
|
|
160
|
-
const plainUsername =
|
|
161
|
-
typeof entity.username === 'string'
|
|
162
|
-
? entity.username
|
|
163
|
-
: new (PrismarineChatLoader(version))(entity.username).toString()
|
|
160
|
+
const plainUsername = typeof entity.username === 'string' ? entity.username : new (PrismarineChatLoader(version))(entity.username).toString()
|
|
164
161
|
if (plainUsername.startsWith('EMPTY')) return
|
|
165
162
|
|
|
166
163
|
const canvas = getUsernameTexture(entity, options, version)
|
|
@@ -203,22 +200,31 @@ const addNametag = (entity, options: { fontFamily: string }, mesh, version: stri
|
|
|
203
200
|
// todo cleanup
|
|
204
201
|
const nametags = {}
|
|
205
202
|
|
|
206
|
-
const isFirstUpperCase =
|
|
203
|
+
const isFirstUpperCase = str => str.charAt(0) === str.charAt(0).toUpperCase()
|
|
207
204
|
|
|
208
|
-
function metadataAsArray
|
|
205
|
+
function metadataAsArray(metadata: unknown): unknown[] | undefined {
|
|
209
206
|
if (metadata == null) return undefined
|
|
210
207
|
if (Array.isArray(metadata)) return metadata
|
|
211
208
|
if (typeof metadata === 'object') {
|
|
212
209
|
const record = metadata as Record<string, unknown>
|
|
213
|
-
const keys = Object.keys(record)
|
|
210
|
+
const keys = Object.keys(record)
|
|
211
|
+
.filter(k => /^\d+$/.test(k))
|
|
212
|
+
.map(Number)
|
|
213
|
+
.sort((a, b) => a - b)
|
|
214
214
|
if (keys.length && keys[0] === 0 && keys.every((k, i) => k === i)) {
|
|
215
|
-
return keys.map(
|
|
215
|
+
return keys.map(k => record[String(k)])
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
return undefined
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
function getEntityMesh(
|
|
221
|
+
function getEntityMesh(
|
|
222
|
+
mcData: IndexedData | undefined,
|
|
223
|
+
entity: import('prismarine-entity').Entity & { delete?: any; pos?: any; name?: any },
|
|
224
|
+
world: WorldRendererThree,
|
|
225
|
+
options: { fontFamily: string },
|
|
226
|
+
overrides
|
|
227
|
+
) {
|
|
222
228
|
if (entity.name) {
|
|
223
229
|
try {
|
|
224
230
|
// https://github.com/PrismarineJS/prismarine-viewer/pull/410
|
|
@@ -241,10 +247,15 @@ function getEntityMesh(mcData: IndexedData | undefined, entity: import('prismari
|
|
|
241
247
|
const cube = new THREE.Mesh(geometry, material)
|
|
242
248
|
const nametagCount = (nametags[entity.name] = (nametags[entity.name] || 0) + 1)
|
|
243
249
|
if (nametagCount < 6) {
|
|
244
|
-
addNametag(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
250
|
+
addNametag(
|
|
251
|
+
{
|
|
252
|
+
username: entity.name,
|
|
253
|
+
height: entity.height
|
|
254
|
+
},
|
|
255
|
+
options,
|
|
256
|
+
cube,
|
|
257
|
+
world.version
|
|
258
|
+
)
|
|
248
259
|
}
|
|
249
260
|
return cube
|
|
250
261
|
}
|
|
@@ -254,7 +265,7 @@ export type SceneEntity = THREE.Object3D & {
|
|
|
254
265
|
username?: string
|
|
255
266
|
uuid?: string
|
|
256
267
|
additionalCleanup?: () => void
|
|
257
|
-
originalEntity: import('prismarine-entity').Entity & { delete?; pos
|
|
268
|
+
originalEntity: import('prismarine-entity').Entity & { delete?; pos?; name; team?: Team }
|
|
258
269
|
}
|
|
259
270
|
|
|
260
271
|
export class Entities {
|
|
@@ -295,9 +306,12 @@ export class Entities {
|
|
|
295
306
|
return `${visibleEntities}/${totalEntities} ${visiblePlayerEntities.length}/${playerEntities.length}`
|
|
296
307
|
}
|
|
297
308
|
|
|
298
|
-
constructor(
|
|
309
|
+
constructor(
|
|
310
|
+
public worldRenderer: WorldRendererThree,
|
|
311
|
+
public mcData?: IndexedData
|
|
312
|
+
) {
|
|
299
313
|
this.debugMode = 'none'
|
|
300
|
-
this.onSkinUpdate = () => {
|
|
314
|
+
this.onSkinUpdate = () => {}
|
|
301
315
|
this.watchResourcesUpdates()
|
|
302
316
|
}
|
|
303
317
|
|
|
@@ -355,7 +369,7 @@ export class Entities {
|
|
|
355
369
|
for (const entity of Object.values(this.entities)) {
|
|
356
370
|
// update all entities textures like held items, armour, etc
|
|
357
371
|
// todo update entity textures itself
|
|
358
|
-
this.update({ ...entity.originalEntity, delete: true
|
|
372
|
+
this.update({ ...entity.originalEntity, delete: true } as SceneEntity['originalEntity'], {})
|
|
359
373
|
this.update(entity.originalEntity, {})
|
|
360
374
|
}
|
|
361
375
|
}
|
|
@@ -421,11 +435,7 @@ export class Entities {
|
|
|
421
435
|
|
|
422
436
|
if (thirdPerson) {
|
|
423
437
|
const yOffset = this.worldRenderer.playerStateReactive.eyeHeight
|
|
424
|
-
entity.position.set(
|
|
425
|
-
this.worldRenderer.cameraWorldPos.x,
|
|
426
|
-
this.worldRenderer.cameraWorldPos.y - yOffset,
|
|
427
|
-
this.worldRenderer.cameraWorldPos.z
|
|
428
|
-
)
|
|
438
|
+
entity.position.set(this.worldRenderer.cameraWorldPos.x, this.worldRenderer.cameraWorldPos.y - yOffset, this.worldRenderer.cameraWorldPos.z)
|
|
429
439
|
}
|
|
430
440
|
}
|
|
431
441
|
|
|
@@ -460,7 +470,7 @@ export class Entities {
|
|
|
460
470
|
const rotation = this.worldRenderer.cameraShake.getBaseRotation()
|
|
461
471
|
entity.rotation.set(0, rotation.yaw, 0)
|
|
462
472
|
|
|
463
|
-
entity.traverse(
|
|
473
|
+
entity.traverse(c => {
|
|
464
474
|
if (c.name === 'head') {
|
|
465
475
|
c.rotation.set(-rotation.pitch, 0, 0)
|
|
466
476
|
}
|
|
@@ -473,7 +483,7 @@ export class Entities {
|
|
|
473
483
|
if (!entity.playerObject) return
|
|
474
484
|
|
|
475
485
|
// todo-low use property access for less loop iterations (small performance gain)
|
|
476
|
-
entity.traverse(
|
|
486
|
+
entity.traverse(armor => {
|
|
477
487
|
if (!armor.name.startsWith('geometry_armor_')) return
|
|
478
488
|
|
|
479
489
|
const { skin } = entity.playerObject!
|
|
@@ -482,12 +492,7 @@ export class Entities {
|
|
|
482
492
|
case 'geometry_armor_head':
|
|
483
493
|
// Head armor sync
|
|
484
494
|
if (armor.children[0]?.children[0]) {
|
|
485
|
-
armor.children[0].children[0].rotation.set(
|
|
486
|
-
-skin.head.rotation.x,
|
|
487
|
-
skin.head.rotation.y,
|
|
488
|
-
skin.head.rotation.z,
|
|
489
|
-
skin.head.rotation.order
|
|
490
|
-
)
|
|
495
|
+
armor.children[0].children[0].rotation.set(-skin.head.rotation.x, skin.head.rotation.y, skin.head.rotation.z, skin.head.rotation.order)
|
|
491
496
|
}
|
|
492
497
|
break
|
|
493
498
|
|
|
@@ -548,19 +553,23 @@ export class Entities {
|
|
|
548
553
|
return playerObject
|
|
549
554
|
}
|
|
550
555
|
|
|
551
|
-
uuidPerSkinUrlsCache = {} as Record<string, { skinUrl?: string
|
|
556
|
+
uuidPerSkinUrlsCache = {} as Record<string, { skinUrl?: string; capeUrl?: string }>
|
|
552
557
|
currentSkinUrls = {} as Record<string, string>
|
|
553
558
|
|
|
554
559
|
private isCanvasBlank(canvas: HTMLCanvasElement | OffscreenCanvas): boolean {
|
|
555
560
|
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null
|
|
556
|
-
return !ctx
|
|
557
|
-
?.getImageData(0, 0, canvas.width, canvas.height).data
|
|
558
|
-
.some(channel => channel !== 0)
|
|
561
|
+
return !ctx?.getImageData(0, 0, canvas.width, canvas.height).data.some(channel => channel !== 0)
|
|
559
562
|
}
|
|
560
563
|
|
|
561
564
|
// todo true/undefined doesnt reset the skin to the default one
|
|
562
565
|
// eslint-disable-next-line max-params
|
|
563
|
-
async updatePlayerSkin(
|
|
566
|
+
async updatePlayerSkin(
|
|
567
|
+
entityId: string | number,
|
|
568
|
+
username: string | undefined,
|
|
569
|
+
uuidCache: string | undefined,
|
|
570
|
+
skinUrl: string | true,
|
|
571
|
+
capeUrl: string | true | undefined = undefined
|
|
572
|
+
) {
|
|
564
573
|
const isCustomSkin = skinUrl !== stevePngUrl
|
|
565
574
|
if (isCustomSkin) {
|
|
566
575
|
this.loadedSkinEntityIds.add(String(entityId))
|
|
@@ -623,7 +632,6 @@ export class Entities {
|
|
|
623
632
|
}
|
|
624
633
|
})
|
|
625
634
|
|
|
626
|
-
|
|
627
635
|
playerObject.cape.visible = false
|
|
628
636
|
if (!capeUrl) {
|
|
629
637
|
playerObject.backEquipment = null
|
|
@@ -636,12 +644,7 @@ export class Entities {
|
|
|
636
644
|
}
|
|
637
645
|
|
|
638
646
|
/** Local preview override: hand + player model until server skin refresh or reconnect. */
|
|
639
|
-
async applyTemporaryPlayerSkinOverride
|
|
640
|
-
skinUrl: string,
|
|
641
|
-
entityId: string | number,
|
|
642
|
-
username?: string,
|
|
643
|
-
uuid?: string
|
|
644
|
-
) {
|
|
647
|
+
async applyTemporaryPlayerSkinOverride(skinUrl: string, entityId: string | number, username?: string, uuid?: string) {
|
|
645
648
|
this.worldRenderer.playerStateReactive.playerSkin = skinUrl
|
|
646
649
|
await this.updatePlayerSkin(entityId, username, uuid, skinUrl, undefined)
|
|
647
650
|
}
|
|
@@ -740,10 +743,7 @@ export class Entities {
|
|
|
740
743
|
}
|
|
741
744
|
}
|
|
742
745
|
|
|
743
|
-
private applyMovementAnimation(
|
|
744
|
-
playerObject: PlayerObjectType,
|
|
745
|
-
animation: 'walking' | 'running' | 'oneSwing' | 'idle' | 'crouch' | 'crouchWalking',
|
|
746
|
-
): void {
|
|
746
|
+
private applyMovementAnimation(playerObject: PlayerObjectType, animation: 'walking' | 'running' | 'oneSwing' | 'idle' | 'crouch' | 'crouchWalking'): void {
|
|
747
747
|
const anim = playerObject.animation as WalkingGeneralSwing | undefined
|
|
748
748
|
if (!anim) return
|
|
749
749
|
|
|
@@ -759,9 +759,8 @@ export class Entities {
|
|
|
759
759
|
}
|
|
760
760
|
|
|
761
761
|
playAnimation(entityPlayerId, animation: 'walking' | 'running' | 'oneSwing' | 'idle' | 'crouch' | 'crouchWalking') {
|
|
762
|
-
const playerObject =
|
|
763
|
-
? this.playerEntity?.playerObject
|
|
764
|
-
: this.getPlayerObject(entityPlayerId) ?? this.playerEntity?.playerObject
|
|
762
|
+
const playerObject =
|
|
763
|
+
entityPlayerId === 'player_entity' ? this.playerEntity?.playerObject : (this.getPlayerObject(entityPlayerId) ?? this.playerEntity?.playerObject)
|
|
765
764
|
|
|
766
765
|
if (!playerObject) return
|
|
767
766
|
this.applyMovementAnimation(playerObject, animation)
|
|
@@ -782,7 +781,7 @@ export class Entities {
|
|
|
782
781
|
}
|
|
783
782
|
|
|
784
783
|
private textFromComponent(component) {
|
|
785
|
-
return typeof component === 'string' ? component : component.text ?? ''
|
|
784
|
+
return typeof component === 'string' ? component : (component.text ?? '')
|
|
786
785
|
}
|
|
787
786
|
|
|
788
787
|
getItemMesh(item, specificProps: ItemSpecificContextProperties, faceCamera = false, previousModel?: string) {
|
|
@@ -791,7 +790,13 @@ export class Entities {
|
|
|
791
790
|
if (previousModel && previousModel === textureUv?.modelName) return undefined
|
|
792
791
|
|
|
793
792
|
if (textureUv && 'resolvedModel' in textureUv) {
|
|
794
|
-
const mesh = getBlockMeshFromModel(
|
|
793
|
+
const mesh = getBlockMeshFromModel(
|
|
794
|
+
this.worldRenderer.material,
|
|
795
|
+
textureUv.resolvedModel,
|
|
796
|
+
textureUv.modelName,
|
|
797
|
+
this.worldRenderer.resourcesManager.currentResources.worldBlockProvider!,
|
|
798
|
+
this.worldRenderer.resourcesManager.currentResources.mcData!
|
|
799
|
+
)
|
|
795
800
|
let SCALE = 1
|
|
796
801
|
if (specificProps['minecraft:display_context'] === 'ground') {
|
|
797
802
|
SCALE = 0.5
|
|
@@ -804,7 +809,7 @@ export class Entities {
|
|
|
804
809
|
return {
|
|
805
810
|
mesh: outerGroup,
|
|
806
811
|
isBlock: true,
|
|
807
|
-
modelName: textureUv.modelName
|
|
812
|
+
modelName: textureUv.modelName
|
|
808
813
|
}
|
|
809
814
|
}
|
|
810
815
|
|
|
@@ -815,15 +820,19 @@ export class Entities {
|
|
|
815
820
|
const sizeX = su ?? 1 // su is actually width
|
|
816
821
|
const sizeY = sv ?? 1 // sv is actually height
|
|
817
822
|
|
|
818
|
-
const result = createItemMesh(
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
823
|
+
const result = createItemMesh(
|
|
824
|
+
textureThree,
|
|
825
|
+
{
|
|
826
|
+
u,
|
|
827
|
+
v,
|
|
828
|
+
sizeX,
|
|
829
|
+
sizeY
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
faceCamera,
|
|
833
|
+
use3D: !faceCamera // Only use 3D for non-camera-facing items
|
|
834
|
+
}
|
|
835
|
+
)
|
|
827
836
|
|
|
828
837
|
let SCALE = 1
|
|
829
838
|
if (specificProps['minecraft:display_context'] === 'ground') {
|
|
@@ -887,18 +896,31 @@ export class Entities {
|
|
|
887
896
|
|
|
888
897
|
const group = new THREE.Group() as unknown as SceneEntity
|
|
889
898
|
group.originalEntity = entity
|
|
890
|
-
if (
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
899
|
+
if (
|
|
900
|
+
entity.name === 'item' ||
|
|
901
|
+
entity.name === 'tnt' ||
|
|
902
|
+
entity.name === 'falling_block' ||
|
|
903
|
+
entity.name === 'snowball' ||
|
|
904
|
+
entity.name === 'egg' ||
|
|
905
|
+
entity.name === 'ender_pearl' ||
|
|
906
|
+
entity.name === 'experience_bottle' ||
|
|
907
|
+
entity.name === 'splash_potion' ||
|
|
908
|
+
entity.name === 'lingering_potion'
|
|
909
|
+
) {
|
|
910
|
+
const item =
|
|
911
|
+
entity.name === 'tnt' || entity.type === 'projectile'
|
|
912
|
+
? { name: entity.name }
|
|
913
|
+
: entity.name === 'falling_block'
|
|
914
|
+
? { blockState: entity['objectData'] }
|
|
915
|
+
: metadataAsArray(entity.metadata)?.find((m: any) => typeof m === 'object' && m?.itemCount)
|
|
898
916
|
if (item) {
|
|
899
|
-
const object = this.getItemMesh(
|
|
900
|
-
|
|
901
|
-
|
|
917
|
+
const object = this.getItemMesh(
|
|
918
|
+
item,
|
|
919
|
+
{
|
|
920
|
+
'minecraft:display_context': 'ground'
|
|
921
|
+
},
|
|
922
|
+
entity.type === 'projectile'
|
|
923
|
+
)
|
|
902
924
|
if (object) {
|
|
903
925
|
mesh = object.mesh
|
|
904
926
|
if (entity.name === 'item' || entity.type === 'projectile') {
|
|
@@ -954,10 +976,7 @@ export class Entities {
|
|
|
954
976
|
// todo use width and height instead
|
|
955
977
|
const boxHelper = new THREE.BoxHelper(
|
|
956
978
|
mesh,
|
|
957
|
-
entity.type === 'hostile' ? 0xff_00_00 :
|
|
958
|
-
entity.type === 'mob' ? 0x00_ff_00 :
|
|
959
|
-
entity.type === 'player' ? 0x00_00_ff :
|
|
960
|
-
0xff_a5_00,
|
|
979
|
+
entity.type === 'hostile' ? 0xff_00_00 : entity.type === 'mob' ? 0x00_ff_00 : entity.type === 'player' ? 0x00_00_ff : 0xff_a5_00
|
|
961
980
|
)
|
|
962
981
|
boxHelper.name = 'debug'
|
|
963
982
|
group.add(mesh)
|
|
@@ -987,7 +1006,9 @@ export class Entities {
|
|
|
987
1006
|
const meta = getGeneralEntitiesMetadata(entity, this.mcData)
|
|
988
1007
|
|
|
989
1008
|
const meta0 = metadataAsArray(entity.metadata)?.[0] ?? (entity.metadata as { 0?: unknown } | undefined)?.[0]
|
|
990
|
-
const isInvisible =
|
|
1009
|
+
const isInvisible =
|
|
1010
|
+
((meta0 ?? 0) as unknown as number) & 0x20 ||
|
|
1011
|
+
(this.worldRenderer.playerStateReactive.cameraSpectatingEntity === entity.id && this.worldRenderer.playerStateUtils.isSpectator())
|
|
991
1012
|
for (const child of mesh!.children ?? []) {
|
|
992
1013
|
if (child.name !== 'nametag') {
|
|
993
1014
|
child.visible = !isInvisible
|
|
@@ -1002,10 +1023,11 @@ export class Entities {
|
|
|
1002
1023
|
}
|
|
1003
1024
|
// entity specific meta
|
|
1004
1025
|
const textDisplayMeta = getSpecificEntityMetadata('text_display', entity, this.mcData)
|
|
1005
|
-
const displayTextRaw = textDisplayMeta?.text || meta.custom_name_visible && meta.custom_name
|
|
1026
|
+
const displayTextRaw = textDisplayMeta?.text || (meta.custom_name_visible && meta.custom_name)
|
|
1006
1027
|
if (entity.name !== 'player' && displayTextRaw) {
|
|
1007
1028
|
const nameTagFixed = textDisplayMeta && (textDisplayMeta.billboard_render_constraints === 'fixed' || !textDisplayMeta.billboard_render_constraints)
|
|
1008
|
-
const nameTagBackgroundColor =
|
|
1029
|
+
const nameTagBackgroundColor =
|
|
1030
|
+
textDisplayMeta && (parseInt(textDisplayMeta.style_flags, 10) & 0x04) === 0 ? toRgba(textDisplayMeta.background_color) : undefined
|
|
1009
1031
|
let nameTagTextOpacity: any
|
|
1010
1032
|
if (textDisplayMeta?.text_opacity) {
|
|
1011
1033
|
const rawOpacity = parseInt(textDisplayMeta?.text_opacity, 10)
|
|
@@ -1013,10 +1035,15 @@ export class Entities {
|
|
|
1013
1035
|
}
|
|
1014
1036
|
addNametag(
|
|
1015
1037
|
{
|
|
1016
|
-
...entity,
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1038
|
+
...entity,
|
|
1039
|
+
username: typeof displayTextRaw === 'string' ? mojangson.simplify(mojangson.parse(displayTextRaw)) : nbt.simplify(displayTextRaw),
|
|
1040
|
+
nameTagBackgroundColor,
|
|
1041
|
+
nameTagTextOpacity,
|
|
1042
|
+
nameTagFixed,
|
|
1043
|
+
nameTagScale: textDisplayMeta?.scale,
|
|
1044
|
+
nameTagTranslation: textDisplayMeta && (textDisplayMeta.translation || new THREE.Vector3(0, 0, 0)),
|
|
1045
|
+
nameTagRotationLeft: toQuaternion(textDisplayMeta?.left_rotation),
|
|
1046
|
+
nameTagRotationRight: toQuaternion(textDisplayMeta?.right_rotation)
|
|
1020
1047
|
},
|
|
1021
1048
|
this.entitiesOptions,
|
|
1022
1049
|
mesh,
|
|
@@ -1060,7 +1087,7 @@ export class Entities {
|
|
|
1060
1087
|
if (armorStandMeta.left_arm_pose) {
|
|
1061
1088
|
c.setRotationFromEuler(poseToEuler(armorStandMeta.left_arm_pose))
|
|
1062
1089
|
} else {
|
|
1063
|
-
c.setRotationFromEuler(poseToEuler({
|
|
1090
|
+
c.setRotationFromEuler(poseToEuler({ yaw: -10, pitch: -10, roll: 0 }))
|
|
1064
1091
|
}
|
|
1065
1092
|
break
|
|
1066
1093
|
case 'bone_leftarm':
|
|
@@ -1070,21 +1097,21 @@ export class Entities {
|
|
|
1070
1097
|
if (armorStandMeta.right_arm_pose) {
|
|
1071
1098
|
c.setRotationFromEuler(poseToEuler(armorStandMeta.right_arm_pose))
|
|
1072
1099
|
} else {
|
|
1073
|
-
c.setRotationFromEuler(poseToEuler({
|
|
1100
|
+
c.setRotationFromEuler(poseToEuler({ yaw: 10, pitch: -10, roll: 0 }))
|
|
1074
1101
|
}
|
|
1075
1102
|
break
|
|
1076
1103
|
case 'bone_rightleg':
|
|
1077
1104
|
if (armorStandMeta.left_leg_pose) {
|
|
1078
1105
|
c.setRotationFromEuler(poseToEuler(armorStandMeta.left_leg_pose))
|
|
1079
1106
|
} else {
|
|
1080
|
-
c.setRotationFromEuler(poseToEuler({
|
|
1107
|
+
c.setRotationFromEuler(poseToEuler({ yaw: -1, pitch: -1, roll: 0 }))
|
|
1081
1108
|
}
|
|
1082
1109
|
break
|
|
1083
1110
|
case 'bone_leftleg':
|
|
1084
1111
|
if (armorStandMeta.right_leg_pose) {
|
|
1085
1112
|
c.setRotationFromEuler(poseToEuler(armorStandMeta.right_leg_pose))
|
|
1086
1113
|
} else {
|
|
1087
|
-
c.setRotationFromEuler(poseToEuler({
|
|
1114
|
+
c.setRotationFromEuler(poseToEuler({ yaw: 1, pitch: 1, roll: 0 }))
|
|
1088
1115
|
}
|
|
1089
1116
|
break
|
|
1090
1117
|
}
|
|
@@ -1099,26 +1126,28 @@ export class Entities {
|
|
|
1099
1126
|
if (itemFrameMeta) {
|
|
1100
1127
|
// TODO: fix type
|
|
1101
1128
|
// todo! fix errors in mc-data (no entities data prior 1.18.2)
|
|
1102
|
-
const item = (itemFrameMeta?.item ?? entity.metadata?.[8]) as any as { itemId
|
|
1129
|
+
const item = (itemFrameMeta?.item ?? entity.metadata?.[8]) as any as { itemId; blockId; components; nbtData: { value: { map: { value: number } } } }
|
|
1103
1130
|
mesh!.scale.set(1, 1, 1)
|
|
1104
1131
|
mesh!.position.set(0, 0, -0.5)
|
|
1105
1132
|
|
|
1106
1133
|
e.rotation.x = -entity.pitch
|
|
1107
|
-
e.children
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
c.
|
|
1134
|
+
e.children
|
|
1135
|
+
.find(c => {
|
|
1136
|
+
if (c.name.startsWith('map_')) {
|
|
1137
|
+
disposeObject(c)
|
|
1138
|
+
const existingMapNumber = parseInt(c.name.split('_')[1], 10)
|
|
1139
|
+
this.itemFrameMaps[existingMapNumber] = this.itemFrameMaps[existingMapNumber]?.filter(mesh => mesh !== c)
|
|
1140
|
+
if (c instanceof THREE.Mesh) {
|
|
1141
|
+
c.material?.map?.dispose()
|
|
1142
|
+
}
|
|
1143
|
+
return true
|
|
1144
|
+
} else if (c.name === 'item') {
|
|
1145
|
+
disposeObject(c)
|
|
1146
|
+
return true
|
|
1114
1147
|
}
|
|
1115
|
-
return
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
return true
|
|
1119
|
-
}
|
|
1120
|
-
return false
|
|
1121
|
-
})?.removeFromParent()
|
|
1148
|
+
return false
|
|
1149
|
+
})
|
|
1150
|
+
?.removeFromParent()
|
|
1122
1151
|
|
|
1123
1152
|
if (item && (item.itemId ?? item.blockId ?? 0) !== 0) {
|
|
1124
1153
|
// Get rotation from metadata, default to 0 if not present
|
|
@@ -1133,7 +1162,7 @@ export class Entities {
|
|
|
1133
1162
|
} else {
|
|
1134
1163
|
// Handle regular item rotation (8 possibilities, 45° increments)
|
|
1135
1164
|
const itemMesh = this.getItemMesh(item, {
|
|
1136
|
-
'minecraft:display_context': 'fixed'
|
|
1165
|
+
'minecraft:display_context': 'fixed'
|
|
1137
1166
|
})
|
|
1138
1167
|
if (itemMesh) {
|
|
1139
1168
|
itemMesh.mesh.position.set(0, 0, -0.05)
|
|
@@ -1145,7 +1174,7 @@ export class Entities {
|
|
|
1145
1174
|
// Rotate 180° around Y axis first
|
|
1146
1175
|
itemMesh.mesh.rotateY(Math.PI)
|
|
1147
1176
|
// Then apply the 45° increment rotation
|
|
1148
|
-
itemMesh.mesh.rotateZ(-rotation * Math.PI / 4)
|
|
1177
|
+
itemMesh.mesh.rotateZ((-rotation * Math.PI) / 4)
|
|
1149
1178
|
itemMesh.mesh.name = 'item'
|
|
1150
1179
|
e.add(itemMesh.mesh)
|
|
1151
1180
|
}
|
|
@@ -1162,7 +1191,7 @@ export class Entities {
|
|
|
1162
1191
|
this.updateEntityPosition(entity, justAdded, overrides)
|
|
1163
1192
|
}
|
|
1164
1193
|
|
|
1165
|
-
updateEntityPosition(entity: import('prismarine-entity').Entity, justAdded: boolean, overrides: { rotation?: { head?: { y: number
|
|
1194
|
+
updateEntityPosition(entity: import('prismarine-entity').Entity, justAdded: boolean, overrides: { rotation?: { head?: { y: number; x: number } } }) {
|
|
1166
1195
|
const e = this.entities[entity.id]
|
|
1167
1196
|
if (!e) return
|
|
1168
1197
|
const ANIMATION_DURATION = justAdded ? 0 : TWEEN_DURATION
|
|
@@ -1186,8 +1215,7 @@ export class Entities {
|
|
|
1186
1215
|
let targetYaw: number | undefined
|
|
1187
1216
|
if (e.playerObject && overrides?.rotation?.head) {
|
|
1188
1217
|
const hy = overrides.rotation.head.y
|
|
1189
|
-
const headYawWorld =
|
|
1190
|
-
typeof hy === 'number' && Number.isFinite(hy) ? hy : entity.yaw
|
|
1218
|
+
const headYawWorld = typeof hy === 'number' && Number.isFinite(hy) ? hy : entity.yaw
|
|
1191
1219
|
if (typeof headYawWorld === 'number' && Number.isFinite(headYawWorld)) {
|
|
1192
1220
|
targetYaw = headYawWorld
|
|
1193
1221
|
}
|
|
@@ -1198,9 +1226,7 @@ export class Entities {
|
|
|
1198
1226
|
const dy = shortestYawRadians(e.rotation.y, targetYaw)
|
|
1199
1227
|
// Stop previous rotation tween to prevent accumulation (mirror _posTween)
|
|
1200
1228
|
e.userData._rotTween?.stop()
|
|
1201
|
-
e.userData._rotTween = new TWEEN.Tween(e.rotation)
|
|
1202
|
-
.to({ y: e.rotation.y + dy }, ANIMATION_DURATION)
|
|
1203
|
-
.start()
|
|
1229
|
+
e.userData._rotTween = new TWEEN.Tween(e.rotation).to({ y: e.rotation.y + dy }, ANIMATION_DURATION).start()
|
|
1204
1230
|
}
|
|
1205
1231
|
|
|
1206
1232
|
if (e?.playerObject && overrides?.rotation?.head) {
|
|
@@ -1208,13 +1234,11 @@ export class Entities {
|
|
|
1208
1234
|
playerObject.skin.head.rotation.y = 0
|
|
1209
1235
|
|
|
1210
1236
|
const hp = overrides.rotation.head.x
|
|
1211
|
-
playerObject.skin.head.rotation.x =
|
|
1212
|
-
typeof hp === 'number' && Number.isFinite(hp) ? -hp : 0
|
|
1237
|
+
playerObject.skin.head.rotation.x = typeof hp === 'number' && Number.isFinite(hp) ? -hp : 0
|
|
1213
1238
|
}
|
|
1214
1239
|
}
|
|
1215
1240
|
|
|
1216
|
-
afterAddEntity(entity: import('prismarine-entity').Entity) {
|
|
1217
|
-
}
|
|
1241
|
+
afterAddEntity(entity: import('prismarine-entity').Entity) {}
|
|
1218
1242
|
|
|
1219
1243
|
beforeEntityAdded(entity: import('prismarine-entity').Entity) {
|
|
1220
1244
|
const override = this.pendingModelOverrides.get(entity.id.toString())
|
|
@@ -1244,7 +1268,7 @@ export class Entities {
|
|
|
1244
1268
|
? new THREE.Vector3(wp.x, wp.y, wp.z)
|
|
1245
1269
|
: mesh.position.clone().add(new THREE.Vector3(this.worldRenderer.sceneOrigin.x, this.worldRenderer.sceneOrigin.y, this.worldRenderer.sceneOrigin.z))
|
|
1246
1270
|
const distance = entityWorldPos.distanceTo(cameraPos)
|
|
1247
|
-
if (distance < MAX_DISTANCE_SKIN_LOAD && distance <
|
|
1271
|
+
if (distance < MAX_DISTANCE_SKIN_LOAD && distance < this.worldRenderer.viewDistance * 16) {
|
|
1248
1272
|
if (this.loadedSkinEntityIds.has(String(entityId))) return
|
|
1249
1273
|
void this.updatePlayerSkin(entityId, mesh.playerObject.realUsername, mesh.playerObject.realPlayerUuid, true, true)
|
|
1250
1274
|
}
|
|
@@ -1274,7 +1298,8 @@ export class Entities {
|
|
|
1274
1298
|
const playerTeam = this.worldRenderer.playerStateReactive.team
|
|
1275
1299
|
const entityTeam = entity.originalEntity.team
|
|
1276
1300
|
const nameTagVisibility = entityTeam?.nameTagVisibility || 'always'
|
|
1277
|
-
const showNameTag =
|
|
1301
|
+
const showNameTag =
|
|
1302
|
+
nameTagVisibility === 'always' ||
|
|
1278
1303
|
(nameTagVisibility === 'hideForOwnTeam' && entityTeam?.team !== playerTeam?.team) ||
|
|
1279
1304
|
(nameTagVisibility === 'hideForOtherTeams' && (entityTeam?.team === playerTeam?.team || playerTeam === undefined))
|
|
1280
1305
|
entity.traverse(c => {
|
|
@@ -1292,7 +1317,7 @@ export class Entities {
|
|
|
1292
1317
|
}
|
|
1293
1318
|
const parameters = {
|
|
1294
1319
|
transparent: true,
|
|
1295
|
-
alphaTest: 0.1
|
|
1320
|
+
alphaTest: 0.1
|
|
1296
1321
|
}
|
|
1297
1322
|
if (texture) {
|
|
1298
1323
|
parameters['map'] = texture
|
|
@@ -1315,7 +1340,7 @@ export class Entities {
|
|
|
1315
1340
|
mapMesh.position.set(0, 0, 0.437)
|
|
1316
1341
|
}
|
|
1317
1342
|
// Apply 90° increment rotation for maps (0-3)
|
|
1318
|
-
mapMesh.rotateZ(Math.PI * 2 - rotation * Math.PI / 2)
|
|
1343
|
+
mapMesh.rotateZ(Math.PI * 2 - (rotation * Math.PI) / 2)
|
|
1319
1344
|
mapMesh.name = `map_${mapNumber}`
|
|
1320
1345
|
|
|
1321
1346
|
if (!texture) {
|
|
@@ -1348,7 +1373,7 @@ export class Entities {
|
|
|
1348
1373
|
if (!item) return
|
|
1349
1374
|
|
|
1350
1375
|
const itemObject = this.getItemMesh(item, {
|
|
1351
|
-
'minecraft:display_context': 'thirdperson'
|
|
1376
|
+
'minecraft:display_context': 'thirdperson'
|
|
1352
1377
|
})
|
|
1353
1378
|
if (itemObject?.mesh) {
|
|
1354
1379
|
entityMesh.traverse(c => {
|
|
@@ -1390,16 +1415,14 @@ export class Entities {
|
|
|
1390
1415
|
handleDamageEvent(entityId, damageAmount) {
|
|
1391
1416
|
const entityMesh = this.entities[entityId]?.children.find(c => c.name === 'mesh')
|
|
1392
1417
|
if (entityMesh) {
|
|
1393
|
-
entityMesh.traverse(
|
|
1418
|
+
entityMesh.traverse(child => {
|
|
1394
1419
|
if (child instanceof THREE.Mesh && child.material.clone) {
|
|
1395
1420
|
const clonedMaterial = child.material.clone()
|
|
1396
1421
|
clonedMaterial.dispose()
|
|
1397
1422
|
child.material = child.material.clone()
|
|
1398
1423
|
const originalColor = child.material.color.clone()
|
|
1399
1424
|
child.material.color.set(0xff_00_00)
|
|
1400
|
-
new TWEEN.Tween(child.material.color)
|
|
1401
|
-
.to(originalColor, 500)
|
|
1402
|
-
.start()
|
|
1425
|
+
new TWEEN.Tween(child.material.color).to(originalColor, 500).start()
|
|
1403
1426
|
}
|
|
1404
1427
|
})
|
|
1405
1428
|
}
|
|
@@ -1413,12 +1436,7 @@ export class Entities {
|
|
|
1413
1436
|
return intersects[0]?.object
|
|
1414
1437
|
}
|
|
1415
1438
|
|
|
1416
|
-
updateEntityModel(
|
|
1417
|
-
entityId: string,
|
|
1418
|
-
modelPathOrParts: string | EntityModelOverridePart[],
|
|
1419
|
-
modelType?: Entity.EntityModelType,
|
|
1420
|
-
metadata?: any
|
|
1421
|
-
) {
|
|
1439
|
+
updateEntityModel(entityId: string, modelPathOrParts: string | EntityModelOverridePart[], modelType?: Entity.EntityModelType, metadata?: any) {
|
|
1422
1440
|
const parts: EntityModelOverridePart[] = Array.isArray(modelPathOrParts)
|
|
1423
1441
|
? modelPathOrParts
|
|
1424
1442
|
: [{ modelPath: modelPathOrParts, modelType: modelType!, metadata }]
|
|
@@ -1468,7 +1486,7 @@ export class Entities {
|
|
|
1468
1486
|
// Update player-specific equipment
|
|
1469
1487
|
if (isPlayer && entityMesh.playerObject) {
|
|
1470
1488
|
const { playerObject } = entityMesh
|
|
1471
|
-
playerObject.backEquipment = entity.equipment.some(
|
|
1489
|
+
playerObject.backEquipment = entity.equipment.some(item => item?.name === 'elytra') ? 'elytra' : 'cape'
|
|
1472
1490
|
if (playerObject.backEquipment === 'elytra') {
|
|
1473
1491
|
void this.loadAndApplyCape(entity.id, elytraTexture)
|
|
1474
1492
|
}
|
|
@@ -1479,15 +1497,21 @@ export class Entities {
|
|
|
1479
1497
|
}
|
|
1480
1498
|
}
|
|
1481
1499
|
|
|
1482
|
-
function getGeneralEntitiesMetadata(
|
|
1500
|
+
function getGeneralEntitiesMetadata(
|
|
1501
|
+
entity: { name; metadata },
|
|
1502
|
+
mcData?: IndexedData
|
|
1503
|
+
): Partial<UnionToIntersection<EntityMetadataVersions[keyof EntityMetadataVersions]>> {
|
|
1483
1504
|
const entityData = mcData?.entitiesByName[entity.name]
|
|
1484
|
-
return new Proxy(
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1505
|
+
return new Proxy(
|
|
1506
|
+
{},
|
|
1507
|
+
{
|
|
1508
|
+
get(target, p, receiver) {
|
|
1509
|
+
if (typeof p !== 'string' || !entityData) return
|
|
1510
|
+
const index = entityData.metadataKeys?.indexOf(p)
|
|
1511
|
+
return entity.metadata?.[index ?? -1]
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
)
|
|
1491
1515
|
}
|
|
1492
1516
|
|
|
1493
1517
|
function getSpecificEntityMetadata<T extends keyof EntityMetadataVersions>(name: T, entity, mcData?: IndexedData): EntityMetadataVersions[T] | undefined {
|
|
@@ -1519,7 +1543,8 @@ function addArmorModel(worldRenderer: WorldRendererThree, entityMesh: THREE.Obje
|
|
|
1519
1543
|
texturePath = decodedData.textures?.SKIN?.url
|
|
1520
1544
|
const { skinTexturesProxy } = worldRenderer.worldRendererConfig
|
|
1521
1545
|
if (skinTexturesProxy) {
|
|
1522
|
-
texturePath = texturePath
|
|
1546
|
+
texturePath = texturePath
|
|
1547
|
+
?.replace('http://textures.minecraft.net/', skinTexturesProxy)
|
|
1523
1548
|
.replace('https://textures.minecraft.net/', skinTexturesProxy)
|
|
1524
1549
|
}
|
|
1525
1550
|
}
|
|
@@ -1569,16 +1594,16 @@ function addArmorModel(worldRenderer: WorldRendererThree, entityMesh: THREE.Obje
|
|
|
1569
1594
|
if (armorMaterial === 'leather' && !overlay) {
|
|
1570
1595
|
const color = (item.nbt?.value as any)?.display?.value?.color?.value
|
|
1571
1596
|
if (color) {
|
|
1572
|
-
const r = color >> 16 & 0xff
|
|
1573
|
-
const g = color >> 8 & 0xff
|
|
1597
|
+
const r = (color >> 16) & 0xff
|
|
1598
|
+
const g = (color >> 8) & 0xff
|
|
1574
1599
|
const b = color & 0xff
|
|
1575
1600
|
material.color.setRGB(r / 255, g / 255, b / 255)
|
|
1576
1601
|
} else {
|
|
1577
|
-
material.color.setHex(
|
|
1602
|
+
material.color.setHex(0xb5_6d_51) // default brown color
|
|
1578
1603
|
}
|
|
1579
1604
|
addArmorModel(worldRenderer, entityMesh, slotType, item, layer, true)
|
|
1580
1605
|
} else {
|
|
1581
|
-
material.color.setHex(
|
|
1606
|
+
material.color.setHex(0xff_ff_ff)
|
|
1582
1607
|
}
|
|
1583
1608
|
const group = new THREE.Object3D()
|
|
1584
1609
|
group.name = `armor_${slotType}${overlay ? '_overlay' : ''}`
|