@almadar/ui 2.16.0 → 2.16.1
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 +91 -1
- package/dist/avl/index.d.cts +7 -5
- package/dist/avl/index.js +91 -1
- package/dist/components/index.cjs +131 -2411
- package/dist/components/index.css +0 -508
- package/dist/components/index.js +132 -2411
- package/dist/components/molecules/avl/AvlSlotMap.d.ts +5 -4
- package/dist/components/molecules/avl/avl-layout.d.ts +2 -1
- package/dist/components/organisms/component-registry.generated.d.ts +1 -1
- package/dist/components/organisms/game/three/index.cjs +1067 -0
- package/dist/components/organisms/game/three/index.css +192 -0
- package/dist/components/organisms/game/three/index.d.ts +4 -0
- package/dist/components/organisms/game/three/index.js +1068 -5
- package/dist/illustrations/index.cjs +91 -1
- package/dist/illustrations/index.d.cts +5 -4
- package/dist/illustrations/index.js +91 -1
- package/dist/providers/index.cjs +152 -1521
- package/dist/providers/index.css +0 -508
- package/dist/providers/index.js +62 -1430
- package/dist/runtime/index.cjs +145 -1514
- package/dist/runtime/index.css +0 -508
- package/dist/runtime/index.js +63 -1431
- package/package.json +1 -1
|
@@ -9,6 +9,8 @@ var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
|
|
|
9
9
|
var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
|
|
10
10
|
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
11
11
|
var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
|
|
12
|
+
var clsx = require('clsx');
|
|
13
|
+
var tailwindMerge = require('tailwind-merge');
|
|
12
14
|
|
|
13
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
16
|
|
|
@@ -2200,6 +2202,1067 @@ function preloadFeatures(urls) {
|
|
|
2200
2202
|
}
|
|
2201
2203
|
});
|
|
2202
2204
|
}
|
|
2205
|
+
var DEFAULT_GRID_CONFIG = {
|
|
2206
|
+
cellSize: 1,
|
|
2207
|
+
offsetX: 0,
|
|
2208
|
+
offsetZ: 0
|
|
2209
|
+
};
|
|
2210
|
+
function CameraController({
|
|
2211
|
+
onCameraChange
|
|
2212
|
+
}) {
|
|
2213
|
+
const { camera } = fiber.useThree();
|
|
2214
|
+
React8.useEffect(() => {
|
|
2215
|
+
if (onCameraChange) {
|
|
2216
|
+
onCameraChange({
|
|
2217
|
+
x: camera.position.x,
|
|
2218
|
+
y: camera.position.y,
|
|
2219
|
+
z: camera.position.z
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
}, [camera.position, onCameraChange]);
|
|
2223
|
+
return null;
|
|
2224
|
+
}
|
|
2225
|
+
var GameCanvas3D = React8.forwardRef(
|
|
2226
|
+
({
|
|
2227
|
+
tiles = [],
|
|
2228
|
+
units = [],
|
|
2229
|
+
features = [],
|
|
2230
|
+
events = [],
|
|
2231
|
+
orientation = "standard",
|
|
2232
|
+
cameraMode = "isometric",
|
|
2233
|
+
showGrid = true,
|
|
2234
|
+
showCoordinates = false,
|
|
2235
|
+
showTileInfo = false,
|
|
2236
|
+
overlay = "default",
|
|
2237
|
+
shadows = true,
|
|
2238
|
+
backgroundColor = "#1a1a2e",
|
|
2239
|
+
onTileClick,
|
|
2240
|
+
onUnitClick,
|
|
2241
|
+
onFeatureClick,
|
|
2242
|
+
onCanvasClick,
|
|
2243
|
+
onTileHover,
|
|
2244
|
+
onUnitAnimation,
|
|
2245
|
+
assetLoader: customAssetLoader,
|
|
2246
|
+
tileRenderer: CustomTileRenderer,
|
|
2247
|
+
unitRenderer: CustomUnitRenderer,
|
|
2248
|
+
featureRenderer: CustomFeatureRenderer,
|
|
2249
|
+
className,
|
|
2250
|
+
isLoading: externalLoading,
|
|
2251
|
+
error: externalError,
|
|
2252
|
+
entity,
|
|
2253
|
+
preloadAssets = [],
|
|
2254
|
+
tileClickEvent,
|
|
2255
|
+
unitClickEvent,
|
|
2256
|
+
featureClickEvent,
|
|
2257
|
+
canvasClickEvent,
|
|
2258
|
+
tileHoverEvent,
|
|
2259
|
+
tileLeaveEvent,
|
|
2260
|
+
unitAnimationEvent,
|
|
2261
|
+
cameraChangeEvent,
|
|
2262
|
+
loadingMessage = "Loading 3D Scene...",
|
|
2263
|
+
useInstancing = true,
|
|
2264
|
+
validMoves = [],
|
|
2265
|
+
attackTargets = [],
|
|
2266
|
+
selectedTileIds = [],
|
|
2267
|
+
selectedUnitId = null,
|
|
2268
|
+
children
|
|
2269
|
+
}, ref) => {
|
|
2270
|
+
const containerRef = React8.useRef(null);
|
|
2271
|
+
const controlsRef = React8.useRef(null);
|
|
2272
|
+
const [hoveredTile, setHoveredTile] = React8.useState(null);
|
|
2273
|
+
const [internalError, setInternalError] = React8.useState(null);
|
|
2274
|
+
const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
|
|
2275
|
+
preloadUrls: preloadAssets,
|
|
2276
|
+
loader: customAssetLoader
|
|
2277
|
+
});
|
|
2278
|
+
const eventHandlers = useGameCanvas3DEvents({
|
|
2279
|
+
tileClickEvent,
|
|
2280
|
+
unitClickEvent,
|
|
2281
|
+
featureClickEvent,
|
|
2282
|
+
canvasClickEvent,
|
|
2283
|
+
tileHoverEvent,
|
|
2284
|
+
tileLeaveEvent,
|
|
2285
|
+
unitAnimationEvent,
|
|
2286
|
+
cameraChangeEvent,
|
|
2287
|
+
onTileClick,
|
|
2288
|
+
onUnitClick,
|
|
2289
|
+
onFeatureClick,
|
|
2290
|
+
onCanvasClick,
|
|
2291
|
+
onTileHover,
|
|
2292
|
+
onUnitAnimation
|
|
2293
|
+
});
|
|
2294
|
+
const gridBounds = React8.useMemo(() => {
|
|
2295
|
+
if (tiles.length === 0) {
|
|
2296
|
+
return { minX: 0, maxX: 10, minZ: 0, maxZ: 10 };
|
|
2297
|
+
}
|
|
2298
|
+
const xs = tiles.map((t) => t.x);
|
|
2299
|
+
const zs = tiles.map((t) => t.z || t.y || 0);
|
|
2300
|
+
return {
|
|
2301
|
+
minX: Math.min(...xs),
|
|
2302
|
+
maxX: Math.max(...xs),
|
|
2303
|
+
minZ: Math.min(...zs),
|
|
2304
|
+
maxZ: Math.max(...zs)
|
|
2305
|
+
};
|
|
2306
|
+
}, [tiles]);
|
|
2307
|
+
const cameraTarget = React8.useMemo(() => {
|
|
2308
|
+
return [
|
|
2309
|
+
(gridBounds.minX + gridBounds.maxX) / 2,
|
|
2310
|
+
0,
|
|
2311
|
+
(gridBounds.minZ + gridBounds.maxZ) / 2
|
|
2312
|
+
];
|
|
2313
|
+
}, [gridBounds]);
|
|
2314
|
+
const gridConfig = React8.useMemo(
|
|
2315
|
+
() => ({
|
|
2316
|
+
...DEFAULT_GRID_CONFIG,
|
|
2317
|
+
offsetX: -(gridBounds.maxX - gridBounds.minX) / 2,
|
|
2318
|
+
offsetZ: -(gridBounds.maxZ - gridBounds.minZ) / 2
|
|
2319
|
+
}),
|
|
2320
|
+
[gridBounds]
|
|
2321
|
+
);
|
|
2322
|
+
const gridToWorld2 = React8.useCallback(
|
|
2323
|
+
(x, z, y = 0) => {
|
|
2324
|
+
const worldX = (x - gridBounds.minX) * gridConfig.cellSize;
|
|
2325
|
+
const worldZ = (z - gridBounds.minZ) * gridConfig.cellSize;
|
|
2326
|
+
return [worldX, y * gridConfig.cellSize, worldZ];
|
|
2327
|
+
},
|
|
2328
|
+
[gridBounds, gridConfig]
|
|
2329
|
+
);
|
|
2330
|
+
React8.useImperativeHandle(ref, () => ({
|
|
2331
|
+
getCameraPosition: () => {
|
|
2332
|
+
if (controlsRef.current) {
|
|
2333
|
+
const pos = controlsRef.current.object.position;
|
|
2334
|
+
return new THREE6__namespace.Vector3(pos.x, pos.y, pos.z);
|
|
2335
|
+
}
|
|
2336
|
+
return null;
|
|
2337
|
+
},
|
|
2338
|
+
setCameraPosition: (x, y, z) => {
|
|
2339
|
+
if (controlsRef.current) {
|
|
2340
|
+
controlsRef.current.object.position.set(x, y, z);
|
|
2341
|
+
controlsRef.current.update();
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2344
|
+
lookAt: (x, y, z) => {
|
|
2345
|
+
if (controlsRef.current) {
|
|
2346
|
+
controlsRef.current.target.set(x, y, z);
|
|
2347
|
+
controlsRef.current.update();
|
|
2348
|
+
}
|
|
2349
|
+
},
|
|
2350
|
+
resetCamera: () => {
|
|
2351
|
+
if (controlsRef.current) {
|
|
2352
|
+
controlsRef.current.reset();
|
|
2353
|
+
}
|
|
2354
|
+
},
|
|
2355
|
+
screenshot: () => {
|
|
2356
|
+
const canvas = containerRef.current?.querySelector("canvas");
|
|
2357
|
+
if (canvas) {
|
|
2358
|
+
return canvas.toDataURL("image/png");
|
|
2359
|
+
}
|
|
2360
|
+
return null;
|
|
2361
|
+
},
|
|
2362
|
+
export: () => ({
|
|
2363
|
+
tiles,
|
|
2364
|
+
units,
|
|
2365
|
+
features
|
|
2366
|
+
})
|
|
2367
|
+
}));
|
|
2368
|
+
const handleTileClick = React8.useCallback(
|
|
2369
|
+
(tile, event) => {
|
|
2370
|
+
eventHandlers.handleTileClick(tile, event);
|
|
2371
|
+
},
|
|
2372
|
+
[eventHandlers]
|
|
2373
|
+
);
|
|
2374
|
+
const handleUnitClick = React8.useCallback(
|
|
2375
|
+
(unit, event) => {
|
|
2376
|
+
eventHandlers.handleUnitClick(unit, event);
|
|
2377
|
+
},
|
|
2378
|
+
[eventHandlers]
|
|
2379
|
+
);
|
|
2380
|
+
const handleFeatureClick = React8.useCallback(
|
|
2381
|
+
(feature, event) => {
|
|
2382
|
+
if (event) {
|
|
2383
|
+
eventHandlers.handleFeatureClick(feature, event);
|
|
2384
|
+
}
|
|
2385
|
+
},
|
|
2386
|
+
[eventHandlers]
|
|
2387
|
+
);
|
|
2388
|
+
const handleTileHover = React8.useCallback(
|
|
2389
|
+
(tile, event) => {
|
|
2390
|
+
setHoveredTile(tile);
|
|
2391
|
+
if (event) {
|
|
2392
|
+
eventHandlers.handleTileHover(tile, event);
|
|
2393
|
+
}
|
|
2394
|
+
},
|
|
2395
|
+
[eventHandlers]
|
|
2396
|
+
);
|
|
2397
|
+
const cameraConfig = React8.useMemo(() => {
|
|
2398
|
+
const size = Math.max(
|
|
2399
|
+
gridBounds.maxX - gridBounds.minX,
|
|
2400
|
+
gridBounds.maxZ - gridBounds.minZ
|
|
2401
|
+
);
|
|
2402
|
+
const distance = size * 1.5;
|
|
2403
|
+
switch (cameraMode) {
|
|
2404
|
+
case "isometric":
|
|
2405
|
+
return {
|
|
2406
|
+
position: [distance, distance * 0.8, distance],
|
|
2407
|
+
fov: 45
|
|
2408
|
+
};
|
|
2409
|
+
case "top-down":
|
|
2410
|
+
return {
|
|
2411
|
+
position: [0, distance * 2, 0],
|
|
2412
|
+
fov: 45
|
|
2413
|
+
};
|
|
2414
|
+
case "perspective":
|
|
2415
|
+
default:
|
|
2416
|
+
return {
|
|
2417
|
+
position: [distance, distance, distance],
|
|
2418
|
+
fov: 45
|
|
2419
|
+
};
|
|
2420
|
+
}
|
|
2421
|
+
}, [cameraMode, gridBounds]);
|
|
2422
|
+
const DefaultTileRenderer = React8.useCallback(
|
|
2423
|
+
({ tile, position }) => {
|
|
2424
|
+
const isSelected = tile.id ? selectedTileIds.includes(tile.id) : false;
|
|
2425
|
+
const isHovered = hoveredTile?.id === tile.id;
|
|
2426
|
+
const isValidMove = validMoves.some(
|
|
2427
|
+
(m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
|
|
2428
|
+
);
|
|
2429
|
+
const isAttackTarget = attackTargets.some(
|
|
2430
|
+
(m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
|
|
2431
|
+
);
|
|
2432
|
+
let color = 8421504;
|
|
2433
|
+
if (tile.type === "water") color = 4491468;
|
|
2434
|
+
else if (tile.type === "grass") color = 4500036;
|
|
2435
|
+
else if (tile.type === "sand") color = 14535816;
|
|
2436
|
+
else if (tile.type === "rock") color = 8947848;
|
|
2437
|
+
else if (tile.type === "snow") color = 15658734;
|
|
2438
|
+
let emissive = 0;
|
|
2439
|
+
if (isSelected) emissive = 4473924;
|
|
2440
|
+
else if (isAttackTarget) emissive = 4456448;
|
|
2441
|
+
else if (isValidMove) emissive = 17408;
|
|
2442
|
+
else if (isHovered) emissive = 2236962;
|
|
2443
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2444
|
+
"mesh",
|
|
2445
|
+
{
|
|
2446
|
+
position,
|
|
2447
|
+
onClick: (e) => handleTileClick(tile, e),
|
|
2448
|
+
onPointerEnter: (e) => handleTileHover(tile, e),
|
|
2449
|
+
onPointerLeave: (e) => handleTileHover(null, e),
|
|
2450
|
+
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
2451
|
+
children: [
|
|
2452
|
+
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.95, 0.2, 0.95] }),
|
|
2453
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, emissive })
|
|
2454
|
+
]
|
|
2455
|
+
}
|
|
2456
|
+
);
|
|
2457
|
+
},
|
|
2458
|
+
[selectedTileIds, hoveredTile, validMoves, attackTargets, handleTileClick, handleTileHover]
|
|
2459
|
+
);
|
|
2460
|
+
const DefaultUnitRenderer = React8.useCallback(
|
|
2461
|
+
({ unit, position }) => {
|
|
2462
|
+
const isSelected = selectedUnitId === unit.id;
|
|
2463
|
+
const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
|
|
2464
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2465
|
+
"group",
|
|
2466
|
+
{
|
|
2467
|
+
position,
|
|
2468
|
+
onClick: (e) => handleUnitClick(unit, e),
|
|
2469
|
+
userData: { type: "unit", unitId: unit.id },
|
|
2470
|
+
children: [
|
|
2471
|
+
isSelected && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.05, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
2472
|
+
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.4, 0.5, 32] }),
|
|
2473
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#ffff00", transparent: true, opacity: 0.8 })
|
|
2474
|
+
] }),
|
|
2475
|
+
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.3, 0], children: [
|
|
2476
|
+
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.1, 8] }),
|
|
2477
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
2478
|
+
] }),
|
|
2479
|
+
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.6, 0], children: [
|
|
2480
|
+
/* @__PURE__ */ jsxRuntime.jsx("capsuleGeometry", { args: [0.2, 0.4, 4, 8] }),
|
|
2481
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
2482
|
+
] }),
|
|
2483
|
+
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
2484
|
+
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.12, 8, 8] }),
|
|
2485
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
2486
|
+
] }),
|
|
2487
|
+
unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, 1.2, 0], children: [
|
|
2488
|
+
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [-0.25, 0, 0], children: [
|
|
2489
|
+
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5, 0.05] }),
|
|
2490
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: 3355443 })
|
|
2491
|
+
] }),
|
|
2492
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2493
|
+
"mesh",
|
|
2494
|
+
{
|
|
2495
|
+
position: [
|
|
2496
|
+
-0.25 + 0.5 * (unit.health / unit.maxHealth) / 2,
|
|
2497
|
+
0,
|
|
2498
|
+
0.01
|
|
2499
|
+
],
|
|
2500
|
+
children: [
|
|
2501
|
+
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5 * (unit.health / unit.maxHealth), 0.05] }),
|
|
2502
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2503
|
+
"meshBasicMaterial",
|
|
2504
|
+
{
|
|
2505
|
+
color: unit.health / unit.maxHealth > 0.5 ? 4500036 : unit.health / unit.maxHealth > 0.25 ? 11184708 : 16729156
|
|
2506
|
+
}
|
|
2507
|
+
)
|
|
2508
|
+
]
|
|
2509
|
+
}
|
|
2510
|
+
)
|
|
2511
|
+
] })
|
|
2512
|
+
]
|
|
2513
|
+
}
|
|
2514
|
+
);
|
|
2515
|
+
},
|
|
2516
|
+
[selectedUnitId, handleUnitClick]
|
|
2517
|
+
);
|
|
2518
|
+
const DefaultFeatureRenderer = React8.useCallback(
|
|
2519
|
+
({
|
|
2520
|
+
feature,
|
|
2521
|
+
position
|
|
2522
|
+
}) => {
|
|
2523
|
+
if (feature.assetUrl) {
|
|
2524
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2525
|
+
ModelLoader,
|
|
2526
|
+
{
|
|
2527
|
+
url: feature.assetUrl,
|
|
2528
|
+
position,
|
|
2529
|
+
scale: 0.5,
|
|
2530
|
+
rotation: [0, feature.rotation ?? 0, 0],
|
|
2531
|
+
onClick: () => handleFeatureClick(feature, null),
|
|
2532
|
+
fallbackGeometry: "box"
|
|
2533
|
+
},
|
|
2534
|
+
feature.id
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2537
|
+
if (feature.type === "tree") {
|
|
2538
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2539
|
+
"group",
|
|
2540
|
+
{
|
|
2541
|
+
position,
|
|
2542
|
+
onClick: (e) => handleFeatureClick(feature, e),
|
|
2543
|
+
userData: { type: "feature", featureId: feature.id },
|
|
2544
|
+
children: [
|
|
2545
|
+
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.4, 0], children: [
|
|
2546
|
+
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.1, 0.15, 0.8, 6] }),
|
|
2547
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 9127187 })
|
|
2548
|
+
] }),
|
|
2549
|
+
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
2550
|
+
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.5, 0.8, 8] }),
|
|
2551
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 2263842 })
|
|
2552
|
+
] })
|
|
2553
|
+
]
|
|
2554
|
+
}
|
|
2555
|
+
);
|
|
2556
|
+
}
|
|
2557
|
+
if (feature.type === "rock") {
|
|
2558
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2559
|
+
"mesh",
|
|
2560
|
+
{
|
|
2561
|
+
position: [position[0], position[1] + 0.3, position[2]],
|
|
2562
|
+
onClick: (e) => handleFeatureClick(feature, e),
|
|
2563
|
+
userData: { type: "feature", featureId: feature.id },
|
|
2564
|
+
children: [
|
|
2565
|
+
/* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [0.3, 0] }),
|
|
2566
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 8421504 })
|
|
2567
|
+
]
|
|
2568
|
+
}
|
|
2569
|
+
);
|
|
2570
|
+
}
|
|
2571
|
+
return null;
|
|
2572
|
+
},
|
|
2573
|
+
[handleFeatureClick]
|
|
2574
|
+
);
|
|
2575
|
+
if (externalLoading || assetsLoading && preloadAssets.length > 0) {
|
|
2576
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2577
|
+
Canvas3DLoadingState,
|
|
2578
|
+
{
|
|
2579
|
+
progress,
|
|
2580
|
+
loaded,
|
|
2581
|
+
total,
|
|
2582
|
+
message: loadingMessage,
|
|
2583
|
+
className
|
|
2584
|
+
}
|
|
2585
|
+
);
|
|
2586
|
+
}
|
|
2587
|
+
const displayError = externalError || internalError;
|
|
2588
|
+
if (displayError) {
|
|
2589
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Canvas3DErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "game-canvas-3d game-canvas-3d--error", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__error", children: [
|
|
2590
|
+
"Error: ",
|
|
2591
|
+
displayError
|
|
2592
|
+
] }) }) });
|
|
2593
|
+
}
|
|
2594
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2595
|
+
Canvas3DErrorBoundary,
|
|
2596
|
+
{
|
|
2597
|
+
onError: (err) => setInternalError(err.message),
|
|
2598
|
+
onReset: () => setInternalError(null),
|
|
2599
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2600
|
+
"div",
|
|
2601
|
+
{
|
|
2602
|
+
ref: containerRef,
|
|
2603
|
+
className: `game-canvas-3d ${className || ""}`,
|
|
2604
|
+
"data-orientation": orientation,
|
|
2605
|
+
"data-camera-mode": cameraMode,
|
|
2606
|
+
"data-overlay": overlay,
|
|
2607
|
+
children: [
|
|
2608
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2609
|
+
fiber.Canvas,
|
|
2610
|
+
{
|
|
2611
|
+
shadows,
|
|
2612
|
+
camera: {
|
|
2613
|
+
position: cameraConfig.position,
|
|
2614
|
+
fov: cameraConfig.fov,
|
|
2615
|
+
near: 0.1,
|
|
2616
|
+
far: 1e3
|
|
2617
|
+
},
|
|
2618
|
+
style: { background: backgroundColor },
|
|
2619
|
+
onClick: (e) => {
|
|
2620
|
+
if (e.target === e.currentTarget) {
|
|
2621
|
+
eventHandlers.handleCanvasClick(e);
|
|
2622
|
+
}
|
|
2623
|
+
},
|
|
2624
|
+
children: [
|
|
2625
|
+
/* @__PURE__ */ jsxRuntime.jsx(CameraController, { onCameraChange: eventHandlers.handleCameraChange }),
|
|
2626
|
+
/* @__PURE__ */ jsxRuntime.jsx("ambientLight", { intensity: 0.6 }),
|
|
2627
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2628
|
+
"directionalLight",
|
|
2629
|
+
{
|
|
2630
|
+
position: [10, 20, 10],
|
|
2631
|
+
intensity: 0.8,
|
|
2632
|
+
castShadow: shadows,
|
|
2633
|
+
"shadow-mapSize": [2048, 2048]
|
|
2634
|
+
}
|
|
2635
|
+
),
|
|
2636
|
+
/* @__PURE__ */ jsxRuntime.jsx("hemisphereLight", { intensity: 0.3, color: "#87ceeb", groundColor: "#362d1d" }),
|
|
2637
|
+
showGrid && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2638
|
+
drei.Grid,
|
|
2639
|
+
{
|
|
2640
|
+
args: [
|
|
2641
|
+
Math.max(gridBounds.maxX - gridBounds.minX + 2, 10),
|
|
2642
|
+
Math.max(gridBounds.maxZ - gridBounds.minZ + 2, 10)
|
|
2643
|
+
],
|
|
2644
|
+
position: [
|
|
2645
|
+
(gridBounds.maxX - gridBounds.minX) / 2 - 0.5,
|
|
2646
|
+
0,
|
|
2647
|
+
(gridBounds.maxZ - gridBounds.minZ) / 2 - 0.5
|
|
2648
|
+
],
|
|
2649
|
+
cellSize: 1,
|
|
2650
|
+
cellThickness: 1,
|
|
2651
|
+
cellColor: "#444444",
|
|
2652
|
+
sectionSize: 5,
|
|
2653
|
+
sectionThickness: 1.5,
|
|
2654
|
+
sectionColor: "#666666",
|
|
2655
|
+
fadeDistance: 50,
|
|
2656
|
+
fadeStrength: 1
|
|
2657
|
+
}
|
|
2658
|
+
),
|
|
2659
|
+
tiles.map((tile, index) => {
|
|
2660
|
+
const position = gridToWorld2(
|
|
2661
|
+
tile.x,
|
|
2662
|
+
tile.z ?? tile.y ?? 0,
|
|
2663
|
+
tile.elevation ?? 0
|
|
2664
|
+
);
|
|
2665
|
+
const Renderer = CustomTileRenderer || DefaultTileRenderer;
|
|
2666
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { tile, position }, tile.id ?? `tile-${index}`);
|
|
2667
|
+
}),
|
|
2668
|
+
features.map((feature, index) => {
|
|
2669
|
+
const position = gridToWorld2(
|
|
2670
|
+
feature.x,
|
|
2671
|
+
feature.z ?? feature.y ?? 0,
|
|
2672
|
+
(feature.elevation ?? 0) + 0.5
|
|
2673
|
+
);
|
|
2674
|
+
const Renderer = CustomFeatureRenderer || DefaultFeatureRenderer;
|
|
2675
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { feature, position }, feature.id ?? `feature-${index}`);
|
|
2676
|
+
}),
|
|
2677
|
+
units.map((unit) => {
|
|
2678
|
+
const position = gridToWorld2(
|
|
2679
|
+
unit.x ?? 0,
|
|
2680
|
+
unit.z ?? unit.y ?? 0,
|
|
2681
|
+
(unit.elevation ?? 0) + 0.5
|
|
2682
|
+
);
|
|
2683
|
+
const Renderer = CustomUnitRenderer || DefaultUnitRenderer;
|
|
2684
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { unit, position }, unit.id);
|
|
2685
|
+
}),
|
|
2686
|
+
children,
|
|
2687
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2688
|
+
drei.OrbitControls,
|
|
2689
|
+
{
|
|
2690
|
+
ref: controlsRef,
|
|
2691
|
+
target: cameraTarget,
|
|
2692
|
+
enableDamping: true,
|
|
2693
|
+
dampingFactor: 0.05,
|
|
2694
|
+
minDistance: 2,
|
|
2695
|
+
maxDistance: 100,
|
|
2696
|
+
maxPolarAngle: Math.PI / 2 - 0.1
|
|
2697
|
+
}
|
|
2698
|
+
)
|
|
2699
|
+
]
|
|
2700
|
+
}
|
|
2701
|
+
),
|
|
2702
|
+
showCoordinates && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__coordinates", children: [
|
|
2703
|
+
"X: ",
|
|
2704
|
+
hoveredTile.x,
|
|
2705
|
+
", Z: ",
|
|
2706
|
+
hoveredTile.z ?? hoveredTile.y ?? 0
|
|
2707
|
+
] }),
|
|
2708
|
+
showTileInfo && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__tile-info", children: [
|
|
2709
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__type", children: hoveredTile.type }),
|
|
2710
|
+
hoveredTile.terrain && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__terrain", children: hoveredTile.terrain })
|
|
2711
|
+
] })
|
|
2712
|
+
]
|
|
2713
|
+
}
|
|
2714
|
+
)
|
|
2715
|
+
}
|
|
2716
|
+
);
|
|
2717
|
+
}
|
|
2718
|
+
);
|
|
2719
|
+
GameCanvas3D.displayName = "GameCanvas3D";
|
|
2720
|
+
function cn(...inputs) {
|
|
2721
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
2722
|
+
}
|
|
2723
|
+
var paddingStyles = {
|
|
2724
|
+
none: "p-0",
|
|
2725
|
+
xs: "p-1",
|
|
2726
|
+
sm: "p-2",
|
|
2727
|
+
md: "p-4",
|
|
2728
|
+
lg: "p-6",
|
|
2729
|
+
xl: "p-8",
|
|
2730
|
+
"2xl": "p-12"
|
|
2731
|
+
};
|
|
2732
|
+
var paddingXStyles = {
|
|
2733
|
+
none: "px-0",
|
|
2734
|
+
xs: "px-1",
|
|
2735
|
+
sm: "px-2",
|
|
2736
|
+
md: "px-4",
|
|
2737
|
+
lg: "px-6",
|
|
2738
|
+
xl: "px-8",
|
|
2739
|
+
"2xl": "px-12"
|
|
2740
|
+
};
|
|
2741
|
+
var paddingYStyles = {
|
|
2742
|
+
none: "py-0",
|
|
2743
|
+
xs: "py-1",
|
|
2744
|
+
sm: "py-2",
|
|
2745
|
+
md: "py-4",
|
|
2746
|
+
lg: "py-6",
|
|
2747
|
+
xl: "py-8",
|
|
2748
|
+
"2xl": "py-12"
|
|
2749
|
+
};
|
|
2750
|
+
var marginStyles = {
|
|
2751
|
+
none: "m-0",
|
|
2752
|
+
xs: "m-1",
|
|
2753
|
+
sm: "m-2",
|
|
2754
|
+
md: "m-4",
|
|
2755
|
+
lg: "m-6",
|
|
2756
|
+
xl: "m-8",
|
|
2757
|
+
"2xl": "m-12",
|
|
2758
|
+
auto: "m-auto"
|
|
2759
|
+
};
|
|
2760
|
+
var marginXStyles = {
|
|
2761
|
+
none: "mx-0",
|
|
2762
|
+
xs: "mx-1",
|
|
2763
|
+
sm: "mx-2",
|
|
2764
|
+
md: "mx-4",
|
|
2765
|
+
lg: "mx-6",
|
|
2766
|
+
xl: "mx-8",
|
|
2767
|
+
"2xl": "mx-12",
|
|
2768
|
+
auto: "mx-auto"
|
|
2769
|
+
};
|
|
2770
|
+
var marginYStyles = {
|
|
2771
|
+
none: "my-0",
|
|
2772
|
+
xs: "my-1",
|
|
2773
|
+
sm: "my-2",
|
|
2774
|
+
md: "my-4",
|
|
2775
|
+
lg: "my-6",
|
|
2776
|
+
xl: "my-8",
|
|
2777
|
+
"2xl": "my-12",
|
|
2778
|
+
auto: "my-auto"
|
|
2779
|
+
};
|
|
2780
|
+
var bgStyles = {
|
|
2781
|
+
transparent: "bg-transparent",
|
|
2782
|
+
primary: "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
|
|
2783
|
+
secondary: "bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)]",
|
|
2784
|
+
muted: "bg-[var(--color-muted)] text-[var(--color-foreground)]",
|
|
2785
|
+
accent: "bg-[var(--color-accent)] text-[var(--color-accent-foreground)]",
|
|
2786
|
+
surface: "bg-[var(--color-card)]",
|
|
2787
|
+
overlay: "bg-[var(--color-card)]/80 backdrop-blur-sm"
|
|
2788
|
+
};
|
|
2789
|
+
var roundedStyles = {
|
|
2790
|
+
none: "rounded-none",
|
|
2791
|
+
sm: "rounded-[var(--radius-sm)]",
|
|
2792
|
+
md: "rounded-[var(--radius-md)]",
|
|
2793
|
+
lg: "rounded-[var(--radius-lg)]",
|
|
2794
|
+
xl: "rounded-[var(--radius-xl)]",
|
|
2795
|
+
"2xl": "rounded-[var(--radius-xl)]",
|
|
2796
|
+
full: "rounded-[var(--radius-full)]"
|
|
2797
|
+
};
|
|
2798
|
+
var shadowStyles = {
|
|
2799
|
+
none: "shadow-none",
|
|
2800
|
+
sm: "shadow-[var(--shadow-sm)]",
|
|
2801
|
+
md: "shadow-[var(--shadow-main)]",
|
|
2802
|
+
lg: "shadow-[var(--shadow-lg)]",
|
|
2803
|
+
xl: "shadow-[var(--shadow-lg)]"
|
|
2804
|
+
};
|
|
2805
|
+
var displayStyles = {
|
|
2806
|
+
block: "block",
|
|
2807
|
+
inline: "inline",
|
|
2808
|
+
"inline-block": "inline-block",
|
|
2809
|
+
flex: "flex",
|
|
2810
|
+
"inline-flex": "inline-flex",
|
|
2811
|
+
grid: "grid"
|
|
2812
|
+
};
|
|
2813
|
+
var overflowStyles = {
|
|
2814
|
+
auto: "overflow-auto",
|
|
2815
|
+
hidden: "overflow-hidden",
|
|
2816
|
+
visible: "overflow-visible",
|
|
2817
|
+
scroll: "overflow-scroll"
|
|
2818
|
+
};
|
|
2819
|
+
var positionStyles = {
|
|
2820
|
+
relative: "relative",
|
|
2821
|
+
absolute: "absolute",
|
|
2822
|
+
fixed: "fixed",
|
|
2823
|
+
sticky: "sticky"
|
|
2824
|
+
};
|
|
2825
|
+
var Box = React8__default.default.forwardRef(
|
|
2826
|
+
({
|
|
2827
|
+
padding,
|
|
2828
|
+
paddingX,
|
|
2829
|
+
paddingY,
|
|
2830
|
+
margin,
|
|
2831
|
+
marginX,
|
|
2832
|
+
marginY,
|
|
2833
|
+
bg = "transparent",
|
|
2834
|
+
border = false,
|
|
2835
|
+
rounded = "none",
|
|
2836
|
+
shadow = "none",
|
|
2837
|
+
display,
|
|
2838
|
+
fullWidth = false,
|
|
2839
|
+
fullHeight = false,
|
|
2840
|
+
overflow,
|
|
2841
|
+
position,
|
|
2842
|
+
className,
|
|
2843
|
+
children,
|
|
2844
|
+
as: Component2 = "div",
|
|
2845
|
+
action,
|
|
2846
|
+
actionPayload,
|
|
2847
|
+
hoverEvent,
|
|
2848
|
+
onClick,
|
|
2849
|
+
onMouseEnter,
|
|
2850
|
+
onMouseLeave,
|
|
2851
|
+
...rest
|
|
2852
|
+
}, ref) => {
|
|
2853
|
+
const eventBus = useEventBus();
|
|
2854
|
+
const handleClick = React8.useCallback((e) => {
|
|
2855
|
+
if (action) {
|
|
2856
|
+
e.stopPropagation();
|
|
2857
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
2858
|
+
}
|
|
2859
|
+
onClick?.(e);
|
|
2860
|
+
}, [action, actionPayload, eventBus, onClick]);
|
|
2861
|
+
const handleMouseEnter = React8.useCallback((e) => {
|
|
2862
|
+
if (hoverEvent) {
|
|
2863
|
+
eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
2864
|
+
}
|
|
2865
|
+
onMouseEnter?.(e);
|
|
2866
|
+
}, [hoverEvent, eventBus, onMouseEnter]);
|
|
2867
|
+
const handleMouseLeave = React8.useCallback((e) => {
|
|
2868
|
+
if (hoverEvent) {
|
|
2869
|
+
eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
2870
|
+
}
|
|
2871
|
+
onMouseLeave?.(e);
|
|
2872
|
+
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
2873
|
+
const isClickable = action || onClick;
|
|
2874
|
+
const Comp = Component2;
|
|
2875
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2876
|
+
Comp,
|
|
2877
|
+
{
|
|
2878
|
+
ref,
|
|
2879
|
+
className: cn(
|
|
2880
|
+
// Padding
|
|
2881
|
+
padding && paddingStyles[padding],
|
|
2882
|
+
paddingX && paddingXStyles[paddingX],
|
|
2883
|
+
paddingY && paddingYStyles[paddingY],
|
|
2884
|
+
// Margin
|
|
2885
|
+
margin && marginStyles[margin],
|
|
2886
|
+
marginX && marginXStyles[marginX],
|
|
2887
|
+
marginY && marginYStyles[marginY],
|
|
2888
|
+
// Background
|
|
2889
|
+
bgStyles[bg],
|
|
2890
|
+
// Border - uses theme variables
|
|
2891
|
+
border && "border-[length:var(--border-width)] border-[var(--color-border)]",
|
|
2892
|
+
// Rounded
|
|
2893
|
+
roundedStyles[rounded],
|
|
2894
|
+
// Shadow
|
|
2895
|
+
shadowStyles[shadow],
|
|
2896
|
+
// Display
|
|
2897
|
+
display && displayStyles[display],
|
|
2898
|
+
// Dimensions
|
|
2899
|
+
fullWidth && "w-full",
|
|
2900
|
+
fullHeight && "h-full",
|
|
2901
|
+
// Overflow
|
|
2902
|
+
overflow && overflowStyles[overflow],
|
|
2903
|
+
// Position
|
|
2904
|
+
position && positionStyles[position],
|
|
2905
|
+
// Cursor for clickable
|
|
2906
|
+
isClickable && "cursor-pointer",
|
|
2907
|
+
className
|
|
2908
|
+
),
|
|
2909
|
+
onClick: isClickable ? handleClick : void 0,
|
|
2910
|
+
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
2911
|
+
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
2912
|
+
...rest,
|
|
2913
|
+
children
|
|
2914
|
+
}
|
|
2915
|
+
);
|
|
2916
|
+
}
|
|
2917
|
+
);
|
|
2918
|
+
Box.displayName = "Box";
|
|
2919
|
+
var gapStyles = {
|
|
2920
|
+
none: "gap-0",
|
|
2921
|
+
xs: "gap-1",
|
|
2922
|
+
sm: "gap-2",
|
|
2923
|
+
md: "gap-4",
|
|
2924
|
+
lg: "gap-6",
|
|
2925
|
+
xl: "gap-8",
|
|
2926
|
+
"2xl": "gap-12"
|
|
2927
|
+
};
|
|
2928
|
+
var alignStyles = {
|
|
2929
|
+
start: "items-start",
|
|
2930
|
+
center: "items-center",
|
|
2931
|
+
end: "items-end",
|
|
2932
|
+
stretch: "items-stretch",
|
|
2933
|
+
baseline: "items-baseline"
|
|
2934
|
+
};
|
|
2935
|
+
var justifyStyles = {
|
|
2936
|
+
start: "justify-start",
|
|
2937
|
+
center: "justify-center",
|
|
2938
|
+
end: "justify-end",
|
|
2939
|
+
between: "justify-between",
|
|
2940
|
+
around: "justify-around",
|
|
2941
|
+
evenly: "justify-evenly"
|
|
2942
|
+
};
|
|
2943
|
+
var Stack = ({
|
|
2944
|
+
direction = "vertical",
|
|
2945
|
+
gap = "md",
|
|
2946
|
+
align = "stretch",
|
|
2947
|
+
justify = "start",
|
|
2948
|
+
wrap = false,
|
|
2949
|
+
reverse = false,
|
|
2950
|
+
flex = false,
|
|
2951
|
+
className,
|
|
2952
|
+
style,
|
|
2953
|
+
children,
|
|
2954
|
+
as: Component2 = "div",
|
|
2955
|
+
onClick,
|
|
2956
|
+
onKeyDown,
|
|
2957
|
+
role,
|
|
2958
|
+
tabIndex,
|
|
2959
|
+
action,
|
|
2960
|
+
actionPayload,
|
|
2961
|
+
responsive = false
|
|
2962
|
+
}) => {
|
|
2963
|
+
const eventBus = useEventBus();
|
|
2964
|
+
const handleClick = (e) => {
|
|
2965
|
+
if (action) {
|
|
2966
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
2967
|
+
}
|
|
2968
|
+
onClick?.(e);
|
|
2969
|
+
};
|
|
2970
|
+
const isHorizontal = direction === "horizontal";
|
|
2971
|
+
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";
|
|
2972
|
+
const Comp = Component2;
|
|
2973
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2974
|
+
Comp,
|
|
2975
|
+
{
|
|
2976
|
+
className: cn(
|
|
2977
|
+
"flex",
|
|
2978
|
+
directionClass,
|
|
2979
|
+
gapStyles[gap],
|
|
2980
|
+
alignStyles[align],
|
|
2981
|
+
justifyStyles[justify],
|
|
2982
|
+
wrap && "flex-wrap",
|
|
2983
|
+
flex && "flex-1",
|
|
2984
|
+
className
|
|
2985
|
+
),
|
|
2986
|
+
style,
|
|
2987
|
+
onClick: action || onClick ? handleClick : void 0,
|
|
2988
|
+
onKeyDown,
|
|
2989
|
+
role,
|
|
2990
|
+
tabIndex,
|
|
2991
|
+
children
|
|
2992
|
+
}
|
|
2993
|
+
);
|
|
2994
|
+
};
|
|
2995
|
+
var VStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "vertical", ...props });
|
|
2996
|
+
var HStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "horizontal", ...props });
|
|
2997
|
+
var variantStyles = {
|
|
2998
|
+
h1: "text-4xl font-bold tracking-tight text-[var(--color-foreground)]",
|
|
2999
|
+
h2: "text-3xl font-bold tracking-tight text-[var(--color-foreground)]",
|
|
3000
|
+
h3: "text-2xl font-bold text-[var(--color-foreground)]",
|
|
3001
|
+
h4: "text-xl font-bold text-[var(--color-foreground)]",
|
|
3002
|
+
h5: "text-lg font-bold text-[var(--color-foreground)]",
|
|
3003
|
+
h6: "text-base font-bold text-[var(--color-foreground)]",
|
|
3004
|
+
heading: "text-2xl font-bold text-[var(--color-foreground)]",
|
|
3005
|
+
subheading: "text-lg font-semibold text-[var(--color-foreground)]",
|
|
3006
|
+
body1: "text-base font-normal text-[var(--color-foreground)]",
|
|
3007
|
+
body2: "text-sm font-normal text-[var(--color-foreground)]",
|
|
3008
|
+
body: "text-base font-normal text-[var(--color-foreground)]",
|
|
3009
|
+
caption: "text-xs font-normal text-[var(--color-muted-foreground)]",
|
|
3010
|
+
overline: "text-xs uppercase tracking-wide font-bold text-[var(--color-muted-foreground)]",
|
|
3011
|
+
small: "text-sm font-normal text-[var(--color-foreground)]",
|
|
3012
|
+
large: "text-lg font-medium text-[var(--color-foreground)]",
|
|
3013
|
+
label: "text-sm font-medium text-[var(--color-foreground)]"
|
|
3014
|
+
};
|
|
3015
|
+
var colorStyles = {
|
|
3016
|
+
primary: "text-[var(--color-foreground)]",
|
|
3017
|
+
secondary: "text-[var(--color-muted-foreground)]",
|
|
3018
|
+
muted: "text-[var(--color-muted-foreground)]",
|
|
3019
|
+
error: "text-[var(--color-error)]",
|
|
3020
|
+
success: "text-[var(--color-success)]",
|
|
3021
|
+
warning: "text-[var(--color-warning)]",
|
|
3022
|
+
inherit: "text-inherit"
|
|
3023
|
+
};
|
|
3024
|
+
var weightStyles = {
|
|
3025
|
+
light: "font-light",
|
|
3026
|
+
normal: "font-normal",
|
|
3027
|
+
medium: "font-medium",
|
|
3028
|
+
semibold: "font-semibold",
|
|
3029
|
+
bold: "font-bold"
|
|
3030
|
+
};
|
|
3031
|
+
var defaultElements = {
|
|
3032
|
+
h1: "h1",
|
|
3033
|
+
h2: "h2",
|
|
3034
|
+
h3: "h3",
|
|
3035
|
+
h4: "h4",
|
|
3036
|
+
h5: "h5",
|
|
3037
|
+
h6: "h6",
|
|
3038
|
+
heading: "h2",
|
|
3039
|
+
subheading: "h3",
|
|
3040
|
+
body1: "p",
|
|
3041
|
+
body2: "p",
|
|
3042
|
+
body: "p",
|
|
3043
|
+
caption: "span",
|
|
3044
|
+
overline: "span",
|
|
3045
|
+
small: "span",
|
|
3046
|
+
large: "p",
|
|
3047
|
+
label: "span"
|
|
3048
|
+
};
|
|
3049
|
+
var typographySizeStyles = {
|
|
3050
|
+
xs: "text-xs",
|
|
3051
|
+
sm: "text-sm",
|
|
3052
|
+
md: "text-base",
|
|
3053
|
+
lg: "text-lg",
|
|
3054
|
+
xl: "text-xl",
|
|
3055
|
+
"2xl": "text-2xl",
|
|
3056
|
+
"3xl": "text-3xl"
|
|
3057
|
+
};
|
|
3058
|
+
var overflowStyles2 = {
|
|
3059
|
+
visible: "overflow-visible",
|
|
3060
|
+
hidden: "overflow-hidden",
|
|
3061
|
+
wrap: "break-words overflow-hidden",
|
|
3062
|
+
"clamp-2": "overflow-hidden line-clamp-2",
|
|
3063
|
+
"clamp-3": "overflow-hidden line-clamp-3"
|
|
3064
|
+
};
|
|
3065
|
+
var Typography = ({
|
|
3066
|
+
variant: variantProp,
|
|
3067
|
+
level,
|
|
3068
|
+
color = "primary",
|
|
3069
|
+
align,
|
|
3070
|
+
weight,
|
|
3071
|
+
size,
|
|
3072
|
+
truncate = false,
|
|
3073
|
+
overflow,
|
|
3074
|
+
as,
|
|
3075
|
+
id,
|
|
3076
|
+
className,
|
|
3077
|
+
style,
|
|
3078
|
+
content,
|
|
3079
|
+
children
|
|
3080
|
+
}) => {
|
|
3081
|
+
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
3082
|
+
const Component2 = as || defaultElements[variant];
|
|
3083
|
+
const Comp = Component2;
|
|
3084
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3085
|
+
Comp,
|
|
3086
|
+
{
|
|
3087
|
+
id,
|
|
3088
|
+
className: cn(
|
|
3089
|
+
variantStyles[variant],
|
|
3090
|
+
colorStyles[color],
|
|
3091
|
+
weight && weightStyles[weight],
|
|
3092
|
+
size && typographySizeStyles[size],
|
|
3093
|
+
align && `text-${align}`,
|
|
3094
|
+
truncate && "truncate overflow-hidden text-ellipsis",
|
|
3095
|
+
overflow && overflowStyles2[overflow],
|
|
3096
|
+
className
|
|
3097
|
+
),
|
|
3098
|
+
style,
|
|
3099
|
+
children: children ?? content
|
|
3100
|
+
}
|
|
3101
|
+
);
|
|
3102
|
+
};
|
|
3103
|
+
Typography.displayName = "Typography";
|
|
3104
|
+
function GameCanvas3DBattleTemplate({
|
|
3105
|
+
entity,
|
|
3106
|
+
cameraMode = "perspective",
|
|
3107
|
+
showGrid = true,
|
|
3108
|
+
shadows = true,
|
|
3109
|
+
backgroundColor = "#2a1a1a",
|
|
3110
|
+
tileClickEvent,
|
|
3111
|
+
unitClickEvent,
|
|
3112
|
+
unitAttackEvent,
|
|
3113
|
+
unitMoveEvent,
|
|
3114
|
+
endTurnEvent,
|
|
3115
|
+
exitEvent,
|
|
3116
|
+
selectedUnitId,
|
|
3117
|
+
validMoves,
|
|
3118
|
+
attackTargets,
|
|
3119
|
+
className
|
|
3120
|
+
}) {
|
|
3121
|
+
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
3122
|
+
if (!resolved) return null;
|
|
3123
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("game-canvas-3d-battle-template", className), children: [
|
|
3124
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3125
|
+
GameCanvas3D,
|
|
3126
|
+
{
|
|
3127
|
+
tiles: resolved.tiles,
|
|
3128
|
+
units: resolved.units,
|
|
3129
|
+
features: resolved.features,
|
|
3130
|
+
cameraMode,
|
|
3131
|
+
showGrid,
|
|
3132
|
+
showCoordinates: false,
|
|
3133
|
+
showTileInfo: false,
|
|
3134
|
+
shadows,
|
|
3135
|
+
backgroundColor,
|
|
3136
|
+
tileClickEvent,
|
|
3137
|
+
unitClickEvent,
|
|
3138
|
+
selectedUnitId,
|
|
3139
|
+
validMoves,
|
|
3140
|
+
attackTargets,
|
|
3141
|
+
className: "game-canvas-3d-battle-template__canvas"
|
|
3142
|
+
}
|
|
3143
|
+
),
|
|
3144
|
+
resolved.currentTurn && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3145
|
+
HStack,
|
|
3146
|
+
{
|
|
3147
|
+
gap: "sm",
|
|
3148
|
+
align: "center",
|
|
3149
|
+
className: cn("battle-template__turn-indicator", `battle-template__turn-indicator--${resolved.currentTurn}`),
|
|
3150
|
+
children: [
|
|
3151
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "turn-indicator__label", children: resolved.currentTurn === "player" ? "Your Turn" : "Enemy's Turn" }),
|
|
3152
|
+
resolved.round && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "turn-indicator__round", children: [
|
|
3153
|
+
"Round ",
|
|
3154
|
+
resolved.round
|
|
3155
|
+
] })
|
|
3156
|
+
]
|
|
3157
|
+
}
|
|
3158
|
+
)
|
|
3159
|
+
] });
|
|
3160
|
+
}
|
|
3161
|
+
GameCanvas3DBattleTemplate.displayName = "GameCanvas3DBattleTemplate";
|
|
3162
|
+
function GameCanvas3DCastleTemplate({
|
|
3163
|
+
entity,
|
|
3164
|
+
cameraMode = "isometric",
|
|
3165
|
+
showGrid = true,
|
|
3166
|
+
shadows = true,
|
|
3167
|
+
backgroundColor = "#1e1e2e",
|
|
3168
|
+
buildingClickEvent,
|
|
3169
|
+
unitClickEvent,
|
|
3170
|
+
buildEvent,
|
|
3171
|
+
recruitEvent,
|
|
3172
|
+
exitEvent,
|
|
3173
|
+
selectedBuildingId,
|
|
3174
|
+
selectedTileIds = [],
|
|
3175
|
+
availableBuildSites,
|
|
3176
|
+
showHeader = true,
|
|
3177
|
+
className
|
|
3178
|
+
}) {
|
|
3179
|
+
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
3180
|
+
if (!resolved) return null;
|
|
3181
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { className: cn("game-canvas-3d-castle-template", className), children: [
|
|
3182
|
+
showHeader && resolved.name && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", align: "center", className: "castle-template__header", children: [
|
|
3183
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", className: "header__name", children: resolved.name }),
|
|
3184
|
+
resolved.level && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "header__level", children: [
|
|
3185
|
+
"Level ",
|
|
3186
|
+
resolved.level
|
|
3187
|
+
] }),
|
|
3188
|
+
resolved.owner && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "header__owner", children: resolved.owner })
|
|
3189
|
+
] }),
|
|
3190
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3191
|
+
GameCanvas3D,
|
|
3192
|
+
{
|
|
3193
|
+
tiles: resolved.tiles,
|
|
3194
|
+
units: resolved.units,
|
|
3195
|
+
features: resolved.features,
|
|
3196
|
+
cameraMode,
|
|
3197
|
+
showGrid,
|
|
3198
|
+
showCoordinates: false,
|
|
3199
|
+
showTileInfo: false,
|
|
3200
|
+
shadows,
|
|
3201
|
+
backgroundColor,
|
|
3202
|
+
featureClickEvent: buildingClickEvent,
|
|
3203
|
+
unitClickEvent,
|
|
3204
|
+
selectedTileIds,
|
|
3205
|
+
validMoves: availableBuildSites,
|
|
3206
|
+
className: "game-canvas-3d-castle-template__canvas"
|
|
3207
|
+
}
|
|
3208
|
+
),
|
|
3209
|
+
resolved.units.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", align: "center", className: "castle-template__garrison-info", children: [
|
|
3210
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "garrison-info__label", children: "Garrison:" }),
|
|
3211
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "bold", className: "garrison-info__count", children: [
|
|
3212
|
+
resolved.units.length,
|
|
3213
|
+
" units"
|
|
3214
|
+
] })
|
|
3215
|
+
] })
|
|
3216
|
+
] });
|
|
3217
|
+
}
|
|
3218
|
+
GameCanvas3DCastleTemplate.displayName = "GameCanvas3DCastleTemplate";
|
|
3219
|
+
function GameCanvas3DWorldMapTemplate({
|
|
3220
|
+
entity,
|
|
3221
|
+
cameraMode = "isometric",
|
|
3222
|
+
showGrid = true,
|
|
3223
|
+
showCoordinates = true,
|
|
3224
|
+
showTileInfo = true,
|
|
3225
|
+
shadows = true,
|
|
3226
|
+
backgroundColor = "#1a1a2e",
|
|
3227
|
+
tileClickEvent,
|
|
3228
|
+
unitClickEvent,
|
|
3229
|
+
featureClickEvent,
|
|
3230
|
+
tileHoverEvent,
|
|
3231
|
+
tileLeaveEvent,
|
|
3232
|
+
cameraChangeEvent,
|
|
3233
|
+
selectedUnitId,
|
|
3234
|
+
validMoves,
|
|
3235
|
+
attackTargets,
|
|
3236
|
+
className
|
|
3237
|
+
}) {
|
|
3238
|
+
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
3239
|
+
if (!resolved) return null;
|
|
3240
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3241
|
+
GameCanvas3D,
|
|
3242
|
+
{
|
|
3243
|
+
tiles: resolved.tiles,
|
|
3244
|
+
units: resolved.units,
|
|
3245
|
+
features: resolved.features,
|
|
3246
|
+
cameraMode,
|
|
3247
|
+
showGrid,
|
|
3248
|
+
showCoordinates,
|
|
3249
|
+
showTileInfo,
|
|
3250
|
+
shadows,
|
|
3251
|
+
backgroundColor,
|
|
3252
|
+
tileClickEvent,
|
|
3253
|
+
unitClickEvent,
|
|
3254
|
+
featureClickEvent,
|
|
3255
|
+
tileHoverEvent,
|
|
3256
|
+
tileLeaveEvent,
|
|
3257
|
+
cameraChangeEvent,
|
|
3258
|
+
selectedUnitId,
|
|
3259
|
+
validMoves,
|
|
3260
|
+
attackTargets,
|
|
3261
|
+
className
|
|
3262
|
+
}
|
|
3263
|
+
);
|
|
3264
|
+
}
|
|
3265
|
+
GameCanvas3DWorldMapTemplate.displayName = "GameCanvas3DWorldMapTemplate";
|
|
2203
3266
|
var DEFAULT_CONFIG = {
|
|
2204
3267
|
cellSize: 1,
|
|
2205
3268
|
offsetX: 0,
|
|
@@ -2491,6 +3554,10 @@ exports.Canvas3DErrorBoundary = Canvas3DErrorBoundary;
|
|
|
2491
3554
|
exports.Canvas3DLoadingState = Canvas3DLoadingState;
|
|
2492
3555
|
exports.FeatureRenderer = FeatureRenderer;
|
|
2493
3556
|
exports.FeatureRenderer3D = FeatureRenderer3D;
|
|
3557
|
+
exports.GameCanvas3D = GameCanvas3D;
|
|
3558
|
+
exports.GameCanvas3DBattleTemplate = GameCanvas3DBattleTemplate;
|
|
3559
|
+
exports.GameCanvas3DCastleTemplate = GameCanvas3DCastleTemplate;
|
|
3560
|
+
exports.GameCanvas3DWorldMapTemplate = GameCanvas3DWorldMapTemplate;
|
|
2494
3561
|
exports.Lighting3D = Lighting3D;
|
|
2495
3562
|
exports.ModelLoader = ModelLoader;
|
|
2496
3563
|
exports.PhysicsObject3D = PhysicsObject3D;
|