UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

105 lines (104 loc) 4.23 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const MolangEvaluator_1 = __importDefault(require("./MolangEvaluator")); class RenderControllerResolver { _evaluator; constructor() { this._evaluator = new MolangEvaluator_1.default(); } /** * Resolve a render controller to concrete geometry/texture/material values. * * @param rc The render controller data from the .render_controllers.json file * @param textureMap Entity's texture key map: {"default": "textures/entity/sheep/sheep", "baby": "..."} * @param geometryMap Entity's geometry key map: {"default": "geometry.sheep.v1.8", "sheared": "..."} * @param context Molang evaluation context (entity state) * @returns Resolved geometry ID, texture layers, and optional tint */ resolve(rc, textureMap, geometryMap, context) { const arrays = this._buildArrayMap(rc.arrays); // Resolve geometry let geometryId; if (rc.geometry) { const geoRef = this._evaluator.evaluateString(rc.geometry, context, arrays); geometryId = this._resolveReference(geoRef, "Geometry", geometryMap); } // Resolve texture layers const textureLayers = []; if (rc.textures) { for (const texExpr of rc.textures) { const texRef = this._evaluator.evaluateString(texExpr, context, arrays); const texPath = this._resolveReference(texRef, "Texture", textureMap); if (texPath) { textureLayers.push({ texturePath: texPath }); } } } // If no layers resolved, try fallback to "default" texture if (textureLayers.length === 0 && textureMap["default"]) { textureLayers.push({ texturePath: textureMap["default"] }); } return { geometryId, textureLayers, }; } /** * Resolve a reference like "Texture.default" or "Geometry.baby" to the actual * path/ID using the entity's key maps. */ _resolveReference(ref, prefix, keyMap) { if (!ref) return undefined; // Check if it's a prefixed reference: "Texture.default" → key "default" const prefixDot = prefix + "."; if (ref.startsWith(prefixDot)) { const key = ref.substring(prefixDot.length); return keyMap[key] ?? keyMap["default"]; } // Check case-insensitive prefix match const lowerRef = ref.toLowerCase(); const lowerPrefix = prefix.toLowerCase() + "."; if (lowerRef.startsWith(lowerPrefix)) { const key = ref.substring(lowerPrefix.length); return keyMap[key] ?? keyMap["default"]; } // It might already be a direct path (e.g., "textures/entity/sheep/sheep") if (ref.includes("/")) { return ref; } // Try as a key directly if (keyMap[ref]) { return keyMap[ref]; } return keyMap["default"]; } /** * Build a flat Map<string, string[]> from the render controller's nested array definitions. * Converts: { textures: { "Array.skins": ["Texture.a", "Texture.b"] }, geometries: {...} } * To: Map { "Array.skins" → ["Texture.a", "Texture.b"], "Array.geos" → [...] } */ _buildArrayMap(arrays) { if (!arrays) return undefined; const map = new Map(); for (const category of ["textures", "geometries", "materials"]) { const categoryArrays = arrays[category]; if (categoryArrays) { for (const arrayName in categoryArrays) { const entries = categoryArrays[arrayName]; if (entries) { map.set(arrayName, entries); } } } } return map.size > 0 ? map : undefined; } } exports.default = RenderControllerResolver;