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.
@@ -690,16 +690,17 @@ interface BlockStateVariant {
690
690
  y?: number;
691
691
  x?: number;
692
692
  uvlock?: boolean;
693
+ weight?: number;
693
694
  }
694
695
  interface BlockStateMultipart {
695
- when?: MultipartCondition | {
696
- OR: MultipartCondition[];
697
- };
698
- apply?: BlockStateVariant;
699
- }
700
- interface MultipartCondition {
701
- [key: string]: string;
696
+ when?: MultipartCondition;
697
+ apply?: BlockStateVariant | BlockStateVariant[];
702
698
  }
699
+ type MultipartCondition = Record<string, string> | {
700
+ OR: MultipartCondition[];
701
+ } | {
702
+ AND: MultipartCondition[];
703
+ };
703
704
 
704
705
  declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
705
706
  declare const DEFAULT_NAMESPACE = "minecraft";
@@ -690,16 +690,17 @@ interface BlockStateVariant {
690
690
  y?: number;
691
691
  x?: number;
692
692
  uvlock?: boolean;
693
+ weight?: number;
693
694
  }
694
695
  interface BlockStateMultipart {
695
- when?: MultipartCondition | {
696
- OR: MultipartCondition[];
697
- };
698
- apply?: BlockStateVariant;
699
- }
700
- interface MultipartCondition {
701
- [key: string]: string;
696
+ when?: MultipartCondition;
697
+ apply?: BlockStateVariant | BlockStateVariant[];
702
698
  }
699
+ type MultipartCondition = Record<string, string> | {
700
+ OR: MultipartCondition[];
701
+ } | {
702
+ AND: MultipartCondition[];
703
+ };
703
704
 
704
705
  declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
705
706
  declare const DEFAULT_NAMESPACE = "minecraft";
@@ -4409,6 +4409,16 @@ function isModelObject(obj) {
4409
4409
  var import_ts_deepmerge6 = __toESM(require_dist());
4410
4410
  var import_three16 = require("three");
4411
4411
  var p10 = prefix("BlockObject");
4412
+ function matchesCondition(condition, state) {
4413
+ return Object.entries(condition).every(([key, value]) => {
4414
+ if (Array.isArray(value)) {
4415
+ if (key === "OR") return value.some((child) => matchesCondition(child, state));
4416
+ if (key === "AND") return value.every((child) => matchesCondition(child, state));
4417
+ return false;
4418
+ }
4419
+ return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
4420
+ });
4421
+ }
4412
4422
  var BlockObject = class _BlockObject extends SceneObject {
4413
4423
  constructor(blockState, options) {
4414
4424
  super(options);
@@ -4442,15 +4452,9 @@ var BlockObject = class _BlockObject extends SceneObject {
4442
4452
  if (this.blockState.variants) {
4443
4453
  await this.setState(Object.keys(this.blockState.variants)[0]);
4444
4454
  } else if (this.blockState.multipart) {
4445
- for (let part of this.blockState.multipart) {
4446
- if (part.when && !("OR" in part.when)) {
4447
- const k = Object.keys(part.when)[0];
4448
- if (k) {
4449
- await this.setState(k, part.when[k].split("|")[0]);
4450
- break;
4451
- }
4452
- }
4453
- }
4455
+ const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
4456
+ const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
4457
+ await this.setState(state);
4454
4458
  }
4455
4459
  }
4456
4460
  } else {
@@ -4510,52 +4514,8 @@ var BlockObject = class _BlockObject extends SceneObject {
4510
4514
  console.debug(p10, "Missing apply for blockState part", part);
4511
4515
  continue;
4512
4516
  }
4513
- if (!part.when) {
4517
+ if (!part.when || matchesCondition(part.when, state)) {
4514
4518
  out.push(this.getSingleVariant(part.apply));
4515
- } else {
4516
- let matches = true;
4517
- if ("OR" in part.when) {
4518
- const or = part.when.OR;
4519
- let anyMatch = false;
4520
- for (let o of or) {
4521
- for (let k in o) {
4522
- const split = o[k].split("|");
4523
- let m = false;
4524
- for (let s of split) {
4525
- if (`${state[k]}` === `${s}`) {
4526
- m = true;
4527
- break;
4528
- }
4529
- }
4530
- if (m) {
4531
- anyMatch = true;
4532
- break;
4533
- }
4534
- }
4535
- }
4536
- if (!anyMatch) {
4537
- matches = false;
4538
- }
4539
- } else {
4540
- for (let k in part.when) {
4541
- const split = part.when[k].split("|");
4542
- let m = false;
4543
- for (let s of split) {
4544
- if (`${state[k]}` === `${s}`) {
4545
- m = true;
4546
- break;
4547
- }
4548
- }
4549
- if (!m) {
4550
- matches = false;
4551
- break;
4552
- }
4553
- }
4554
- }
4555
- if (matches) {
4556
- const variants = part.apply;
4557
- out.push(this.getSingleVariant(variants));
4558
- }
4559
4519
  }
4560
4520
  }
4561
4521
  }
@@ -4585,11 +4545,21 @@ var BlockObject = class _BlockObject extends SceneObject {
4585
4545
  }
4586
4546
  }
4587
4547
  getSingleVariant(variants) {
4588
- if (Array.isArray(variants)) {
4589
- return variants[0];
4590
- } else {
4591
- return variants;
4592
- }
4548
+ if (!Array.isArray(variants)) return variants;
4549
+ if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
4550
+ const total = variants.reduce((sum, variant) => {
4551
+ const weight = variant.weight ?? 1;
4552
+ if (!Number.isInteger(weight) || weight < 1) {
4553
+ throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
4554
+ }
4555
+ return sum + weight;
4556
+ }, 0);
4557
+ let choice = Math.random() * total;
4558
+ for (const variant of variants) {
4559
+ choice -= variant.weight ?? 1;
4560
+ if (choice < 0) return variant;
4561
+ }
4562
+ return variants[variants.length - 1];
4593
4563
  }
4594
4564
  // @deprecated
4595
4565
  async createAVariant(variants, instanceInfo) {