@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.cjs CHANGED
@@ -662,12 +662,17 @@ var BehaviorController = class {
662
662
  }
663
663
  /** Selects the weighted transition following the current behavior. */
664
664
  selectNext(environment) {
665
- const next = this.previous?.nextBehaviors ?? [];
666
- const pool = this.previous && this.previous.nextAdditive === false ? next : [...this.spec.behaviors, ...next];
667
- const selected = this.choose(pool, environment);
665
+ const selected = this.choose(this.nextPool(), environment);
668
666
  this.fallbackSelected = selected === void 0;
669
667
  return this.previous = selected ?? this.findFallBehavior();
670
668
  }
669
+ /** Tries a weighted transition from a subset without changing history when none applies. */
670
+ trySelectNext(environment, predicate) {
671
+ const selected = this.choose(this.nextPool().filter(predicate), environment);
672
+ if (!selected) return void 0;
673
+ this.fallbackSelected = false;
674
+ return this.previous = selected;
675
+ }
671
676
  /** Whether the most recent transition had no effective weighted candidate. */
672
677
  usedFallback() {
673
678
  return this.fallbackSelected;
@@ -683,6 +688,10 @@ var BehaviorController = class {
683
688
  const chosen = selectWeighted(applicable, (behavior) => behavior.frequency, this.random);
684
689
  return chosen ? this.resolve(chosen) : void 0;
685
690
  }
691
+ nextPool() {
692
+ const next = this.previous?.nextBehaviors ?? [];
693
+ return this.previous && this.previous.nextAdditive === false ? next : [...this.spec.behaviors, ...next];
694
+ }
686
695
  resolve(behavior) {
687
696
  if (behavior.type !== "Reference") return behavior;
688
697
  const target = this.spec.behaviors.find((candidate) => candidate.type === "Behavior" && candidate.name === behavior.name);
@@ -1637,6 +1646,11 @@ function environmentRectangle(bounds) {
1637
1646
  };
1638
1647
  }
1639
1648
  var PLATFORM_NEARBY_DISTANCE = 400;
1649
+ var PLATFORM_EDGE_TOLERANCE = 2;
1650
+ var IE_BEHAVIOR_NAME_PATTERN = /wall|climb|crawl|壁|登|よじ/i;
1651
+ function isIEBehavior(behavior) {
1652
+ 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));
1653
+ }
1640
1654
  function distanceToRectangle(point, rectangle) {
1641
1655
  const dx = Math.max(rectangle.x - point.x, 0, point.x - rectangle.x - rectangle.width);
1642
1656
  const dy = Math.max(rectangle.y - point.y, 0, point.y - rectangle.y - rectangle.height);
@@ -1756,7 +1770,7 @@ var Mascot = class {
1756
1770
  if (result === "lost-ground") {
1757
1771
  this.state.dragging = false;
1758
1772
  this.actions.cancel();
1759
- this.currentBehavior = this.findFallBehavior();
1773
+ this.currentBehavior = this.selectEdgeBehavior(bounds, platforms);
1760
1774
  if (this.currentBehavior) this.startBehavior(this.createEnvironment(bounds, platforms), bounds, platforms);
1761
1775
  } else if (result === "complete") {
1762
1776
  this.currentBehavior = this.selectNextBehavior(this.createEnvironment(bounds, platforms), bounds);
@@ -1782,14 +1796,39 @@ var Mascot = class {
1782
1796
  findFallBehavior() {
1783
1797
  return this.behavior.force("Fall") ?? this.behavior.force("\u843D\u4E0B\u3059\u308B");
1784
1798
  }
1785
- selectNextBehavior(environment, bounds) {
1799
+ selectNextBehavior(environment, bounds, relocateOnFallback = true) {
1786
1800
  const selected = this.behavior.selectNext(environment);
1787
- if (this.behavior.usedFallback()) {
1801
+ if (relocateOnFallback && this.behavior.usedFallback()) {
1788
1802
  this.state.x = Math.trunc(bounds.x + this.random() * bounds.width);
1789
1803
  this.state.y = bounds.y - 256;
1790
1804
  }
1791
1805
  return selected;
1792
1806
  }
1807
+ selectEdgeBehavior(bounds, platforms) {
1808
+ const original = { x: this.state.x, y: this.state.y };
1809
+ const platform = platforms.find((candidate) => candidate.element === this.activePlatformElement);
1810
+ if (platform) {
1811
+ const left = platform.x;
1812
+ const right = platform.x + platform.width;
1813
+ const top = platform.y;
1814
+ const bottom = platform.y + platform.height;
1815
+ if (Math.abs(this.state.y - top) <= PLATFORM_EDGE_TOLERANCE || Math.abs(this.state.y - bottom) <= PLATFORM_EDGE_TOLERANCE) {
1816
+ if (this.state.x < left) this.state.x = left;
1817
+ else if (this.state.x > right) this.state.x = right;
1818
+ } else if (Math.abs(this.state.x - left) <= PLATFORM_EDGE_TOLERANCE || Math.abs(this.state.x - right) <= PLATFORM_EDGE_TOLERANCE) {
1819
+ if (this.state.y < top) this.state.y = top;
1820
+ else if (this.state.y > bottom) this.state.y = bottom;
1821
+ }
1822
+ }
1823
+ const environment = this.createEnvironment(bounds, platforms);
1824
+ const interruptedBehavior = this.currentBehavior;
1825
+ const selected = this.behavior.trySelectNext(environment, (candidate) => candidate.name !== interruptedBehavior?.name && isIEBehavior(candidate)) ?? this.selectNextBehavior(environment, bounds, false);
1826
+ if (this.behavior.usedFallback() || selected?.name === "Fall" || selected?.name === "\u843D\u4E0B\u3059\u308B") {
1827
+ this.state.x = original.x;
1828
+ this.state.y = original.y;
1829
+ }
1830
+ return selected ?? this.findFallBehavior();
1831
+ }
1793
1832
  createEnvironment(bounds, platforms = this.platforms) {
1794
1833
  const workArea = environmentRectangle(bounds);
1795
1834
  const inactive = environmentRectangle({ x: -100, y: -100, width: 0, height: 0 });
@@ -1820,7 +1859,7 @@ var Mascot = class {
1820
1859
  }
1821
1860
  const anchor = this.state;
1822
1861
  const current = platforms.find((platform) => platform.element === this.activePlatformElement);
1823
- if (current && (isOnTop(anchor, current, 2) || isOnBottom(anchor, current, 2) || isOnLeft(anchor, current, 2) || isOnRight(anchor, current, 2))) return current;
1862
+ 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;
1824
1863
  if (this.state.vy >= 0) {
1825
1864
  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];
1826
1865
  if (landingPlatform) {