@almadar/ui 5.104.0 → 5.105.0
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/avl/index.cjs +154 -80
- package/dist/avl/index.js +154 -80
- package/dist/components/game/2d/molecules/Canvas2D.d.ts +1 -1
- package/dist/components/game/2d/molecules/SideCanvas2D.d.ts +36 -0
- package/dist/components/game/3d/atoms/EventMarker3D.d.ts +17 -0
- package/dist/components/game/3d/atoms/SpriteBillboard3D.d.ts +18 -0
- package/dist/components/game/3d/index.cjs +539 -496
- package/dist/components/game/3d/index.js +367 -324
- package/dist/components/game/3d/molecules/FeatureMesh3D.d.ts +21 -0
- package/dist/components/game/3d/molecules/GameCamera3D.d.ts +35 -0
- package/dist/components/game/3d/molecules/Lighting3D.d.ts +10 -2
- package/dist/components/game/3d/molecules/SideScene3D.d.ts +31 -0
- package/dist/components/game/3d/molecules/TileMesh3D.d.ts +28 -0
- package/dist/components/game/3d/molecules/UnitMesh3D.d.ts +29 -0
- package/dist/components/game/shared/game3dTheme.d.ts +55 -0
- package/dist/components/game/shared/isometric.d.ts +38 -0
- package/dist/components/game/shared/isometricTypes.d.ts +4 -0
- package/dist/components/index.cjs +146 -79
- package/dist/components/index.js +150 -83
- package/dist/providers/index.cjs +154 -80
- package/dist/providers/index.js +154 -80
- package/dist/runtime/index.cjs +154 -80
- package/dist/runtime/index.js +154 -80
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React10 from 'react';
|
|
2
|
+
import React10__default, { forwardRef, useRef, useEffect, useImperativeHandle, useState, useMemo, useCallback, createContext, useContext, Component, useSyncExternalStore, useReducer } from 'react';
|
|
3
3
|
import { useThree, useFrame, Canvas, useLoader } from '@react-three/fiber';
|
|
4
4
|
import * as THREE6 from 'three';
|
|
5
5
|
import { Vector3, QuadraticBezierCurve3, MathUtils, Quaternion } from 'three';
|
|
@@ -149,6 +149,10 @@ function Lighting3D({
|
|
|
149
149
|
shadows = true,
|
|
150
150
|
shadowMapSize = 2048,
|
|
151
151
|
shadowCameraSize = 20,
|
|
152
|
+
shadowBias = -1e-3,
|
|
153
|
+
shadowNormalBias,
|
|
154
|
+
shadowCameraNear = 0.1,
|
|
155
|
+
shadowCameraFar = 100,
|
|
152
156
|
showHelpers = false
|
|
153
157
|
}) {
|
|
154
158
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -165,9 +169,10 @@ function Lighting3D({
|
|
|
165
169
|
"shadow-camera-right": shadowCameraSize,
|
|
166
170
|
"shadow-camera-top": shadowCameraSize,
|
|
167
171
|
"shadow-camera-bottom": -shadowCameraSize,
|
|
168
|
-
"shadow-camera-near":
|
|
169
|
-
"shadow-camera-far":
|
|
170
|
-
"shadow-bias":
|
|
172
|
+
"shadow-camera-near": shadowCameraNear,
|
|
173
|
+
"shadow-camera-far": shadowCameraFar,
|
|
174
|
+
"shadow-bias": shadowBias,
|
|
175
|
+
"shadow-normalBias": shadowNormalBias
|
|
171
176
|
}
|
|
172
177
|
),
|
|
173
178
|
/* @__PURE__ */ jsx(
|
|
@@ -1561,6 +1566,171 @@ function useGameCanvas3DEvents(options) {
|
|
|
1561
1566
|
};
|
|
1562
1567
|
}
|
|
1563
1568
|
|
|
1569
|
+
// components/game/shared/game3dTheme.ts
|
|
1570
|
+
var TERRAIN_COLORS_3D = {
|
|
1571
|
+
base: 8421504,
|
|
1572
|
+
water: 4491468,
|
|
1573
|
+
grass: 4500036,
|
|
1574
|
+
sand: 14535816,
|
|
1575
|
+
rock: 8947848,
|
|
1576
|
+
snow: 15658734
|
|
1577
|
+
};
|
|
1578
|
+
var HIGHLIGHT_EMISSIVE_3D = {
|
|
1579
|
+
selected: 4473924,
|
|
1580
|
+
attackTarget: 4456448,
|
|
1581
|
+
validMove: 17408,
|
|
1582
|
+
hovered: 2236962,
|
|
1583
|
+
none: 0
|
|
1584
|
+
};
|
|
1585
|
+
var FACTION_COLORS_3D = {
|
|
1586
|
+
player: 4491519,
|
|
1587
|
+
enemy: 16729156,
|
|
1588
|
+
default: 16777028
|
|
1589
|
+
};
|
|
1590
|
+
var SELECTION_RING_COLOR_3D = "#ffff00";
|
|
1591
|
+
var HEALTHBAR_3D = {
|
|
1592
|
+
bg: 3355443,
|
|
1593
|
+
/** fill color thresholds: fraction > key → color */
|
|
1594
|
+
high: 4500036,
|
|
1595
|
+
// fraction > 0.5
|
|
1596
|
+
mid: 11184708,
|
|
1597
|
+
// fraction > 0.25
|
|
1598
|
+
low: 16729156,
|
|
1599
|
+
// else
|
|
1600
|
+
width: 0.5
|
|
1601
|
+
};
|
|
1602
|
+
function healthbarFill3D(fraction) {
|
|
1603
|
+
if (fraction > 0.5) return HEALTHBAR_3D.high;
|
|
1604
|
+
if (fraction > 0.25) return HEALTHBAR_3D.mid;
|
|
1605
|
+
return HEALTHBAR_3D.low;
|
|
1606
|
+
}
|
|
1607
|
+
var TREE_COLORS_3D = {
|
|
1608
|
+
trunk: 9127187,
|
|
1609
|
+
foliage: 2263842
|
|
1610
|
+
};
|
|
1611
|
+
var ROCK_COLOR_3D = 8421504;
|
|
1612
|
+
var EVENT_COLORS_3D = {
|
|
1613
|
+
hit: 16733508,
|
|
1614
|
+
damage: 16733508,
|
|
1615
|
+
attack: 16746564,
|
|
1616
|
+
heal: 4513126,
|
|
1617
|
+
pickup: 16763955,
|
|
1618
|
+
score: 16763955,
|
|
1619
|
+
death: 11154227,
|
|
1620
|
+
win: 6750088,
|
|
1621
|
+
lose: 16737894,
|
|
1622
|
+
default: 16777215
|
|
1623
|
+
};
|
|
1624
|
+
var SIDE_PLATFORM_COLORS_3D = {
|
|
1625
|
+
ground: 5999678,
|
|
1626
|
+
platform: 9132587,
|
|
1627
|
+
hazard: 13386820,
|
|
1628
|
+
goal: 4491468,
|
|
1629
|
+
default: 8947848
|
|
1630
|
+
};
|
|
1631
|
+
var SIDE_PLAYER_COLOR_3D = "#4488ff";
|
|
1632
|
+
var GRID_COLORS_3D = {
|
|
1633
|
+
cell: "#444444",
|
|
1634
|
+
section: "#666666"
|
|
1635
|
+
};
|
|
1636
|
+
var DEFAULT_BACKGROUND_3D = "#1a1a2e";
|
|
1637
|
+
function TileMesh3D({
|
|
1638
|
+
tile,
|
|
1639
|
+
position,
|
|
1640
|
+
model,
|
|
1641
|
+
isSelected,
|
|
1642
|
+
isHovered,
|
|
1643
|
+
isValidMove,
|
|
1644
|
+
isAttackTarget,
|
|
1645
|
+
onTileClick,
|
|
1646
|
+
onTileHover
|
|
1647
|
+
}) {
|
|
1648
|
+
const color = tile.color ?? TERRAIN_COLORS_3D[tile.type ?? ""] ?? TERRAIN_COLORS_3D.base;
|
|
1649
|
+
let emissive = HIGHLIGHT_EMISSIVE_3D.none;
|
|
1650
|
+
if (isSelected) emissive = HIGHLIGHT_EMISSIVE_3D.selected;
|
|
1651
|
+
else if (isAttackTarget) emissive = HIGHLIGHT_EMISSIVE_3D.attackTarget;
|
|
1652
|
+
else if (isValidMove) emissive = HIGHLIGHT_EMISSIVE_3D.validMove;
|
|
1653
|
+
else if (isHovered) emissive = HIGHLIGHT_EMISSIVE_3D.hovered;
|
|
1654
|
+
if (model?.url) {
|
|
1655
|
+
return /* @__PURE__ */ jsx(
|
|
1656
|
+
"group",
|
|
1657
|
+
{
|
|
1658
|
+
position,
|
|
1659
|
+
onClick: (e) => onTileClick(tile, e),
|
|
1660
|
+
onPointerEnter: (e) => onTileHover(tile, e),
|
|
1661
|
+
onPointerLeave: (e) => onTileHover(null, e),
|
|
1662
|
+
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
1663
|
+
children: /* @__PURE__ */ jsx(
|
|
1664
|
+
ModelLoader,
|
|
1665
|
+
{
|
|
1666
|
+
url: model.url,
|
|
1667
|
+
scale: 0.95,
|
|
1668
|
+
rotation: [0, tile.rotation ?? 0, 0],
|
|
1669
|
+
fallbackGeometry: "box",
|
|
1670
|
+
castShadow: true,
|
|
1671
|
+
receiveShadow: true
|
|
1672
|
+
}
|
|
1673
|
+
)
|
|
1674
|
+
}
|
|
1675
|
+
);
|
|
1676
|
+
}
|
|
1677
|
+
return /* @__PURE__ */ jsxs(
|
|
1678
|
+
"mesh",
|
|
1679
|
+
{
|
|
1680
|
+
position,
|
|
1681
|
+
onClick: (e) => onTileClick(tile, e),
|
|
1682
|
+
onPointerEnter: (e) => onTileHover(tile, e),
|
|
1683
|
+
onPointerLeave: (e) => onTileHover(null, e),
|
|
1684
|
+
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
1685
|
+
children: [
|
|
1686
|
+
/* @__PURE__ */ jsx("boxGeometry", { args: [0.95, 0.2, 0.95] }),
|
|
1687
|
+
/* @__PURE__ */ jsx("meshStandardMaterial", { color, emissive })
|
|
1688
|
+
]
|
|
1689
|
+
}
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
function SpriteBillboard3D({
|
|
1693
|
+
sheetUrl,
|
|
1694
|
+
resolveFrame,
|
|
1695
|
+
height = 1.2
|
|
1696
|
+
}) {
|
|
1697
|
+
const texture = useLoader(THREE6.TextureLoader, sheetUrl);
|
|
1698
|
+
const meshRef = useRef(null);
|
|
1699
|
+
const matRef = useRef(null);
|
|
1700
|
+
const [aspect, setAspect] = useState(1);
|
|
1701
|
+
useFrame(() => {
|
|
1702
|
+
const frame = resolveFrame();
|
|
1703
|
+
if (!frame || !texture.image) return;
|
|
1704
|
+
const imgW = texture.image.width;
|
|
1705
|
+
const imgH = texture.image.height;
|
|
1706
|
+
if (!imgW || !imgH) return;
|
|
1707
|
+
texture.repeat.set((frame.flipX ? -1 : 1) * (frame.sw / imgW), frame.sh / imgH);
|
|
1708
|
+
texture.offset.set(
|
|
1709
|
+
frame.flipX ? (frame.sx + frame.sw) / imgW : frame.sx / imgW,
|
|
1710
|
+
1 - (frame.sy + frame.sh) / imgH
|
|
1711
|
+
);
|
|
1712
|
+
texture.magFilter = THREE6.NearestFilter;
|
|
1713
|
+
texture.minFilter = THREE6.NearestFilter;
|
|
1714
|
+
texture.needsUpdate = true;
|
|
1715
|
+
const nextAspect = frame.sw / frame.sh;
|
|
1716
|
+
if (Math.abs(nextAspect - aspect) > 1e-3) setAspect(nextAspect);
|
|
1717
|
+
if (matRef.current) matRef.current.needsUpdate = true;
|
|
1718
|
+
});
|
|
1719
|
+
return /* @__PURE__ */ jsxs("mesh", { ref: meshRef, position: [0, height / 2, 0], children: [
|
|
1720
|
+
/* @__PURE__ */ jsx("planeGeometry", { args: [height * aspect, height] }),
|
|
1721
|
+
/* @__PURE__ */ jsx(
|
|
1722
|
+
"meshBasicMaterial",
|
|
1723
|
+
{
|
|
1724
|
+
ref: matRef,
|
|
1725
|
+
map: texture,
|
|
1726
|
+
transparent: true,
|
|
1727
|
+
alphaTest: 0.1,
|
|
1728
|
+
side: THREE6.DoubleSide
|
|
1729
|
+
}
|
|
1730
|
+
)
|
|
1731
|
+
] });
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1564
1734
|
// components/game/shared/spriteAnimation.ts
|
|
1565
1735
|
function resolveSheetDirection(facing) {
|
|
1566
1736
|
switch (facing) {
|
|
@@ -1673,274 +1843,11 @@ function useUnitSpriteAtlas(units) {
|
|
|
1673
1843
|
}, [units]);
|
|
1674
1844
|
return { sheetUrls, resolveUnitFrame, pendingCount };
|
|
1675
1845
|
}
|
|
1676
|
-
function cn(...inputs) {
|
|
1677
|
-
return twMerge(clsx(inputs));
|
|
1678
|
-
}
|
|
1679
|
-
var DEFAULT_GRID_CONFIG = {
|
|
1680
|
-
cellSize: 1,
|
|
1681
|
-
offsetX: 0,
|
|
1682
|
-
offsetZ: 0
|
|
1683
|
-
};
|
|
1684
|
-
function CameraController({
|
|
1685
|
-
onCameraChange
|
|
1686
|
-
}) {
|
|
1687
|
-
const { camera } = useThree();
|
|
1688
|
-
useEffect(() => {
|
|
1689
|
-
if (onCameraChange) {
|
|
1690
|
-
onCameraChange({
|
|
1691
|
-
x: camera.position.x,
|
|
1692
|
-
y: camera.position.y,
|
|
1693
|
-
z: camera.position.z
|
|
1694
|
-
});
|
|
1695
|
-
}
|
|
1696
|
-
}, [camera.position, onCameraChange]);
|
|
1697
|
-
return null;
|
|
1698
|
-
}
|
|
1699
|
-
function UnitSpriteBillboard({
|
|
1700
|
-
sheetUrl,
|
|
1701
|
-
resolveFrame,
|
|
1702
|
-
height = 1.2
|
|
1703
|
-
}) {
|
|
1704
|
-
const texture = useLoader(THREE6.TextureLoader, sheetUrl);
|
|
1705
|
-
const meshRef = useRef(null);
|
|
1706
|
-
const matRef = useRef(null);
|
|
1707
|
-
const [aspect, setAspect] = useState(1);
|
|
1708
|
-
useFrame(() => {
|
|
1709
|
-
const frame = resolveFrame();
|
|
1710
|
-
if (!frame || !texture.image) return;
|
|
1711
|
-
const imgW = texture.image.width;
|
|
1712
|
-
const imgH = texture.image.height;
|
|
1713
|
-
if (!imgW || !imgH) return;
|
|
1714
|
-
texture.repeat.set((frame.flipX ? -1 : 1) * (frame.sw / imgW), frame.sh / imgH);
|
|
1715
|
-
texture.offset.set(
|
|
1716
|
-
frame.flipX ? (frame.sx + frame.sw) / imgW : frame.sx / imgW,
|
|
1717
|
-
1 - (frame.sy + frame.sh) / imgH
|
|
1718
|
-
);
|
|
1719
|
-
texture.magFilter = THREE6.NearestFilter;
|
|
1720
|
-
texture.minFilter = THREE6.NearestFilter;
|
|
1721
|
-
texture.needsUpdate = true;
|
|
1722
|
-
const nextAspect = frame.sw / frame.sh;
|
|
1723
|
-
if (Math.abs(nextAspect - aspect) > 1e-3) setAspect(nextAspect);
|
|
1724
|
-
if (matRef.current) matRef.current.needsUpdate = true;
|
|
1725
|
-
});
|
|
1726
|
-
return /* @__PURE__ */ jsxs("mesh", { ref: meshRef, position: [0, height / 2, 0], children: [
|
|
1727
|
-
/* @__PURE__ */ jsx("planeGeometry", { args: [height * aspect, height] }),
|
|
1728
|
-
/* @__PURE__ */ jsx(
|
|
1729
|
-
"meshBasicMaterial",
|
|
1730
|
-
{
|
|
1731
|
-
ref: matRef,
|
|
1732
|
-
map: texture,
|
|
1733
|
-
transparent: true,
|
|
1734
|
-
alphaTest: 0.1,
|
|
1735
|
-
side: THREE6.DoubleSide
|
|
1736
|
-
}
|
|
1737
|
-
)
|
|
1738
|
-
] });
|
|
1739
|
-
}
|
|
1740
|
-
function FollowCamera({
|
|
1741
|
-
target,
|
|
1742
|
-
offset
|
|
1743
|
-
}) {
|
|
1744
|
-
const { camera } = useThree();
|
|
1745
|
-
const look = useRef(new THREE6.Vector3(target[0], target[1], target[2]));
|
|
1746
|
-
const goal = useRef(new THREE6.Vector3());
|
|
1747
|
-
useFrame((_, delta) => {
|
|
1748
|
-
const t = Math.min(1, delta * 5);
|
|
1749
|
-
goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
|
|
1750
|
-
camera.position.lerp(goal.current, t);
|
|
1751
|
-
look.current.lerp(goal.current.set(target[0], target[1], target[2]), t);
|
|
1752
|
-
camera.lookAt(look.current);
|
|
1753
|
-
});
|
|
1754
|
-
return null;
|
|
1755
|
-
}
|
|
1756
|
-
function LerpedGroup({
|
|
1757
|
-
target,
|
|
1758
|
-
enabled,
|
|
1759
|
-
children
|
|
1760
|
-
}) {
|
|
1761
|
-
const ref = useRef(null);
|
|
1762
|
-
const goal = useRef(new THREE6.Vector3());
|
|
1763
|
-
useFrame((_, delta) => {
|
|
1764
|
-
const g = ref.current;
|
|
1765
|
-
if (!g) return;
|
|
1766
|
-
goal.current.set(target[0], target[1], target[2]);
|
|
1767
|
-
if (enabled) g.position.lerp(goal.current, Math.min(1, delta * 10));
|
|
1768
|
-
else g.position.copy(goal.current);
|
|
1769
|
-
});
|
|
1770
|
-
return /* @__PURE__ */ jsx("group", { ref, position: target, children });
|
|
1771
|
-
}
|
|
1772
|
-
var SIDE_PLATFORM_COLORS = {
|
|
1773
|
-
ground: "#5b8c3e",
|
|
1774
|
-
platform: "#8b5a2b",
|
|
1775
|
-
hazard: "#cc4444",
|
|
1776
|
-
goal: "#4488cc"
|
|
1777
|
-
};
|
|
1778
|
-
function SideScene({
|
|
1779
|
-
player,
|
|
1780
|
-
platforms,
|
|
1781
|
-
worldHeight,
|
|
1782
|
-
ppu,
|
|
1783
|
-
playerSprite,
|
|
1784
|
-
tileSprites,
|
|
1785
|
-
interpolate,
|
|
1786
|
-
features = [],
|
|
1787
|
-
events = [],
|
|
1788
|
-
assetManifest
|
|
1789
|
-
}) {
|
|
1790
|
-
const pw = player.width ?? 32;
|
|
1791
|
-
const ph = player.height ?? 48;
|
|
1792
|
-
const playerPos = [
|
|
1793
|
-
(player.x + pw / 2) / ppu,
|
|
1794
|
-
(worldHeight - player.y - ph) / ppu,
|
|
1795
|
-
0
|
|
1796
|
-
];
|
|
1797
|
-
const playerH = Math.max(ph / ppu, 0.5);
|
|
1798
|
-
return /* @__PURE__ */ jsxs("group", { children: [
|
|
1799
|
-
platforms.map((p, i) => {
|
|
1800
|
-
const platformType = p.type ?? "platform";
|
|
1801
|
-
const model = tileSprites?.[platformType]?.url;
|
|
1802
|
-
const topY = (worldHeight - p.y) / ppu;
|
|
1803
|
-
if (model) {
|
|
1804
|
-
const cells = Math.max(1, Math.round(p.width / ppu));
|
|
1805
|
-
const x0 = p.x / ppu;
|
|
1806
|
-
return /* @__PURE__ */ jsx("group", { children: Array.from({ length: cells }, (_, c) => /* @__PURE__ */ jsx("group", { position: [x0 + c + 0.5, topY - 0.475, 0], children: /* @__PURE__ */ jsx(ModelLoader, { url: model, scale: 0.95, fallbackGeometry: "box", castShadow: true, receiveShadow: true }) }, c)) }, `plat-${i}`);
|
|
1807
|
-
}
|
|
1808
|
-
return /* @__PURE__ */ jsxs(
|
|
1809
|
-
"mesh",
|
|
1810
|
-
{
|
|
1811
|
-
position: [(p.x + p.width / 2) / ppu, topY - p.height / 2 / ppu, 0],
|
|
1812
|
-
children: [
|
|
1813
|
-
/* @__PURE__ */ jsx("boxGeometry", { args: [p.width / ppu, p.height / ppu, 1] }),
|
|
1814
|
-
/* @__PURE__ */ jsx("meshStandardMaterial", { color: SIDE_PLATFORM_COLORS[platformType] ?? "#888888" })
|
|
1815
|
-
]
|
|
1816
|
-
},
|
|
1817
|
-
`plat-${i}`
|
|
1818
|
-
);
|
|
1819
|
-
}),
|
|
1820
|
-
features.map((feature, i) => {
|
|
1821
|
-
const model = feature.assetUrl ?? assetManifest?.features?.[feature.type];
|
|
1822
|
-
const fx = feature.x / ppu;
|
|
1823
|
-
const fy = (worldHeight - feature.y) / ppu;
|
|
1824
|
-
if (!model?.url) return null;
|
|
1825
|
-
return /* @__PURE__ */ jsx("group", { position: [fx, fy, 0], children: /* @__PURE__ */ jsx(ModelLoader, { url: model.url, scale: 0.6, tint: feature.color, fallbackGeometry: "sphere", castShadow: true }) }, feature.id ?? `sfeat-${i}`);
|
|
1826
|
-
}),
|
|
1827
|
-
events.map((ev, i) => /* @__PURE__ */ jsx(
|
|
1828
|
-
EventMarker,
|
|
1829
|
-
{
|
|
1830
|
-
event: ev,
|
|
1831
|
-
position: [ev.x / ppu, (worldHeight - (ev.y ?? 0)) / ppu + 0.8, 0.2]
|
|
1832
|
-
},
|
|
1833
|
-
ev.id ?? `sev-${i}`
|
|
1834
|
-
)),
|
|
1835
|
-
/* @__PURE__ */ jsx(LerpedGroup, { target: playerPos, enabled: interpolate, children: playerSprite?.url ? /* @__PURE__ */ jsx("group", { position: [0, playerH / 2, 0], children: /* @__PURE__ */ jsx(
|
|
1836
|
-
ModelLoader,
|
|
1837
|
-
{
|
|
1838
|
-
url: playerSprite.url,
|
|
1839
|
-
scale: playerH,
|
|
1840
|
-
rotation: [0, player.facingRight ? 90 : -90, 0],
|
|
1841
|
-
animation: player.animation ?? "idle",
|
|
1842
|
-
fallbackGeometry: "box",
|
|
1843
|
-
castShadow: true
|
|
1844
|
-
}
|
|
1845
|
-
) }) : /* @__PURE__ */ jsxs("mesh", { position: [0, playerH / 2, 0], children: [
|
|
1846
|
-
/* @__PURE__ */ jsx("capsuleGeometry", { args: [playerH * 0.25, playerH * 0.5, 4, 8] }),
|
|
1847
|
-
/* @__PURE__ */ jsx("meshStandardMaterial", { color: "#4488ff" })
|
|
1848
|
-
] }) })
|
|
1849
|
-
] });
|
|
1850
|
-
}
|
|
1851
1846
|
var UNIT_BASE_MODEL_SCALE = 0.5;
|
|
1852
1847
|
var UNIT_BASE_BILLBOARD_HEIGHT = 1.2;
|
|
1853
1848
|
var UNIT_BASE_PRIMITIVE_RADIUS = 0.3;
|
|
1854
|
-
var
|
|
1855
|
-
|
|
1856
|
-
hit: "#ff5544",
|
|
1857
|
-
damage: "#ff5544",
|
|
1858
|
-
attack: "#ff8844",
|
|
1859
|
-
heal: "#44dd66",
|
|
1860
|
-
pickup: "#ffcc33",
|
|
1861
|
-
score: "#ffcc33",
|
|
1862
|
-
death: "#aa3333",
|
|
1863
|
-
win: "#66ff88",
|
|
1864
|
-
lose: "#ff6666"
|
|
1865
|
-
};
|
|
1866
|
-
function EventMarker({
|
|
1867
|
-
event,
|
|
1868
|
-
position
|
|
1869
|
-
}) {
|
|
1870
|
-
return /* @__PURE__ */ jsx(Billboard, { position, children: /* @__PURE__ */ jsx(
|
|
1871
|
-
Text,
|
|
1872
|
-
{
|
|
1873
|
-
fontSize: 0.32,
|
|
1874
|
-
color: EVENT_COLORS[event.type] ?? "#ffffff",
|
|
1875
|
-
outlineWidth: 0.02,
|
|
1876
|
-
outlineColor: "#000000",
|
|
1877
|
-
anchorX: "center",
|
|
1878
|
-
anchorY: "middle",
|
|
1879
|
-
children: event.message ?? event.type
|
|
1880
|
-
}
|
|
1881
|
-
) });
|
|
1882
|
-
}
|
|
1883
|
-
function DefaultTile({
|
|
1884
|
-
tile,
|
|
1885
|
-
position,
|
|
1886
|
-
model,
|
|
1887
|
-
isSelected,
|
|
1888
|
-
isHovered,
|
|
1889
|
-
isValidMove,
|
|
1890
|
-
isAttackTarget,
|
|
1891
|
-
onTileClick,
|
|
1892
|
-
onTileHover
|
|
1893
|
-
}) {
|
|
1894
|
-
let color = 8421504;
|
|
1895
|
-
if (tile.type === "water") color = 4491468;
|
|
1896
|
-
else if (tile.type === "grass") color = 4500036;
|
|
1897
|
-
else if (tile.type === "sand") color = 14535816;
|
|
1898
|
-
else if (tile.type === "rock") color = 8947848;
|
|
1899
|
-
else if (tile.type === "snow") color = 15658734;
|
|
1900
|
-
let emissive = 0;
|
|
1901
|
-
if (isSelected) emissive = 4473924;
|
|
1902
|
-
else if (isAttackTarget) emissive = 4456448;
|
|
1903
|
-
else if (isValidMove) emissive = 17408;
|
|
1904
|
-
else if (isHovered) emissive = 2236962;
|
|
1905
|
-
if (model?.url) {
|
|
1906
|
-
return /* @__PURE__ */ jsx(
|
|
1907
|
-
"group",
|
|
1908
|
-
{
|
|
1909
|
-
position,
|
|
1910
|
-
onClick: (e) => onTileClick(tile, e),
|
|
1911
|
-
onPointerEnter: (e) => onTileHover(tile, e),
|
|
1912
|
-
onPointerLeave: (e) => onTileHover(null, e),
|
|
1913
|
-
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
1914
|
-
children: /* @__PURE__ */ jsx(
|
|
1915
|
-
ModelLoader,
|
|
1916
|
-
{
|
|
1917
|
-
url: model.url,
|
|
1918
|
-
scale: 0.95,
|
|
1919
|
-
rotation: [0, tile.rotation ?? 0, 0],
|
|
1920
|
-
fallbackGeometry: "box",
|
|
1921
|
-
castShadow: true,
|
|
1922
|
-
receiveShadow: true
|
|
1923
|
-
}
|
|
1924
|
-
)
|
|
1925
|
-
}
|
|
1926
|
-
);
|
|
1927
|
-
}
|
|
1928
|
-
return /* @__PURE__ */ jsxs(
|
|
1929
|
-
"mesh",
|
|
1930
|
-
{
|
|
1931
|
-
position,
|
|
1932
|
-
onClick: (e) => onTileClick(tile, e),
|
|
1933
|
-
onPointerEnter: (e) => onTileHover(tile, e),
|
|
1934
|
-
onPointerLeave: (e) => onTileHover(null, e),
|
|
1935
|
-
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
1936
|
-
children: [
|
|
1937
|
-
/* @__PURE__ */ jsx("boxGeometry", { args: [0.95, 0.2, 0.95] }),
|
|
1938
|
-
/* @__PURE__ */ jsx("meshStandardMaterial", { color, emissive })
|
|
1939
|
-
]
|
|
1940
|
-
}
|
|
1941
|
-
);
|
|
1942
|
-
}
|
|
1943
|
-
function DefaultUnit({
|
|
1849
|
+
var HEALTHBAR_HEIGHT = 0.05;
|
|
1850
|
+
function UnitMesh3D({
|
|
1944
1851
|
unit,
|
|
1945
1852
|
position,
|
|
1946
1853
|
model,
|
|
@@ -1950,7 +1857,7 @@ function DefaultUnit({
|
|
|
1950
1857
|
resolveUnitFrame,
|
|
1951
1858
|
onUnitClick
|
|
1952
1859
|
}) {
|
|
1953
|
-
const color = unit.
|
|
1860
|
+
const color = unit.tint ?? FACTION_COLORS_3D[unit.faction ?? ""] ?? FACTION_COLORS_3D.default;
|
|
1954
1861
|
const hasAtlas = unitAtlasUrl(unit) !== null;
|
|
1955
1862
|
const initialFrame = hasAtlas ? resolveUnitFrame(unit.id) : null;
|
|
1956
1863
|
const modelScale = UNIT_BASE_MODEL_SCALE * unitScale * cellSize;
|
|
@@ -1965,12 +1872,12 @@ function DefaultUnit({
|
|
|
1965
1872
|
children: [
|
|
1966
1873
|
isSelected && /* @__PURE__ */ jsxs("mesh", { position: [0, 0.05, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
1967
1874
|
/* @__PURE__ */ jsx("ringGeometry", { args: [0.4, 0.5, 32] }),
|
|
1968
|
-
/* @__PURE__ */ jsx("meshBasicMaterial", { color:
|
|
1875
|
+
/* @__PURE__ */ jsx("meshBasicMaterial", { color: SELECTION_RING_COLOR_3D, transparent: true, opacity: 0.8 })
|
|
1969
1876
|
] }),
|
|
1970
1877
|
hasAtlas && initialFrame ? (
|
|
1971
1878
|
/* Animated sprite-sheet billboard — single cropped frame, by state */
|
|
1972
1879
|
/* @__PURE__ */ jsx(Billboard, { children: /* @__PURE__ */ jsx(
|
|
1973
|
-
|
|
1880
|
+
SpriteBillboard3D,
|
|
1974
1881
|
{
|
|
1975
1882
|
sheetUrl: initialFrame.sheetUrl,
|
|
1976
1883
|
resolveFrame: () => resolveUnitFrame(unit.id),
|
|
@@ -2006,26 +1913,21 @@ function DefaultUnit({
|
|
|
2006
1913
|
] })
|
|
2007
1914
|
] }),
|
|
2008
1915
|
unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxs("group", { position: [0, billboardHeight, 0], children: [
|
|
2009
|
-
/* @__PURE__ */ jsxs("mesh", { position: [-0.
|
|
2010
|
-
/* @__PURE__ */ jsx("planeGeometry", { args: [
|
|
2011
|
-
/* @__PURE__ */ jsx("meshBasicMaterial", { color:
|
|
1916
|
+
/* @__PURE__ */ jsxs("mesh", { position: [-0.5 / 2, 0, 0], children: [
|
|
1917
|
+
/* @__PURE__ */ jsx("planeGeometry", { args: [HEALTHBAR_3D.width, HEALTHBAR_HEIGHT] }),
|
|
1918
|
+
/* @__PURE__ */ jsx("meshBasicMaterial", { color: HEALTHBAR_3D.bg })
|
|
2012
1919
|
] }),
|
|
2013
1920
|
/* @__PURE__ */ jsxs(
|
|
2014
1921
|
"mesh",
|
|
2015
1922
|
{
|
|
2016
1923
|
position: [
|
|
2017
|
-
-0.
|
|
1924
|
+
-0.5 / 2 + HEALTHBAR_3D.width * (unit.health / unit.maxHealth) / 2,
|
|
2018
1925
|
0,
|
|
2019
1926
|
0.01
|
|
2020
1927
|
],
|
|
2021
1928
|
children: [
|
|
2022
|
-
/* @__PURE__ */ jsx("planeGeometry", { args: [
|
|
2023
|
-
/* @__PURE__ */ jsx(
|
|
2024
|
-
"meshBasicMaterial",
|
|
2025
|
-
{
|
|
2026
|
-
color: unit.health / unit.maxHealth > 0.5 ? 4500036 : unit.health / unit.maxHealth > 0.25 ? 11184708 : 16729156
|
|
2027
|
-
}
|
|
2028
|
-
)
|
|
1929
|
+
/* @__PURE__ */ jsx("planeGeometry", { args: [HEALTHBAR_3D.width * (unit.health / unit.maxHealth), HEALTHBAR_HEIGHT] }),
|
|
1930
|
+
/* @__PURE__ */ jsx("meshBasicMaterial", { color: healthbarFill3D(unit.health / unit.maxHealth) })
|
|
2029
1931
|
]
|
|
2030
1932
|
}
|
|
2031
1933
|
)
|
|
@@ -2034,7 +1936,7 @@ function DefaultUnit({
|
|
|
2034
1936
|
}
|
|
2035
1937
|
);
|
|
2036
1938
|
}
|
|
2037
|
-
function
|
|
1939
|
+
function FeatureMesh3D({
|
|
2038
1940
|
feature,
|
|
2039
1941
|
position,
|
|
2040
1942
|
model,
|
|
@@ -2064,11 +1966,11 @@ function DefaultFeature({
|
|
|
2064
1966
|
children: [
|
|
2065
1967
|
/* @__PURE__ */ jsxs("mesh", { position: [0, 0.4, 0], children: [
|
|
2066
1968
|
/* @__PURE__ */ jsx("cylinderGeometry", { args: [0.1, 0.15, 0.8, 6] }),
|
|
2067
|
-
/* @__PURE__ */ jsx("meshStandardMaterial", { color:
|
|
1969
|
+
/* @__PURE__ */ jsx("meshStandardMaterial", { color: TREE_COLORS_3D.trunk })
|
|
2068
1970
|
] }),
|
|
2069
1971
|
/* @__PURE__ */ jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
2070
1972
|
/* @__PURE__ */ jsx("coneGeometry", { args: [0.5, 0.8, 8] }),
|
|
2071
|
-
/* @__PURE__ */ jsx("meshStandardMaterial", { color:
|
|
1973
|
+
/* @__PURE__ */ jsx("meshStandardMaterial", { color: TREE_COLORS_3D.foliage })
|
|
2072
1974
|
] })
|
|
2073
1975
|
]
|
|
2074
1976
|
}
|
|
@@ -2083,13 +1985,156 @@ function DefaultFeature({
|
|
|
2083
1985
|
userData: { type: "feature", featureId: feature.id },
|
|
2084
1986
|
children: [
|
|
2085
1987
|
/* @__PURE__ */ jsx("dodecahedronGeometry", { args: [0.3, 0] }),
|
|
2086
|
-
/* @__PURE__ */ jsx("meshStandardMaterial", { color:
|
|
1988
|
+
/* @__PURE__ */ jsx("meshStandardMaterial", { color: ROCK_COLOR_3D })
|
|
2087
1989
|
]
|
|
2088
1990
|
}
|
|
2089
1991
|
);
|
|
2090
1992
|
}
|
|
2091
1993
|
return null;
|
|
2092
1994
|
}
|
|
1995
|
+
function CameraController3D({
|
|
1996
|
+
onCameraChange
|
|
1997
|
+
}) {
|
|
1998
|
+
const { camera } = useThree();
|
|
1999
|
+
useEffect(() => {
|
|
2000
|
+
if (onCameraChange) {
|
|
2001
|
+
onCameraChange({
|
|
2002
|
+
x: camera.position.x,
|
|
2003
|
+
y: camera.position.y,
|
|
2004
|
+
z: camera.position.z
|
|
2005
|
+
});
|
|
2006
|
+
}
|
|
2007
|
+
}, [camera.position, onCameraChange]);
|
|
2008
|
+
return null;
|
|
2009
|
+
}
|
|
2010
|
+
function FollowCamera3D({
|
|
2011
|
+
target,
|
|
2012
|
+
offset
|
|
2013
|
+
}) {
|
|
2014
|
+
const { camera } = useThree();
|
|
2015
|
+
const look = useRef(new THREE6.Vector3(target[0], target[1], target[2]));
|
|
2016
|
+
const goal = useRef(new THREE6.Vector3());
|
|
2017
|
+
useFrame((_, delta) => {
|
|
2018
|
+
const t = Math.min(1, delta * 5);
|
|
2019
|
+
goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
|
|
2020
|
+
camera.position.lerp(goal.current, t);
|
|
2021
|
+
look.current.lerp(goal.current.set(target[0], target[1], target[2]), t);
|
|
2022
|
+
camera.lookAt(look.current);
|
|
2023
|
+
});
|
|
2024
|
+
return null;
|
|
2025
|
+
}
|
|
2026
|
+
function LerpedGroup3D({
|
|
2027
|
+
target,
|
|
2028
|
+
enabled,
|
|
2029
|
+
children
|
|
2030
|
+
}) {
|
|
2031
|
+
const ref = useRef(null);
|
|
2032
|
+
const goal = useRef(new THREE6.Vector3());
|
|
2033
|
+
useFrame((_, delta) => {
|
|
2034
|
+
const g = ref.current;
|
|
2035
|
+
if (!g) return;
|
|
2036
|
+
goal.current.set(target[0], target[1], target[2]);
|
|
2037
|
+
if (enabled) g.position.lerp(goal.current, Math.min(1, delta * 10));
|
|
2038
|
+
else g.position.copy(goal.current);
|
|
2039
|
+
});
|
|
2040
|
+
return /* @__PURE__ */ jsx("group", { ref, position: target, children });
|
|
2041
|
+
}
|
|
2042
|
+
function EventMarker3D({ event, position }) {
|
|
2043
|
+
return /* @__PURE__ */ jsx(Billboard, { position, children: /* @__PURE__ */ jsx(
|
|
2044
|
+
Text,
|
|
2045
|
+
{
|
|
2046
|
+
fontSize: 0.32,
|
|
2047
|
+
color: EVENT_COLORS_3D[event.type] ?? EVENT_COLORS_3D.default,
|
|
2048
|
+
outlineWidth: 0.02,
|
|
2049
|
+
outlineColor: "#000000",
|
|
2050
|
+
anchorX: "center",
|
|
2051
|
+
anchorY: "middle",
|
|
2052
|
+
children: event.message ?? event.type
|
|
2053
|
+
}
|
|
2054
|
+
) });
|
|
2055
|
+
}
|
|
2056
|
+
function SideScene3D({
|
|
2057
|
+
player,
|
|
2058
|
+
platforms,
|
|
2059
|
+
worldHeight,
|
|
2060
|
+
ppu,
|
|
2061
|
+
playerSprite,
|
|
2062
|
+
tileSprites,
|
|
2063
|
+
interpolate,
|
|
2064
|
+
features = [],
|
|
2065
|
+
events = [],
|
|
2066
|
+
assetManifest
|
|
2067
|
+
}) {
|
|
2068
|
+
const pw = player.width ?? 32;
|
|
2069
|
+
const ph = player.height ?? 48;
|
|
2070
|
+
const playerPos = [
|
|
2071
|
+
(player.x + pw / 2) / ppu,
|
|
2072
|
+
(worldHeight - player.y - ph) / ppu,
|
|
2073
|
+
0
|
|
2074
|
+
];
|
|
2075
|
+
const playerH = Math.max(ph / ppu, 0.5);
|
|
2076
|
+
return /* @__PURE__ */ jsxs("group", { children: [
|
|
2077
|
+
platforms.map((p, i) => {
|
|
2078
|
+
const platformType = p.type ?? "platform";
|
|
2079
|
+
const model = tileSprites?.[platformType]?.url;
|
|
2080
|
+
const topY = (worldHeight - p.y) / ppu;
|
|
2081
|
+
if (model) {
|
|
2082
|
+
const cells = Math.max(1, Math.round(p.width / ppu));
|
|
2083
|
+
const x0 = p.x / ppu;
|
|
2084
|
+
return /* @__PURE__ */ jsx("group", { children: Array.from({ length: cells }, (_, c) => /* @__PURE__ */ jsx("group", { position: [x0 + c + 0.5, topY - 0.475, 0], children: /* @__PURE__ */ jsx(ModelLoader, { url: model, scale: 0.95, fallbackGeometry: "box", castShadow: true, receiveShadow: true }) }, c)) }, `plat-${i}`);
|
|
2085
|
+
}
|
|
2086
|
+
return /* @__PURE__ */ jsxs(
|
|
2087
|
+
"mesh",
|
|
2088
|
+
{
|
|
2089
|
+
position: [(p.x + p.width / 2) / ppu, topY - p.height / 2 / ppu, 0],
|
|
2090
|
+
children: [
|
|
2091
|
+
/* @__PURE__ */ jsx("boxGeometry", { args: [p.width / ppu, p.height / ppu, 1] }),
|
|
2092
|
+
/* @__PURE__ */ jsx("meshStandardMaterial", { color: SIDE_PLATFORM_COLORS_3D[platformType] ?? SIDE_PLATFORM_COLORS_3D.default })
|
|
2093
|
+
]
|
|
2094
|
+
},
|
|
2095
|
+
`plat-${i}`
|
|
2096
|
+
);
|
|
2097
|
+
}),
|
|
2098
|
+
features.map((feature, i) => {
|
|
2099
|
+
const model = feature.assetUrl ?? assetManifest?.features?.[feature.type];
|
|
2100
|
+
const fx = feature.x / ppu;
|
|
2101
|
+
const fy = (worldHeight - feature.y) / ppu;
|
|
2102
|
+
if (!model?.url) return null;
|
|
2103
|
+
return /* @__PURE__ */ jsx("group", { position: [fx, fy, 0], children: /* @__PURE__ */ jsx(ModelLoader, { url: model.url, scale: 0.6, tint: feature.color, fallbackGeometry: "sphere", castShadow: true }) }, feature.id ?? `sfeat-${i}`);
|
|
2104
|
+
}),
|
|
2105
|
+
events.map((ev, i) => /* @__PURE__ */ jsx(
|
|
2106
|
+
EventMarker3D,
|
|
2107
|
+
{
|
|
2108
|
+
event: ev,
|
|
2109
|
+
position: [ev.x / ppu, (worldHeight - (ev.y ?? 0)) / ppu + 0.8, 0.2]
|
|
2110
|
+
},
|
|
2111
|
+
ev.id ?? `sev-${i}`
|
|
2112
|
+
)),
|
|
2113
|
+
/* @__PURE__ */ jsx(LerpedGroup3D, { target: playerPos, enabled: interpolate, children: playerSprite?.url ? /* @__PURE__ */ jsx("group", { position: [0, playerH / 2, 0], children: /* @__PURE__ */ jsx(
|
|
2114
|
+
ModelLoader,
|
|
2115
|
+
{
|
|
2116
|
+
url: playerSprite.url,
|
|
2117
|
+
scale: playerH,
|
|
2118
|
+
rotation: [0, player.facingRight ? 90 : -90, 0],
|
|
2119
|
+
animation: player.animation ?? "idle",
|
|
2120
|
+
fallbackGeometry: "box",
|
|
2121
|
+
castShadow: true
|
|
2122
|
+
}
|
|
2123
|
+
) }) : /* @__PURE__ */ jsxs("mesh", { position: [0, playerH / 2, 0], children: [
|
|
2124
|
+
/* @__PURE__ */ jsx("capsuleGeometry", { args: [playerH * 0.25, playerH * 0.5, 4, 8] }),
|
|
2125
|
+
/* @__PURE__ */ jsx("meshStandardMaterial", { color: SIDE_PLAYER_COLOR_3D })
|
|
2126
|
+
] }) })
|
|
2127
|
+
] });
|
|
2128
|
+
}
|
|
2129
|
+
function cn(...inputs) {
|
|
2130
|
+
return twMerge(clsx(inputs));
|
|
2131
|
+
}
|
|
2132
|
+
var DEFAULT_GRID_CONFIG = {
|
|
2133
|
+
cellSize: 1,
|
|
2134
|
+
offsetX: 0,
|
|
2135
|
+
offsetZ: 0
|
|
2136
|
+
};
|
|
2137
|
+
var TILE_TOP_OFFSET = 0.1;
|
|
2093
2138
|
var GameCanvas3D = forwardRef(
|
|
2094
2139
|
({
|
|
2095
2140
|
tiles = [],
|
|
@@ -2103,7 +2148,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2103
2148
|
showTileInfo = false,
|
|
2104
2149
|
overlay = "default",
|
|
2105
2150
|
shadows = true,
|
|
2106
|
-
backgroundColor =
|
|
2151
|
+
backgroundColor = DEFAULT_BACKGROUND_3D,
|
|
2107
2152
|
onTileClick,
|
|
2108
2153
|
onUnitClick,
|
|
2109
2154
|
onFeatureClick,
|
|
@@ -2437,27 +2482,25 @@ var GameCanvas3D = forwardRef(
|
|
|
2437
2482
|
}
|
|
2438
2483
|
},
|
|
2439
2484
|
children: [
|
|
2440
|
-
/* @__PURE__ */ jsx(
|
|
2485
|
+
/* @__PURE__ */ jsx(CameraController3D, { onCameraChange: eventHandlers.handleCameraChange }),
|
|
2441
2486
|
(cameraMode === "follow" || cameraMode === "chase") && /* @__PURE__ */ jsx(
|
|
2442
|
-
|
|
2487
|
+
FollowCamera3D,
|
|
2443
2488
|
{
|
|
2444
2489
|
target: followTarget,
|
|
2445
2490
|
offset: followOffset
|
|
2446
2491
|
}
|
|
2447
2492
|
),
|
|
2448
|
-
/* @__PURE__ */ jsx("ambientLight", { intensity: 0.6 }),
|
|
2449
2493
|
/* @__PURE__ */ jsx(
|
|
2450
|
-
|
|
2494
|
+
Lighting3D,
|
|
2451
2495
|
{
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2496
|
+
shadows,
|
|
2497
|
+
shadowBias: -4e-4,
|
|
2498
|
+
shadowNormalBias: 0.04,
|
|
2499
|
+
shadowCameraSize: 5,
|
|
2500
|
+
shadowCameraNear: 0.5,
|
|
2501
|
+
shadowCameraFar: 500
|
|
2458
2502
|
}
|
|
2459
2503
|
),
|
|
2460
|
-
/* @__PURE__ */ jsx("hemisphereLight", { intensity: 0.3, color: "#87ceeb", groundColor: "#362d1d" }),
|
|
2461
2504
|
showGrid && /* @__PURE__ */ jsx(
|
|
2462
2505
|
Grid,
|
|
2463
2506
|
{
|
|
@@ -2472,10 +2515,10 @@ var GameCanvas3D = forwardRef(
|
|
|
2472
2515
|
],
|
|
2473
2516
|
cellSize: 1,
|
|
2474
2517
|
cellThickness: 1,
|
|
2475
|
-
cellColor:
|
|
2518
|
+
cellColor: GRID_COLORS_3D.cell,
|
|
2476
2519
|
sectionSize: 5,
|
|
2477
2520
|
sectionThickness: 1.5,
|
|
2478
|
-
sectionColor:
|
|
2521
|
+
sectionColor: GRID_COLORS_3D.section,
|
|
2479
2522
|
fadeDistance: 50,
|
|
2480
2523
|
fadeStrength: 1
|
|
2481
2524
|
}
|
|
@@ -2483,7 +2526,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2483
2526
|
player ? (
|
|
2484
2527
|
/* Side-scroller mode — LOLO-owned pixel space mapped to world units */
|
|
2485
2528
|
/* @__PURE__ */ jsx(
|
|
2486
|
-
|
|
2529
|
+
SideScene3D,
|
|
2487
2530
|
{
|
|
2488
2531
|
player,
|
|
2489
2532
|
platforms,
|
|
@@ -2509,7 +2552,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2509
2552
|
return /* @__PURE__ */ jsx(CustomTileRenderer, { tile, position }, key);
|
|
2510
2553
|
}
|
|
2511
2554
|
return /* @__PURE__ */ jsx(
|
|
2512
|
-
|
|
2555
|
+
TileMesh3D,
|
|
2513
2556
|
{
|
|
2514
2557
|
tile,
|
|
2515
2558
|
position,
|
|
@@ -2535,7 +2578,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2535
2578
|
return /* @__PURE__ */ jsx(CustomFeatureRenderer, { feature, position }, key);
|
|
2536
2579
|
}
|
|
2537
2580
|
return /* @__PURE__ */ jsx(
|
|
2538
|
-
|
|
2581
|
+
FeatureMesh3D,
|
|
2539
2582
|
{
|
|
2540
2583
|
feature,
|
|
2541
2584
|
position,
|
|
@@ -2551,8 +2594,8 @@ var GameCanvas3D = forwardRef(
|
|
|
2551
2594
|
unit.z ?? unit.y ?? unit.position?.y ?? 0,
|
|
2552
2595
|
(unit.elevation ?? 0) + TILE_TOP_OFFSET
|
|
2553
2596
|
);
|
|
2554
|
-
return /* @__PURE__ */ jsx(
|
|
2555
|
-
|
|
2597
|
+
return /* @__PURE__ */ jsx(LerpedGroup3D, { target: position, enabled: interpolateUnits, children: CustomUnitRenderer ? /* @__PURE__ */ jsx(CustomUnitRenderer, { unit, position: [0, 0, 0] }) : /* @__PURE__ */ jsx(
|
|
2598
|
+
UnitMesh3D,
|
|
2556
2599
|
{
|
|
2557
2600
|
unit,
|
|
2558
2601
|
position: [0, 0, 0],
|
|
@@ -2568,7 +2611,7 @@ var GameCanvas3D = forwardRef(
|
|
|
2568
2611
|
events.map((ev, i) => {
|
|
2569
2612
|
const position = gridToWorld2(ev.x, ev.z ?? ev.y ?? 0, 0);
|
|
2570
2613
|
return /* @__PURE__ */ jsx(
|
|
2571
|
-
|
|
2614
|
+
EventMarker3D,
|
|
2572
2615
|
{
|
|
2573
2616
|
event: ev,
|
|
2574
2617
|
position: [position[0], position[1] + 1.4, position[2]]
|
|
@@ -2687,7 +2730,7 @@ function loadLib(key, importer) {
|
|
|
2687
2730
|
return p;
|
|
2688
2731
|
}
|
|
2689
2732
|
function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
2690
|
-
const Lazy =
|
|
2733
|
+
const Lazy = React10__default.lazy(async () => {
|
|
2691
2734
|
const lib = await loadLib(libKey, importer);
|
|
2692
2735
|
const Comp = pick(lib);
|
|
2693
2736
|
if (!Comp) {
|
|
@@ -2697,7 +2740,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
|
2697
2740
|
return { default: Comp };
|
|
2698
2741
|
});
|
|
2699
2742
|
const Wrapped = (props) => /* @__PURE__ */ jsx(
|
|
2700
|
-
|
|
2743
|
+
React10__default.Suspense,
|
|
2701
2744
|
{
|
|
2702
2745
|
fallback: /* @__PURE__ */ jsx(
|
|
2703
2746
|
"span",
|
|
@@ -3366,7 +3409,7 @@ var Icon = ({
|
|
|
3366
3409
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
3367
3410
|
const effectiveName = typeof icon === "string" ? icon : name;
|
|
3368
3411
|
const family = useIconFamily();
|
|
3369
|
-
const RenderedComponent =
|
|
3412
|
+
const RenderedComponent = React10__default.useMemo(() => {
|
|
3370
3413
|
if (directIcon) return null;
|
|
3371
3414
|
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
3372
3415
|
}, [directIcon, effectiveName, family]);
|
|
@@ -3493,13 +3536,13 @@ function AtlasImage({
|
|
|
3493
3536
|
style,
|
|
3494
3537
|
"aria-hidden": ariaHidden
|
|
3495
3538
|
}) {
|
|
3496
|
-
const [, bump] =
|
|
3497
|
-
const canvasRef =
|
|
3539
|
+
const [, bump] = React10.useReducer((x) => x + 1, 0);
|
|
3540
|
+
const canvasRef = React10.useRef(null);
|
|
3498
3541
|
const sliced = isAtlasAsset(asset);
|
|
3499
3542
|
const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
|
|
3500
3543
|
const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
|
|
3501
3544
|
const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
|
|
3502
|
-
|
|
3545
|
+
React10.useEffect(() => {
|
|
3503
3546
|
const canvas = canvasRef.current;
|
|
3504
3547
|
if (!canvas || !img || !rect) return;
|
|
3505
3548
|
canvas.width = rect.sw;
|
|
@@ -3623,7 +3666,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
3623
3666
|
const IconComp = value;
|
|
3624
3667
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
3625
3668
|
}
|
|
3626
|
-
if (
|
|
3669
|
+
if (React10__default.isValidElement(value)) {
|
|
3627
3670
|
return value;
|
|
3628
3671
|
}
|
|
3629
3672
|
if (typeof value === "object" && value !== null && isIconLike(value)) {
|
|
@@ -3632,7 +3675,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
3632
3675
|
}
|
|
3633
3676
|
return value;
|
|
3634
3677
|
}
|
|
3635
|
-
var Button =
|
|
3678
|
+
var Button = React10__default.forwardRef(
|
|
3636
3679
|
({
|
|
3637
3680
|
className,
|
|
3638
3681
|
variant = "primary",
|
|
@@ -3780,7 +3823,7 @@ var Typography = ({
|
|
|
3780
3823
|
}) => {
|
|
3781
3824
|
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
3782
3825
|
const Component2 = as || defaultElements[variant];
|
|
3783
|
-
return
|
|
3826
|
+
return React10__default.createElement(
|
|
3784
3827
|
Component2,
|
|
3785
3828
|
{
|
|
3786
3829
|
id,
|
|
@@ -3853,7 +3896,7 @@ var Stack = ({
|
|
|
3853
3896
|
};
|
|
3854
3897
|
const isHorizontal = direction === "horizontal";
|
|
3855
3898
|
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
3856
|
-
return
|
|
3899
|
+
return React10__default.createElement(
|
|
3857
3900
|
Component2,
|
|
3858
3901
|
{
|
|
3859
3902
|
className: cn(
|
|
@@ -4228,7 +4271,7 @@ var positionStyles = {
|
|
|
4228
4271
|
fixed: "fixed",
|
|
4229
4272
|
sticky: "sticky"
|
|
4230
4273
|
};
|
|
4231
|
-
var Box =
|
|
4274
|
+
var Box = React10__default.forwardRef(
|
|
4232
4275
|
({
|
|
4233
4276
|
padding,
|
|
4234
4277
|
paddingX,
|
|
@@ -4293,7 +4336,7 @@ var Box = React8__default.forwardRef(
|
|
|
4293
4336
|
onPointerDown?.(e);
|
|
4294
4337
|
}, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
|
|
4295
4338
|
const isClickable = action || onClick;
|
|
4296
|
-
return
|
|
4339
|
+
return React10__default.createElement(
|
|
4297
4340
|
Component2,
|
|
4298
4341
|
{
|
|
4299
4342
|
ref,
|
|
@@ -6971,7 +7014,7 @@ var Avl3DContext = createContext(DEFAULT_CONFIG2);
|
|
|
6971
7014
|
function useAvl3DConfig() {
|
|
6972
7015
|
return useContext(Avl3DContext);
|
|
6973
7016
|
}
|
|
6974
|
-
function
|
|
7017
|
+
function CameraController({ targetPosition, targetLookAt, animated }) {
|
|
6975
7018
|
const { camera } = useThree();
|
|
6976
7019
|
const targetPosVec = useRef(new THREE6.Vector3(...targetPosition));
|
|
6977
7020
|
const targetLookVec = useRef(new THREE6.Vector3(...targetLookAt));
|
|
@@ -7081,7 +7124,7 @@ var Avl3DViewer = ({
|
|
|
7081
7124
|
const handleTraitClick = useCallback((name) => {
|
|
7082
7125
|
dispatch({ type: "ZOOM_INTO_TRAIT", trait: name, targetPosition: { x: 0, y: 0 } });
|
|
7083
7126
|
}, []);
|
|
7084
|
-
const [highlightedTrait, setHighlightedTrait] =
|
|
7127
|
+
const [highlightedTrait, setHighlightedTrait] = React10__default.useState(null);
|
|
7085
7128
|
const handleTransitionClick = useCallback((index) => {
|
|
7086
7129
|
dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex: index, targetPosition: { x: 0, y: 0 } });
|
|
7087
7130
|
}, []);
|
|
@@ -7168,7 +7211,7 @@ var Avl3DViewer = ({
|
|
|
7168
7211
|
gap: "xs",
|
|
7169
7212
|
align: "center",
|
|
7170
7213
|
className: "absolute top-2 left-2 z-10 bg-surface/80 backdrop-blur rounded-md px-3 py-1.5",
|
|
7171
|
-
children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(
|
|
7214
|
+
children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React10__default.Fragment, { children: [
|
|
7172
7215
|
i > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "mx-1", children: "/" }),
|
|
7173
7216
|
i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsx(
|
|
7174
7217
|
Box,
|
|
@@ -7243,7 +7286,7 @@ var Avl3DViewer = ({
|
|
|
7243
7286
|
}
|
|
7244
7287
|
),
|
|
7245
7288
|
/* @__PURE__ */ jsx(
|
|
7246
|
-
|
|
7289
|
+
CameraController,
|
|
7247
7290
|
{
|
|
7248
7291
|
targetPosition: cameraConfig.position,
|
|
7249
7292
|
targetLookAt: cameraConfig.target,
|