@rpgjs/common 5.0.0-alpha.24 → 5.0.0-alpha.26

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.
@@ -1,4 +1,11 @@
1
1
  import { RpgCommonPlayer } from '../Player';
2
+ interface ItemData {
3
+ name: string;
4
+ description: string;
5
+ price: number;
6
+ quantity: number;
7
+ onAdd: (player: RpgCommonPlayer) => void;
8
+ }
2
9
  export declare class Item {
3
10
  id: import('@signe/reactive').WritableSignal<string>;
4
11
  name: import('@signe/reactive').WritableSignal<string>;
@@ -6,5 +13,6 @@ export declare class Item {
6
13
  price: import('@signe/reactive').WritableSignal<number>;
7
14
  quantity: import('@signe/reactive').WritableSignal<number>;
8
15
  onAdd: (player: RpgCommonPlayer) => void;
9
- constructor(data: any);
16
+ constructor(data?: ItemData);
10
17
  }
18
+ export {};
package/dist/index.js CHANGED
@@ -1721,7 +1721,7 @@ var trackDependency = /* @__PURE__ */ __name$1((signal2) => {
1721
1721
  reactiveStore.currentDependencyTracker(signal2);
1722
1722
  }
1723
1723
  }, "trackDependency");
1724
- function signal(defaultValue) {
1724
+ function signal(defaultValue, options) {
1725
1725
  let subject;
1726
1726
  if (Array.isArray(defaultValue)) {
1727
1727
  subject = new ArraySubject(defaultValue);
@@ -1743,12 +1743,21 @@ function signal(defaultValue) {
1743
1743
  return getValue();
1744
1744
  }, "fn");
1745
1745
  fn.set = (value) => {
1746
- if (subject instanceof ArraySubject) {
1747
- subject.items = value;
1748
- } else if (subject instanceof ObjectSubject) {
1749
- subject.obj = value;
1746
+ const currentValue = getValue();
1747
+ let shouldEmit = true;
1748
+ if (options?.equal) {
1749
+ shouldEmit = !options.equal(currentValue, value);
1750
1750
  } else {
1751
- subject.next(value);
1751
+ shouldEmit = currentValue !== value;
1752
+ }
1753
+ if (shouldEmit) {
1754
+ if (subject instanceof ArraySubject) {
1755
+ subject.items = value;
1756
+ } else if (subject instanceof ObjectSubject) {
1757
+ subject.obj = value;
1758
+ } else {
1759
+ subject.next(value);
1760
+ }
1752
1761
  }
1753
1762
  };
1754
1763
  fn._isFrozen = false;
@@ -1805,9 +1814,18 @@ function computed(computeFunction, disposableFn) {
1805
1814
  disposableFn = lastComputedValue;
1806
1815
  }
1807
1816
  reactiveStore.currentDependencyTracker = previousTracker;
1808
- const computedObservable = combineLatest([
1817
+ const observables = [
1809
1818
  ...dependencies
1810
- ].map((signal2) => signal2.observable)).pipe(filter(() => !init), map(() => computeFunction()), finalize(() => disposableFn?.()));
1819
+ ].map((dep) => {
1820
+ if (isComputed(dep) && "dependencies" in dep) {
1821
+ const computedDep = dep;
1822
+ if (computedDep.dependencies.size === 0) {
1823
+ return new BehaviorSubject(computedDep()).asObservable();
1824
+ }
1825
+ }
1826
+ return dep.observable;
1827
+ });
1828
+ const computedObservable = combineLatest(observables).pipe(filter(() => !init), map(() => computeFunction()), finalize(() => disposableFn?.()));
1811
1829
  const fn = /* @__PURE__ */ __name$1(function() {
1812
1830
  trackDependency(fn);
1813
1831
  return lastComputedValue;
@@ -1822,6 +1840,193 @@ function computed(computeFunction, disposableFn) {
1822
1840
  return fn;
1823
1841
  }
1824
1842
  __name$1(computed, "computed");
1843
+ function linkedSignal(computationOrOptions, simpleOptions) {
1844
+ const dependencies = /* @__PURE__ */ new Set();
1845
+ let init = true;
1846
+ let lastComputedValue;
1847
+ let computeFunction;
1848
+ let sourceSignal;
1849
+ let computationFn;
1850
+ let equalFn;
1851
+ let previousValue;
1852
+ let isOverridden = false;
1853
+ let overriddenValue;
1854
+ let depVersion = 0;
1855
+ let overrideDepVersion = null;
1856
+ if (typeof computationOrOptions === "function") {
1857
+ computeFunction = computationOrOptions;
1858
+ equalFn = simpleOptions?.equal;
1859
+ } else {
1860
+ const options = computationOrOptions;
1861
+ sourceSignal = options.source;
1862
+ computationFn = options.computation;
1863
+ equalFn = options.equal;
1864
+ if (typeof sourceSignal === "function" && !isSignal(sourceSignal)) {
1865
+ const sourceFn = sourceSignal;
1866
+ computeFunction = /* @__PURE__ */ __name$1(() => {
1867
+ const sourceValue = sourceFn();
1868
+ if (computationFn.length > 1) {
1869
+ const result = computationFn(sourceValue, previousValue);
1870
+ previousValue = {
1871
+ source: sourceValue,
1872
+ value: result
1873
+ };
1874
+ return result;
1875
+ } else {
1876
+ const result = computationFn(sourceValue);
1877
+ previousValue = {
1878
+ source: sourceValue,
1879
+ value: result
1880
+ };
1881
+ return result;
1882
+ }
1883
+ }, "computeFunction");
1884
+ } else {
1885
+ const source = typeof sourceSignal === "function" ? sourceSignal : sourceSignal;
1886
+ computeFunction = /* @__PURE__ */ __name$1(() => {
1887
+ const sourceValue = source();
1888
+ if (computationFn.length > 1) {
1889
+ const result = computationFn(sourceValue, previousValue);
1890
+ previousValue = {
1891
+ source: sourceValue,
1892
+ value: result
1893
+ };
1894
+ return result;
1895
+ } else {
1896
+ const result = computationFn(sourceValue);
1897
+ previousValue = {
1898
+ source: sourceValue,
1899
+ value: result
1900
+ };
1901
+ return result;
1902
+ }
1903
+ }, "computeFunction");
1904
+ }
1905
+ }
1906
+ const previousTracker = reactiveStore.currentDependencyTracker;
1907
+ reactiveStore.currentDependencyTracker = (signal2) => {
1908
+ dependencies.add(signal2);
1909
+ };
1910
+ if (sourceSignal && typeof sourceSignal === "function" && !isSignal(sourceSignal)) {
1911
+ lastComputedValue = computeFunction();
1912
+ } else if (sourceSignal && isSignal(sourceSignal)) {
1913
+ dependencies.add(sourceSignal);
1914
+ lastComputedValue = computeFunction();
1915
+ } else {
1916
+ lastComputedValue = computeFunction();
1917
+ }
1918
+ reactiveStore.currentDependencyTracker = previousTracker;
1919
+ const subject = new BehaviorSubject(lastComputedValue);
1920
+ const observables = [
1921
+ ...dependencies
1922
+ ].map((dep) => {
1923
+ if (isComputed(dep) && "dependencies" in dep) {
1924
+ const computedDep = dep;
1925
+ if (computedDep.dependencies.size === 0) {
1926
+ return new BehaviorSubject(computedDep()).asObservable();
1927
+ }
1928
+ }
1929
+ return dep.observable;
1930
+ });
1931
+ let linkedObservable;
1932
+ if (observables.length > 0) {
1933
+ linkedObservable = combineLatest(observables).pipe(filter(() => !init), map(() => {
1934
+ const computed2 = computeFunction();
1935
+ if (equalFn) {
1936
+ if (!equalFn(lastComputedValue, computed2)) {
1937
+ lastComputedValue = computed2;
1938
+ isOverridden = false;
1939
+ }
1940
+ } else {
1941
+ if (lastComputedValue !== computed2) {
1942
+ lastComputedValue = computed2;
1943
+ isOverridden = false;
1944
+ }
1945
+ }
1946
+ return lastComputedValue;
1947
+ }));
1948
+ } else {
1949
+ linkedObservable = subject.asObservable().pipe(filter(() => !init));
1950
+ }
1951
+ const fn = /* @__PURE__ */ __name$1(function() {
1952
+ trackDependency(fn);
1953
+ if (isOverridden && dependencies.size > 0) {
1954
+ if (overrideDepVersion !== depVersion) {
1955
+ const computed2 = computeFunction();
1956
+ isOverridden = false;
1957
+ overriddenValue = void 0;
1958
+ lastComputedValue = computed2;
1959
+ overrideDepVersion = null;
1960
+ return computed2;
1961
+ }
1962
+ return overriddenValue;
1963
+ }
1964
+ if (isOverridden) {
1965
+ return overriddenValue;
1966
+ }
1967
+ if (dependencies.size === 0) {
1968
+ const computed2 = computeFunction();
1969
+ lastComputedValue = computed2;
1970
+ }
1971
+ return lastComputedValue;
1972
+ }, "fn");
1973
+ fn.observable = new Observable((observer) => {
1974
+ const depSubscription = linkedObservable.subscribe((value) => {
1975
+ if (dependencies.size > 0) {
1976
+ depVersion++;
1977
+ isOverridden = false;
1978
+ overrideDepVersion = null;
1979
+ lastComputedValue = value;
1980
+ } else {
1981
+ lastComputedValue = value;
1982
+ }
1983
+ observer.next(value);
1984
+ });
1985
+ let subjectSubscription;
1986
+ if (dependencies.size === 0) {
1987
+ subjectSubscription = subject.pipe(filter(() => !init)).subscribe((value) => {
1988
+ observer.next(value);
1989
+ });
1990
+ }
1991
+ observer.next(lastComputedValue);
1992
+ return () => {
1993
+ depSubscription.unsubscribe();
1994
+ if (subjectSubscription) {
1995
+ subjectSubscription.unsubscribe();
1996
+ }
1997
+ };
1998
+ });
1999
+ fn.subscription = fn.observable.subscribe(() => {
2000
+ });
2001
+ fn.dependencies = dependencies;
2002
+ fn._subject = subject;
2003
+ fn.set = (value) => {
2004
+ if (!isOverridden) {
2005
+ overrideDepVersion = depVersion;
2006
+ if (computationFn && sourceSignal) {
2007
+ const sourceValue = untracked(() => {
2008
+ if (typeof sourceSignal === "function") {
2009
+ const source = sourceSignal;
2010
+ return isSignal(source) ? source() : sourceSignal();
2011
+ }
2012
+ return sourceSignal();
2013
+ });
2014
+ previousValue = {
2015
+ source: sourceValue,
2016
+ value
2017
+ };
2018
+ }
2019
+ }
2020
+ isOverridden = true;
2021
+ overriddenValue = value;
2022
+ lastComputedValue = value;
2023
+ subject.next(value);
2024
+ };
2025
+ reactiveStore.currentSubscriptionsTracker?.(fn.subscription);
2026
+ init = false;
2027
+ return fn;
2028
+ }
2029
+ __name$1(linkedSignal, "linkedSignal");
1825
2030
  function untracked(fn) {
1826
2031
  const prevDepTracker = reactiveStore.currentDependencyTracker;
1827
2032
  const prevSubTracker = reactiveStore.currentSubscriptionsTracker;
@@ -2237,10 +2442,10 @@ class Item {
2237
2442
  this.quantity = signal(1);
2238
2443
  this.onAdd = () => {
2239
2444
  };
2240
- this.description.set(data.description);
2241
- this.price.set(data.price);
2242
- this.name.set(data.name);
2243
- this.onAdd = data.onAdd?.bind(this) ?? (() => {
2445
+ this.description.set(data?.description ?? "");
2446
+ this.price.set(data?.price ?? 0);
2447
+ this.name.set(data?.name ?? "");
2448
+ this.onAdd = data?.onAdd?.bind(this) ?? (() => {
2244
2449
  });
2245
2450
  }
2246
2451
  }
@@ -2317,7 +2522,7 @@ class RpgCommonPlayer {
2317
2522
  this.hpSignal = signal(0);
2318
2523
  this.spSignal = signal(0);
2319
2524
  this._exp = signal(0);
2320
- this._level = signal(0);
2525
+ this._level = signal(1);
2321
2526
  this._class = signal({});
2322
2527
  this.items = signal([]);
2323
2528
  this.equipments = signal([]);
@@ -9277,6 +9482,10 @@ class RpgCommonMap {
9277
9482
  });
9278
9483
  this.moveManager = new MovementManager(() => this.physic);
9279
9484
  this.speedScalar = 50;
9485
+ // Default speed scalar for movement
9486
+ // World Maps properties
9487
+ this.tileWidth = 32;
9488
+ this.tileHeight = 32;
9280
9489
  this.physicsAccumulatorMs = 0;
9281
9490
  this.physicsSyncDepth = 0;
9282
9491
  /**
@@ -9331,6 +9540,88 @@ class RpgCommonMap {
9331
9540
  get isStandalone() {
9332
9541
  return typeof window !== "undefined";
9333
9542
  }
9543
+ /**
9544
+ * Get the width of the map in pixels
9545
+ *
9546
+ * @returns The width of the map in pixels, or 0 if not loaded
9547
+ *
9548
+ * @example
9549
+ * ```ts
9550
+ * const width = map.widthPx;
9551
+ * console.log(`Map width: ${width}px`);
9552
+ * ```
9553
+ */
9554
+ get widthPx() {
9555
+ return this.data()?.width ?? 0;
9556
+ }
9557
+ /**
9558
+ * Get the height of the map in pixels
9559
+ *
9560
+ * @returns The height of the map in pixels, or 0 if not loaded
9561
+ *
9562
+ * @example
9563
+ * ```ts
9564
+ * const height = map.heightPx;
9565
+ * console.log(`Map height: ${height}px`);
9566
+ * ```
9567
+ */
9568
+ get heightPx() {
9569
+ return this.data()?.height ?? 0;
9570
+ }
9571
+ /**
9572
+ * Get the unique identifier of the map
9573
+ *
9574
+ * @returns The map ID, or empty string if not loaded
9575
+ *
9576
+ * @example
9577
+ * ```ts
9578
+ * const mapId = map.id;
9579
+ * console.log(`Current map: ${mapId}`);
9580
+ * ```
9581
+ */
9582
+ get id() {
9583
+ return this.data()?.id ?? "";
9584
+ }
9585
+ /**
9586
+ * Get the X position of this map in the world coordinate system
9587
+ *
9588
+ * This is used when maps are part of a larger world map. The world position
9589
+ * indicates where this map is located relative to other maps.
9590
+ *
9591
+ * @returns The X position in world coordinates, or 0 if not in a world
9592
+ *
9593
+ * @example
9594
+ * ```ts
9595
+ * const worldX = map.worldX;
9596
+ * console.log(`Map is at world position (${worldX}, ${map.worldY})`);
9597
+ * ```
9598
+ */
9599
+ get worldX() {
9600
+ const worldMaps = this.getWorldMapsManager?.();
9601
+ if (!worldMaps) return 0;
9602
+ const mapId = this.id.startsWith("map-") ? this.id.slice(4) : this.id;
9603
+ return worldMaps.getMapInfo(mapId)?.worldX ?? 0;
9604
+ }
9605
+ /**
9606
+ * Get the Y position of this map in the world coordinate system
9607
+ *
9608
+ * This is used when maps are part of a larger world map. The world position
9609
+ * indicates where this map is located relative to other maps.
9610
+ *
9611
+ * @returns The Y position in world coordinates, or 0 if not in a world
9612
+ *
9613
+ * @example
9614
+ * ```ts
9615
+ * const worldY = map.worldY;
9616
+ * console.log(`Map is at world position (${map.worldX}, ${worldY})`);
9617
+ * ```
9618
+ */
9619
+ get worldY() {
9620
+ const worldMaps = this.getWorldMapsManager?.();
9621
+ if (!worldMaps) return 0;
9622
+ const mapId = this.id.startsWith("map-") ? this.id.slice(4) : this.id;
9623
+ return worldMaps.getMapInfo(mapId)?.worldY ?? 0;
9624
+ }
9334
9625
  /**
9335
9626
  * Clear all physics content and reset to initial state
9336
9627
  *
@@ -10422,17 +10713,19 @@ class WorldMapsManager {
10422
10713
  if (typeof search === "number") {
10423
10714
  const src = map;
10424
10715
  return maps.filter((m) => {
10425
- const horizontallyOverlaps = Math.max(src.worldX, m.worldX) < Math.min(src.worldX + src.width, m.worldX + m.width);
10426
- const verticallyOverlaps = Math.max(src.worldY, m.worldY) < Math.min(src.worldY + src.height, m.worldY + m.height);
10716
+ const horizontallyOverlapsOrTouches = Math.max(src.worldX, m.worldX) <= Math.min(src.worldX + src.widthPx, m.worldX + m.widthPx);
10717
+ const verticallyOverlapsOrTouches = Math.max(src.worldY, m.worldY) <= Math.min(src.worldY + src.heightPx, m.worldY + m.heightPx);
10718
+ const marginLeftRight = src.tileWidth / 2;
10719
+ const marginTopDown = src.tileHeight / 2;
10427
10720
  switch (search) {
10428
10721
  case 0:
10429
- return verticallyOverlaps && m.worldY + m.height === src.worldY;
10722
+ return verticallyOverlapsOrTouches && m.worldY + m.heightPx - marginTopDown === src.worldY;
10430
10723
  case 1:
10431
- return verticallyOverlaps && m.worldY === src.worldY + src.height;
10724
+ return verticallyOverlapsOrTouches && m.worldY + marginTopDown === src.worldY + src.heightPx;
10432
10725
  case 2:
10433
- return horizontallyOverlaps && m.worldX + m.width === src.worldX;
10726
+ return horizontallyOverlapsOrTouches && m.worldX + m.widthPx - marginLeftRight === src.worldX;
10434
10727
  case 3:
10435
- return horizontallyOverlaps && m.worldX === src.worldX + src.width;
10728
+ return horizontallyOverlapsOrTouches && m.worldX + marginLeftRight === src.worldX + src.widthPx;
10436
10729
  default:
10437
10730
  return false;
10438
10731
  }
@@ -10440,7 +10733,7 @@ class WorldMapsManager {
10440
10733
  }
10441
10734
  if ("x" in search && "y" in search) {
10442
10735
  const found = maps.find(
10443
- (m) => search.x >= m.worldX && search.x < m.worldX + m.width && search.y >= m.worldY && search.y < m.worldY + m.height
10736
+ (m) => search.x >= m.worldX && search.x < m.worldX + m.widthPx && search.y >= m.worldY && search.y < m.worldY + m.heightPx
10444
10737
  );
10445
10738
  return found ? [found] : [];
10446
10739
  }
@@ -10448,9 +10741,9 @@ class WorldMapsManager {
10448
10741
  const { minX, minY, maxX, maxY } = search;
10449
10742
  return maps.filter((m) => {
10450
10743
  const aLeft = m.worldX;
10451
- const aRight = m.worldX + m.width;
10744
+ const aRight = m.worldX + m.widthPx;
10452
10745
  const aTop = m.worldY;
10453
- const aBottom = m.worldY + m.height;
10746
+ const aBottom = m.worldY + m.heightPx;
10454
10747
  const bLeft = minX;
10455
10748
  const bRight = maxX;
10456
10749
  const bTop = minY;