minerender 2.1.0-alpha.16 → 2.1.0-alpha.17

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.
@@ -689,16 +689,17 @@ interface BlockStateVariant {
689
689
  y?: number;
690
690
  x?: number;
691
691
  uvlock?: boolean;
692
+ weight?: number;
692
693
  }
693
694
  interface BlockStateMultipart {
694
- when?: MultipartCondition | {
695
- OR: MultipartCondition[];
696
- };
697
- apply?: BlockStateVariant;
698
- }
699
- interface MultipartCondition {
700
- [key: string]: string;
695
+ when?: MultipartCondition;
696
+ apply?: BlockStateVariant | BlockStateVariant[];
701
697
  }
698
+ type MultipartCondition = Record<string, string> | {
699
+ OR: MultipartCondition[];
700
+ } | {
701
+ AND: MultipartCondition[];
702
+ };
702
703
 
703
704
  declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
704
705
  declare const DEFAULT_NAMESPACE = "minecraft";
@@ -689,16 +689,17 @@ interface BlockStateVariant {
689
689
  y?: number;
690
690
  x?: number;
691
691
  uvlock?: boolean;
692
+ weight?: number;
692
693
  }
693
694
  interface BlockStateMultipart {
694
- when?: MultipartCondition | {
695
- OR: MultipartCondition[];
696
- };
697
- apply?: BlockStateVariant;
698
- }
699
- interface MultipartCondition {
700
- [key: string]: string;
695
+ when?: MultipartCondition;
696
+ apply?: BlockStateVariant | BlockStateVariant[];
701
697
  }
698
+ type MultipartCondition = Record<string, string> | {
699
+ OR: MultipartCondition[];
700
+ } | {
701
+ AND: MultipartCondition[];
702
+ };
702
703
 
703
704
  declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
704
705
  declare const DEFAULT_NAMESPACE = "minecraft";
@@ -4368,6 +4368,16 @@ function isModelObject(obj) {
4368
4368
  var import_ts_deepmerge6 = __toESM(require_dist());
4369
4369
  var import_three16 = require("three");
4370
4370
  var p10 = prefix("BlockObject");
4371
+ function matchesCondition(condition, state) {
4372
+ return Object.entries(condition).every(([key, value]) => {
4373
+ if (Array.isArray(value)) {
4374
+ if (key === "OR") return value.some((child) => matchesCondition(child, state));
4375
+ if (key === "AND") return value.every((child) => matchesCondition(child, state));
4376
+ return false;
4377
+ }
4378
+ return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4379
+ });
4380
+ }
4371
4381
  var _BlockObject = class _BlockObject extends SceneObject {
4372
4382
  constructor(blockState, options) {
4373
4383
  super(options);
@@ -4396,15 +4406,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
4396
4406
  if (this.blockState.variants) {
4397
4407
  await this.setState(Object.keys(this.blockState.variants)[0]);
4398
4408
  } else if (this.blockState.multipart) {
4399
- for (let part of this.blockState.multipart) {
4400
- if (part.when && !("OR" in part.when)) {
4401
- const k = Object.keys(part.when)[0];
4402
- if (k) {
4403
- await this.setState(k, part.when[k].split("|")[0]);
4404
- break;
4405
- }
4406
- }
4407
- }
4409
+ const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4410
+ const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4411
+ await this.setState(state);
4408
4412
  }
4409
4413
  }
4410
4414
  } else {
@@ -4464,52 +4468,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
4464
4468
  console.debug(p10, "Missing apply for blockState part", part);
4465
4469
  continue;
4466
4470
  }
4467
- if (!part.when) {
4471
+ if (!part.when || matchesCondition(part.when, state)) {
4468
4472
  out.push(this.getSingleVariant(part.apply));
4469
- } else {
4470
- let matches = true;
4471
- if ("OR" in part.when) {
4472
- const or = part.when.OR;
4473
- let anyMatch = false;
4474
- for (let o of or) {
4475
- for (let k in o) {
4476
- const split = o[k].split("|");
4477
- let m = false;
4478
- for (let s of split) {
4479
- if (`${state[k]}` === `${s}`) {
4480
- m = true;
4481
- break;
4482
- }
4483
- }
4484
- if (m) {
4485
- anyMatch = true;
4486
- break;
4487
- }
4488
- }
4489
- }
4490
- if (!anyMatch) {
4491
- matches = false;
4492
- }
4493
- } else {
4494
- for (let k in part.when) {
4495
- const split = part.when[k].split("|");
4496
- let m = false;
4497
- for (let s of split) {
4498
- if (`${state[k]}` === `${s}`) {
4499
- m = true;
4500
- break;
4501
- }
4502
- }
4503
- if (!m) {
4504
- matches = false;
4505
- break;
4506
- }
4507
- }
4508
- }
4509
- if (matches) {
4510
- const variants = part.apply;
4511
- out.push(this.getSingleVariant(variants));
4512
- }
4513
4473
  }
4514
4474
  }
4515
4475
  }
@@ -4539,11 +4499,21 @@ var _BlockObject = class _BlockObject extends SceneObject {
4539
4499
  }
4540
4500
  }
4541
4501
  getSingleVariant(variants) {
4542
- if (Array.isArray(variants)) {
4543
- return variants[0];
4544
- } else {
4545
- return variants;
4546
- }
4502
+ if (!Array.isArray(variants)) return variants;
4503
+ if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4504
+ const total = variants.reduce((sum, variant) => {
4505
+ const weight = variant.weight ?? 1;
4506
+ if (!Number.isInteger(weight) || weight < 1) {
4507
+ throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4508
+ }
4509
+ return sum + weight;
4510
+ }, 0);
4511
+ let choice = Math.random() * total;
4512
+ for (const variant of variants) {
4513
+ choice -= variant.weight ?? 1;
4514
+ if (choice < 0) return variant;
4515
+ }
4516
+ return variants[variants.length - 1];
4547
4517
  }
4548
4518
  // @deprecated
4549
4519
  async createAVariant(variants, instanceInfo) {