@react-shimeji/core 0.3.1 → 0.3.3

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/dist/index.d.cts CHANGED
@@ -422,11 +422,14 @@ declare class BehaviorController {
422
422
  selectInitial(environment: MascotEnvironment, requestedName?: string): BehaviorDefinition | undefined;
423
423
  /** Selects the weighted transition following the current behavior. */
424
424
  selectNext(environment: MascotEnvironment): BehaviorDefinition | undefined;
425
+ /** Tries a weighted transition from a subset without changing history when none applies. */
426
+ trySelectNext(environment: MascotEnvironment, predicate: (behavior: BehaviorDefinition) => boolean): BehaviorDefinition | undefined;
425
427
  /** Whether the most recent transition had no effective weighted candidate. */
426
428
  usedFallback(): boolean;
427
429
  /** Replaces selection history so an external interaction can force a behavior. */
428
430
  force(name: string): BehaviorDefinition | undefined;
429
431
  private choose;
432
+ private nextPool;
430
433
  private resolve;
431
434
  private findFallBehavior;
432
435
  }
package/dist/index.d.ts CHANGED
@@ -422,11 +422,14 @@ declare class BehaviorController {
422
422
  selectInitial(environment: MascotEnvironment, requestedName?: string): BehaviorDefinition | undefined;
423
423
  /** Selects the weighted transition following the current behavior. */
424
424
  selectNext(environment: MascotEnvironment): BehaviorDefinition | undefined;
425
+ /** Tries a weighted transition from a subset without changing history when none applies. */
426
+ trySelectNext(environment: MascotEnvironment, predicate: (behavior: BehaviorDefinition) => boolean): BehaviorDefinition | undefined;
425
427
  /** Whether the most recent transition had no effective weighted candidate. */
426
428
  usedFallback(): boolean;
427
429
  /** Replaces selection history so an external interaction can force a behavior. */
428
430
  force(name: string): BehaviorDefinition | undefined;
429
431
  private choose;
432
+ private nextPool;
430
433
  private resolve;
431
434
  private findFallBehavior;
432
435
  }
package/dist/index.js CHANGED
@@ -615,12 +615,17 @@ var BehaviorController = class {
615
615
  }
616
616
  /** Selects the weighted transition following the current behavior. */
617
617
  selectNext(environment) {
618
- const next = this.previous?.nextBehaviors ?? [];
619
- const pool = this.previous && this.previous.nextAdditive === false ? next : [...this.spec.behaviors, ...next];
620
- const selected = this.choose(pool, environment);
618
+ const selected = this.choose(this.nextPool(), environment);
621
619
  this.fallbackSelected = selected === void 0;
622
620
  return this.previous = selected ?? this.findFallBehavior();
623
621
  }
622
+ /** Tries a weighted transition from a subset without changing history when none applies. */
623
+ trySelectNext(environment, predicate) {
624
+ const selected = this.choose(this.nextPool().filter(predicate), environment);
625
+ if (!selected) return void 0;
626
+ this.fallbackSelected = false;
627
+ return this.previous = selected;
628
+ }
624
629
  /** Whether the most recent transition had no effective weighted candidate. */
625
630
  usedFallback() {
626
631
  return this.fallbackSelected;
@@ -636,6 +641,10 @@ var BehaviorController = class {
636
641
  const chosen = selectWeighted(applicable, (behavior) => behavior.frequency, this.random);
637
642
  return chosen ? this.resolve(chosen) : void 0;
638
643
  }
644
+ nextPool() {
645
+ const next = this.previous?.nextBehaviors ?? [];
646
+ return this.previous && this.previous.nextAdditive === false ? next : [...this.spec.behaviors, ...next];
647
+ }
639
648
  resolve(behavior) {
640
649
  if (behavior.type !== "Reference") return behavior;
641
650
  const target = this.spec.behaviors.find((candidate) => candidate.type === "Behavior" && candidate.name === behavior.name);
@@ -1590,6 +1599,11 @@ function environmentRectangle(bounds) {
1590
1599
  };
1591
1600
  }
1592
1601
  var PLATFORM_NEARBY_DISTANCE = 400;
1602
+ var PLATFORM_EDGE_TOLERANCE = 2;
1603
+ var IE_BEHAVIOR_NAME_PATTERN = /wall|climb|crawl|壁|登|よじ/i;
1604
+ function isIEBehavior(behavior) {
1605
+ return behavior.conditions.some((condition) => /activeIE/i.test(condition)) || behavior.name.includes("IE") || behavior.name.includes("\uFF29\uFF25") || IE_BEHAVIOR_NAME_PATTERN.test(behavior.name) || behavior.actionName !== void 0 && (behavior.actionName.includes("IE") || behavior.actionName.includes("\uFF29\uFF25") || IE_BEHAVIOR_NAME_PATTERN.test(behavior.actionName));
1606
+ }
1593
1607
  function distanceToRectangle(point, rectangle) {
1594
1608
  const dx = Math.max(rectangle.x - point.x, 0, point.x - rectangle.x - rectangle.width);
1595
1609
  const dy = Math.max(rectangle.y - point.y, 0, point.y - rectangle.y - rectangle.height);
@@ -1709,7 +1723,7 @@ var Mascot = class {
1709
1723
  if (result === "lost-ground") {
1710
1724
  this.state.dragging = false;
1711
1725
  this.actions.cancel();
1712
- this.currentBehavior = this.findFallBehavior();
1726
+ this.currentBehavior = this.selectEdgeBehavior(bounds, platforms);
1713
1727
  if (this.currentBehavior) this.startBehavior(this.createEnvironment(bounds, platforms), bounds, platforms);
1714
1728
  } else if (result === "complete") {
1715
1729
  this.currentBehavior = this.selectNextBehavior(this.createEnvironment(bounds, platforms), bounds);
@@ -1735,14 +1749,39 @@ var Mascot = class {
1735
1749
  findFallBehavior() {
1736
1750
  return this.behavior.force("Fall") ?? this.behavior.force("\u843D\u4E0B\u3059\u308B");
1737
1751
  }
1738
- selectNextBehavior(environment, bounds) {
1752
+ selectNextBehavior(environment, bounds, relocateOnFallback = true) {
1739
1753
  const selected = this.behavior.selectNext(environment);
1740
- if (this.behavior.usedFallback()) {
1754
+ if (relocateOnFallback && this.behavior.usedFallback()) {
1741
1755
  this.state.x = Math.trunc(bounds.x + this.random() * bounds.width);
1742
1756
  this.state.y = bounds.y - 256;
1743
1757
  }
1744
1758
  return selected;
1745
1759
  }
1760
+ selectEdgeBehavior(bounds, platforms) {
1761
+ const original = { x: this.state.x, y: this.state.y };
1762
+ const platform = platforms.find((candidate) => candidate.element === this.activePlatformElement);
1763
+ if (platform) {
1764
+ const left = platform.x;
1765
+ const right = platform.x + platform.width;
1766
+ const top = platform.y;
1767
+ const bottom = platform.y + platform.height;
1768
+ if (Math.abs(this.state.y - top) <= PLATFORM_EDGE_TOLERANCE || Math.abs(this.state.y - bottom) <= PLATFORM_EDGE_TOLERANCE) {
1769
+ if (this.state.x < left) this.state.x = left;
1770
+ else if (this.state.x > right) this.state.x = right;
1771
+ } else if (Math.abs(this.state.x - left) <= PLATFORM_EDGE_TOLERANCE || Math.abs(this.state.x - right) <= PLATFORM_EDGE_TOLERANCE) {
1772
+ if (this.state.y < top) this.state.y = top;
1773
+ else if (this.state.y > bottom) this.state.y = bottom;
1774
+ }
1775
+ }
1776
+ const environment = this.createEnvironment(bounds, platforms);
1777
+ const interruptedBehavior = this.currentBehavior;
1778
+ const selected = this.behavior.trySelectNext(environment, (candidate) => candidate.name !== interruptedBehavior?.name && isIEBehavior(candidate)) ?? this.selectNextBehavior(environment, bounds, false);
1779
+ if (this.behavior.usedFallback() || selected?.name === "Fall" || selected?.name === "\u843D\u4E0B\u3059\u308B") {
1780
+ this.state.x = original.x;
1781
+ this.state.y = original.y;
1782
+ }
1783
+ return selected ?? this.findFallBehavior();
1784
+ }
1746
1785
  createEnvironment(bounds, platforms = this.platforms) {
1747
1786
  const workArea = environmentRectangle(bounds);
1748
1787
  const inactive = environmentRectangle({ x: -100, y: -100, width: 0, height: 0 });
@@ -1773,7 +1812,7 @@ var Mascot = class {
1773
1812
  }
1774
1813
  const anchor = this.state;
1775
1814
  const current = platforms.find((platform) => platform.element === this.activePlatformElement);
1776
- if (current && (isOnTop(anchor, current, 2) || isOnBottom(anchor, current, 2) || isOnLeft(anchor, current, 2) || isOnRight(anchor, current, 2))) return current;
1815
+ if (current && (isOnTop(anchor, current, PLATFORM_EDGE_TOLERANCE) || isOnBottom(anchor, current, PLATFORM_EDGE_TOLERANCE) || isOnLeft(anchor, current, PLATFORM_EDGE_TOLERANCE) || isOnRight(anchor, current, PLATFORM_EDGE_TOLERANCE))) return current;
1777
1816
  if (this.state.vy >= 0) {
1778
1817
  const landingPlatform = platforms.filter((platform) => anchor.x >= platform.x && anchor.x <= platform.x + platform.width && platform.y >= anchor.y - 1).sort((left, right) => left.y - right.y)[0];
1779
1818
  if (landingPlatform) {